View Javadoc

1   /*
2    * Copyright 2004-2006 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package com.isenshi.util;
17  
18  import java.beans.PropertyDescriptor;
19  import java.lang.reflect.Method;
20  import java.util.ArrayList;
21  import java.util.Collection;
22  import java.util.Date;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Properties;
28  
29  import org.apache.commons.beanutils.PropertyUtils;
30  import org.seasar.framework.aop.javassist.AspectWeaver;
31  
32  import com.isenshi.util.extlib.DiconResource;
33  
34  /***
35   * @author nishioka
36   */
37  public class DiconStringBuffer extends XMLStringBuffer {
38  
39  	private List refComponentList_;
40  
41  	private static final String DICON_ENCODING = "Windows-31J";
42  
43  	private static final String DICON_DOCTYPE_DECLARATION = "<!DOCTYPE components PUBLIC \"-//SEASAR//DTD S2Container//EN\" \"http://www.seasar.org/dtd/components.dtd\">";
44  
45  	public DiconStringBuffer() {
46  		super();
47  		appendXMLDeclaration(DICON_ENCODING, null);
48  		appendBody(DICON_DOCTYPE_DECLARATION);
49  	}
50  
51  	public void setReferenceComponents(List componets) {
52  		this.refComponentList_ = componets;
53  	}
54  
55  	public void appendStartComponentsTag() {
56  		appendStartTag("components");
57  	}
58  
59  	public void endComponentsTag() {
60  		endTag();
61  	}
62  
63  	private String toPureClassName(String className) {
64  		int index = className.indexOf(AspectWeaver.PREFIX_ENHANCED_CLASS);
65  		if (index >= 0) {
66  			return className.substring(0, index);
67  		}
68  		return className;
69  	}
70  
71  	public void appendStartComponentTag(Class clazz, Map options) {
72  		appendStartTag("component");
73  		appendAttribute("class", toPureClassName(clazz.getName()));
74  
75  		if (options == null) {
76  			return;
77  		}
78  
79  		String name = (String) options.get(DiconResource.OPTION_NAME);
80  		if (name != null) {
81  			appendAttribute("name", name);
82  		}
83  
84  	}
85  
86  	public void appendStartComponentTag(Class clazz) {
87  		appendStartComponentTag(clazz, null);
88  	}
89  
90  	public void endComponentTag() {
91  		endTag();
92  	}
93  
94  	public void appendComponent(Object component) {
95  		appendComponent(component, null);
96  	}
97  
98  	public void appendComponent(Object component, Map options) {
99  		List propertyList = new ArrayList();
100 		PropertyDescriptor[] descriptos = PropertyUtils
101 				.getPropertyDescriptors(component);
102 		for (int i = 0; i < descriptos.length; i++) {
103 			PropertyDescriptor desc = descriptos[i];
104 			if (desc.getReadMethod() != null
105 					&& isExistWriteMethod(desc, component.getClass())) {
106 				propertyList.add(descriptos[i].getName());
107 			}
108 		}
109 		appendComponent(component, options, (String[]) propertyList
110 				.toArray(new String[propertyList.size()]));
111 	}
112 
113 	private boolean isExistWriteMethod(PropertyDescriptor desc, Class clazz) {
114 		if (desc.getWriteMethod() != null) {
115 			return true;
116 		}
117 
118 		Class propClass = desc.getPropertyType();
119 		if (propClass.equals(List.class)
120 				&& isExistAddMethod(desc.getName(), clazz)) {
121 			return true;
122 		} else if ((propClass.equals(Map.class) || propClass
123 				.equals(Properties.class))
124 				&& isExistPutMethod(desc.getName(), clazz)) {
125 			return true;
126 		}
127 		return false;
128 	}
129 
130 	private boolean isExistAddMethod(String property, Class clazz) {
131 		String addMethodName = createAddMethodName(property);
132 
133 		Method[] methods = clazz.getMethods();
134 		for (int j = 0; j < methods.length; j++) {
135 			if (methods[j].getName().equals(addMethodName)) {
136 				return true;
137 			}
138 		}
139 		return false;
140 	}
141 
142 	private boolean isExistPutMethod(String property, Class clazz) {
143 		String putMethodName = createPutMethodName(property);
144 
145 		Method[] methods = clazz.getMethods();
146 		for (int j = 0; j < methods.length; j++) {
147 			if (methods[j].getName().equals(putMethodName)) {
148 				return true;
149 			}
150 		}
151 		return false;
152 	}
153 
154 	private String createAddMethodName(String property) {
155 		if (property.endsWith("s")) {
156 			property = property.substring(0, property.length() - 1);
157 		} else if (property.endsWith("List")) {
158 			property = property.substring(0, property.length() - 4);
159 		}
160 		property = "add" + CharUtil.toUpperCaseAtFisrtChar(property);
161 		return property;
162 	}
163 
164 	private String createPutMethodName(String property) {
165 		if (property.endsWith("Map")) {
166 			property = property
167 					.substring(0, property.length() - "Map".length());
168 		}
169 		property = "put" + CharUtil.toUpperCaseAtFisrtChar(property);
170 		return property;
171 	}
172 
173 	public void appendComponent(Object component, Map options,
174 			String[] properties) {
175 
176 		if (options == null) {
177 			options = new HashMap();
178 		}
179 		if (!options.containsKey(DiconResource.OPTION_NAME)) {
180 			options.put(DiconResource.OPTION_NAME, createId(component));
181 		}
182 
183 		appendStartComponentTag(component.getClass(), options);
184 		for (int i = 0; i < properties.length; i++) {
185 			appendComponentProperty(properties[i], component);
186 		}
187 		appendAspects(options);
188 		endComponentTag();
189 	}
190 
191 	public void appendAspects(Map options) {
192 		Map aspects = (Map) options.get(DiconResource.OPTION_ASPECTS);
193 		if (aspects == null) {
194 			return;
195 		}
196 		for (Iterator i = aspects.keySet().iterator(); i.hasNext();) {
197 			String pointcut = (String) i.next();
198 			Object value = aspects.get(pointcut);
199 			if (value instanceof List) {
200 				Iterator interceptorItr = ((List) value).iterator();
201 				while (interceptorItr.hasNext()) {
202 					String interceptor = (String) interceptorItr.next();
203 					appendAspect(pointcut, interceptor);
204 				}
205 			} else {
206 				String interceptor = (String) value;
207 				appendAspect(pointcut, interceptor);
208 			}
209 		}
210 	}
211 
212 	public void appendAspect(String pointcut, String interceptor) {
213 		appendStartTag("aspect");
214 		if (pointcut != null) {
215 			appendAttribute("pointcut", pointcut);
216 		}
217 		appendBody(interceptor);
218 		endTag();
219 	}
220 
221 	public void appendProperty(String property, Object valueObj) {
222 		if (valueObj == null) {
223 			return;
224 		}
225 
226 		if (valueObj instanceof Collection) {
227 			Collection col = (Collection) valueObj;
228 			Iterator itr = col.iterator();
229 			while (itr.hasNext()) {
230 				appendStartTag("initMethod");
231 				appendAttribute("name", createAddMethodName(property));
232 				appendStartTag("arg");
233 				appendPropertyBody(itr.next());
234 				endTag();
235 				endTag();
236 			}
237 		} else if (valueObj instanceof Map) {
238 			Map map = (Map) valueObj;
239 			Iterator itr = map.keySet().iterator();
240 			while (itr.hasNext()) {
241 				Object key = itr.next();
242 				appendStartTag("initMethod");
243 				appendAttribute("name", createPutMethodName(property));
244 				appendStartTag("arg");
245 				appendPropertyBody(key);
246 				endTag();
247 				appendStartTag("arg");
248 				appendPropertyBody(map.get(key));
249 				endTag();
250 				endTag();
251 			}
252 		} else {
253 			appendStartTag("property");
254 			appendAttribute("name", property);
255 			appendPropertyBody(valueObj);
256 			endTag();
257 		}
258 	}
259 
260 	public void appendProperty(String property, String value) {
261 		appendProperty(property, (Object) value);
262 	}
263 
264 	public void appendComponentProperty(String property, Object component) {
265 		Object valueObj = null;
266 		try {
267 			valueObj = PropertyUtils.getProperty(component, property);
268 		} catch (Exception e) {
269 			throw new RuntimeException(e);
270 		}
271 		if (valueObj == null) {
272 			return;
273 		}
274 		appendProperty(property, valueObj);
275 	}
276 
277 	public void appendPropertyBody(Object valueObj) {
278 		if (valueObj == null) {
279 			return;
280 		}
281 
282 		if (valueObj instanceof String) {
283 			appendBody("\"" + valueObj.toString() + "\"");
284 		} else if (valueObj instanceof Integer || valueObj instanceof Long
285 				|| valueObj instanceof Boolean || valueObj instanceof Float
286 				|| valueObj instanceof Double) {
287 			appendBody("new " + valueObj.getClass().getName() + "("
288 					+ valueObj.toString() + ")");
289 		} else if (valueObj instanceof Date) {
290 			Date date = (Date) valueObj;
291 			long time = date.getTime();
292 			appendBody("new java.util.Date(" + time + "l)");
293 		} else if (valueObj instanceof Object[]) {
294 			Object[] array = (Object[]) valueObj;
295 			String className = array.getClass().getName();
296 			appendBody("new " + className.substring(2, className.length() - 1)
297 					+ "[]{");
298 			for (int i = 0; i < array.length; i++) {
299 				if (i > 0) {
300 					appendBody(",");
301 				}
302 				appendPropertyBody(array[i]);
303 			}
304 			appendBody("}");
305 
306 		} else {
307 			if (refComponentList_ != null
308 					&& refComponentList_.contains(valueObj)) {
309 				appendBody(createId(valueObj));
310 			} else {
311 				appendComponent(valueObj);
312 			}
313 		}
314 	}
315 
316 	private String createId(Object component) {
317 		return "id" + component.hashCode();
318 	}
319 }