View Javadoc

1   package com.silvermindsoftware.hitch.meta;
2   
3   /**
4    * Copyright 2007 Brandon Goodin
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import com.silvermindsoftware.hitch.ReadOnly;
20  import com.silvermindsoftware.hitch.config.BoundComponentConfig;
21  import com.silvermindsoftware.hitch.reflect.ClassManager;
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  import java.lang.reflect.Field;
26  import java.lang.reflect.Method;
27  import java.util.*;
28  
29  /**
30   * This class holds all of the meta data gathered from the different
31   * configuration mediums (annotations, BinderConfig).
32   * 
33   * @svnLink $Revision: 4068 $;$Date: 2010-01-05 09:38:21 +0100 (Di, 05. Jan 2010) $;$Author: jonasha $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/swing/src/main/java/com/silvermindsoftware/hitch/meta/FormMeta.java $
34   */
35  public class FormMeta {
36  
37  	private static final Logger log = LoggerFactory.getLogger(FormMeta.class);
38  
39  	private boolean annotationMetaCollected;
40  
41  	private Class componentClass;
42  	private Map<String, ModelMeta> modelMap;
43  	private List<ComponentMeta> componentMetaLists;
44  
45  	public FormMeta(Class componentClass) {
46  		this(componentClass, new HashMap<String, ModelMeta>(), new ArrayList<ComponentMeta>());
47  	}
48  
49  	public FormMeta(Class componentClass, Map modelMap, List componentMetaLists) {
50  
51  		this.annotationMetaCollected = false;
52  		this.componentClass = componentClass;
53  		this.modelMap = modelMap;
54  		this.componentMetaLists = componentMetaLists;
55  
56  	}
57  
58  	public void putModelMeta(String id, String modelField) {
59  
60  		try {
61  			putModelMeta(id, ClassManager.getClassInfo(componentClass).getField(modelField));
62  		} catch (NoSuchFieldException e) {
63  			throw new IllegalStateException(
64  					"Field with name " + modelField +
65  							" was not found in class" + componentClass.getName());
66  		}
67  
68  	}
69  
70  	public void putModelMeta(String id, Field modelField) {
71  		if (modelMap.containsKey(id)) {
72  			log.info(
73  					"Model of type "
74  							+ (modelMap.get(id)).getModelField().getType().getName()
75  							+ " with id of '" + id + "' already exists for class "
76  							+ componentClass.getName());
77  		} else {
78  			modelMap.put(id, new ModelMeta(modelField));
79  		}
80  
81  	}
82  
83  	public ModelMeta getModelMeta(String modelId) {
84  
85  		if (!modelMap.containsKey(modelId))
86  			throw new IllegalStateException(
87  					"Model identified by " + modelId
88  							+ " does not exist for class " + componentClass.getName());
89  
90  		return modelMap.get(modelId);
91  	}
92  
93  	public void addComponentMeta(String modelId, BoundComponentConfig boundComponentConfig, boolean autoBound) {
94  
95  		Field field;
96  
97  		try {
98  			field = ClassManager.getClassInfo(componentClass).getField(boundComponentConfig.getComponentFieldName());
99  			field.setAccessible(true);
100 		} catch (NoSuchFieldException e) {
101 			throw new IllegalStateException(
102 					boundComponentConfig.getComponentFieldName() + " field was not found on class " + componentClass.getName());
103 		}
104 
105 		addComponentMeta(
106 				modelId, boundComponentConfig.getModelPropertyName(),
107 				field, boundComponentConfig.getHandlerClass(),
108 				boundComponentConfig.getHandlerParameters(), autoBound,
109 				boundComponentConfig.getReadOnly(), boundComponentConfig.getType());
110 	}
111 
112 	public void addComponentMeta(
113 			String modelId, String modelProperty,
114 			Field componentField, Class componentHandler,
115 			String[] handlerParameters, boolean autoBound,
116 			ReadOnly readOnly, Class type) {
117 
118 		if (!modelMap.containsKey(modelId))
119 			throw new IllegalArgumentException("No model object found for id " + modelId);
120 
121 		ModelMeta modelMeta =
122 				modelMap.get(modelId);
123 
124 		Class modelType = modelMeta.getModelField().getType();
125 
126 		ComponentMeta tempComponentMeta = new ComponentMeta(modelProperty, modelId);
127 
128 		if (componentMetaLists.contains(tempComponentMeta)) {
129 
130 			ComponentMeta componentMeta =
131 					componentMetaLists.get(
132 							componentMetaLists.indexOf(
133 									tempComponentMeta));
134 
135 			if (componentMeta.isAutoBound() && autoBound == false) {
136 				componentMetaLists.add(
137 						componentMetaLists.indexOf(tempComponentMeta),
138 						createComponentMeta(
139 								modelType, modelProperty, modelId, componentField,
140 								componentHandler, handlerParameters, autoBound, readOnly, type));
141 			} else {
142 				log.info(
143 						"ComponentMeta already exists for property "
144 								+ modelProperty + " of model id" + modelId
145 								+ " for class " + modelType.getName());
146 			}
147 
148 		} else {
149 			componentMetaLists.add(
150 					createComponentMeta(
151 							modelType, modelProperty, modelId, componentField,
152 							componentHandler, handlerParameters, autoBound, readOnly, type));
153 		}
154 	}
155 
156 	private ComponentMeta createComponentMeta(Class modelType, String modelProperty, String modelId, Field componentField, Class componentHandler, String[] handlerParameters, boolean autoBound, ReadOnly readOnly, Class type) {
157 		// attain getter/setter/field for model property
158 		Class propertyType = null;
159 
160 		Method modelPropertyGetterMethod = null;
161 		boolean modelPropertyGetterMethodFound = false;
162 
163 		Method modelPropertySetterMethod = null;
164 
165 		Field modelPropertyField = null;
166 		
167 		String mdlProp = modelProperty;
168 		
169 		// SWI: remove "m_" if necessary
170 		if (mdlProp.startsWith("m_")) {
171 			mdlProp = mdlProp.substring(2);
172 		}
173 
174 		// getter
175 		try {
176 			if (Map.class.isAssignableFrom(modelType)) {
177 				modelPropertyGetterMethod =
178 						ClassManager.getClassInfo(modelType).getMethod(
179 								"get", new Class[]{Object.class});
180 
181 				if (modelPropertyGetterMethod != null) {
182 					propertyType = modelPropertyGetterMethod.getReturnType();
183 					modelPropertyGetterMethodFound = true;
184 				}
185 			} else {
186 				modelPropertyGetterMethod =
187 						ClassManager.getClassInfo(modelType).getGetterMethod(
188 								composeGetterName(mdlProp));
189 				modelPropertyGetterMethod.setAccessible(true);
190 				if (modelPropertyGetterMethod != null) {
191 					propertyType = modelPropertyGetterMethod.getReturnType();
192 					modelPropertyGetterMethod.setAccessible(true);
193 					modelPropertyGetterMethodFound = true;
194 				}
195 			}
196 
197 		} catch (NoSuchMethodException e) {
198 			log.info(e.getMessage());
199 		}
200 
201 		// field
202 		try {
203 			modelPropertyField = ClassManager.getClassInfo(modelType).getField(mdlProp);
204 			modelPropertyField.setAccessible(true);
205 			if (propertyType == null) propertyType = modelPropertyField.getType();
206 		} catch (NoSuchFieldException e) {
207 			if (!modelPropertyGetterMethodFound)
208 				throw new IllegalStateException(
209 						"A getter method or a field was not found for property with name " + mdlProp);
210 		}
211 
212 		// setter
213 		try {
214 			if (Map.class.isAssignableFrom(modelType)) {
215 				modelPropertySetterMethod = ClassManager.getClassInfo(modelType).getSetterMethod("put", new Class[]{Object.class, Object.class});
216 			} else {
217 				modelPropertySetterMethod = ClassManager.getClassInfo(modelType).getSetterMethod(composeSetterName(modelProperty), new Class[]{propertyType});
218 				modelPropertySetterMethod.setAccessible(true);
219 			}
220 		} catch (NoSuchMethodException e) {
221 			log.info(e.getMessage());
222 		}
223 
224 		ComponentMeta componentMeta =
225 				new ComponentMeta(
226 						modelType, modelProperty, modelId,
227 						componentField, modelPropertyField,
228 						modelPropertyGetterMethod, modelPropertySetterMethod,
229 						componentHandler, handlerParameters,
230 						autoBound, readOnly,
231 						type == void.class ? propertyType : type
232 				);
233 		return componentMeta;
234 	}
235 
236 	public Iterator<ComponentMeta> getComponentMetaIterator() {
237 		return componentMetaLists.iterator();
238 	}
239 
240 	public void setAnnotationMetaCollected(boolean annotationMetaCollected) {
241 		this.annotationMetaCollected = annotationMetaCollected;
242 	}
243 
244 	public boolean isAnnotationMetaCollected() {
245 		return annotationMetaCollected;
246 	}
247 
248 	public Class getComponentClass() {
249 		return componentClass;
250 	}
251 
252 	protected String composeSetterName(String propertyName) {
253 		StringBuilder sb = new StringBuilder("set");
254 		sb.append(propertyName.substring(0, 1).toUpperCase());
255 		sb.append(propertyName.substring(1));
256 		return sb.toString();
257 	}
258 
259 	protected String composeGetterName(String propertyName) {
260 		StringBuilder sb = new StringBuilder("get");
261 		sb.append(propertyName.substring(0, 1).toUpperCase());
262 		sb.append(propertyName.substring(1));
263 		return sb.toString();
264 	}
265 
266 
267 }