001: package com.silvermindsoftware.hitch;
002:
003: /**
004: * Copyright 2007 Brandon Goodin
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import com.silvermindsoftware.hitch.annotations.BoundComponent;
020: import com.silvermindsoftware.hitch.annotations.Form;
021: import com.silvermindsoftware.hitch.annotations.ModelObject;
022: import com.silvermindsoftware.hitch.meta.FormMeta;
023: import com.silvermindsoftware.hitch.reflect.ClassManager;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: import java.awt.*;
028: import java.lang.reflect.Field;
029: import java.lang.reflect.Method;
030: import java.util.ArrayList;
031: import java.util.HashMap;
032: import java.util.List;
033: import java.util.Map;
034:
035: /**
036: * This class contains all the base metadata creation code
037: */
038: public abstract class AbstractBinder implements Binder {
039:
040: private static final Log log = LogFactory
041: .getLog(AbstractBinder.class);
042:
043: protected Map<Class, FormMeta> formMap = new HashMap<Class, FormMeta>();
044:
045: abstract public void updateModel(Container component,
046: String... modelId);
047:
048: abstract public void populateForm(Container component,
049: String... modelId);
050:
051: @SuppressWarnings("unchecked")
052: public void collectAnnotationMeta(Class formClass) {
053: ErrorContext.put("- Collecting AnnotationMeta on "
054: + formClass.getName());
055: // ComponentField Meta for component class
056: FormMeta formMeta;
057:
058: if (formMap.containsKey(formClass)) {
059: formMeta = formMap.get(formClass);
060: } else {
061: formMeta = new FormMeta(formClass);
062: formMap.put(formClass, formMeta);
063: }
064:
065: if (!formMeta.isAnnotationMetaCollected()) {
066:
067: boolean autoBind = false;
068:
069: if (formClass.isAnnotationPresent(Form.class)) {
070: Form form = (Form) formClass.getAnnotation(Form.class);
071: autoBind = form.autoBind();
072: }
073:
074: // temporary list to hold fields that have BoundComponent annotations
075: List<Field> boundComponentFields = new ArrayList<Field>();
076:
077: // retrieve public component's fields to find annotated fields
078: Field[] fields = ClassManager.getClassInfo(formClass)
079: .getFields();
080:
081: for (Field field : fields) {
082: if (field.isAnnotationPresent(BoundComponent.class)) {
083: boundComponentFields.add(field);
084: } else if (field.isAnnotationPresent(ModelObject.class)) {
085: ModelObject modelObject = field
086: .getAnnotation(ModelObject.class);
087:
088: ErrorContext
089: .put("- Processing Annotation for model object field "
090: + field.getName()
091: + " of type "
092: + modelObject.getClass().getName());
093:
094: if (modelObject.isDefault()) {
095: ErrorContext.put("- Model Object is default");
096: formMeta.putModelMeta("[default]", field);
097: } else {
098: ErrorContext
099: .put("- Model Object is NOT default");
100: formMeta.putModelMeta(field.getName(), field);
101: }
102:
103: Class modelObjectType = field.getType();
104:
105: // autoBind if autoBind enabled. But, do not if ModelObject is a Map because fields do not yet exist
106: if (autoBind
107: && modelObject.autoBind()
108: && !Map.class
109: .isAssignableFrom(modelObjectType)) {
110:
111: // iterate modelObject fields
112:
113: ErrorContext.put("- AutoBind Model Object"
114: + modelObjectType.getName());
115:
116: for (Method moMethod : ClassManager
117: .getClassInfo(modelObjectType)
118: .getSetters()) {
119:
120: String componentFieldName = moMethod
121: .getName().substring(3, 4)
122: .toLowerCase()
123: + moMethod.getName().substring(4);
124:
125: Field formClassField = null;
126:
127: try {
128: ErrorContext
129: .put("- Attempting to lookup field "
130: + componentFieldName);
131: formClassField = ClassManager
132: .getClassInfo(formClass)
133: .getField(componentFieldName);
134:
135: if (!formClassField
136: .isAnnotationPresent(BoundComponent.class)) {
137: ErrorContext
138: .put("- Adding ComponentMeta for "
139: + formClassField
140: .getName()
141: + " of type "
142: + formClassField
143: .getType()
144: .getName());
145:
146: formMeta
147: .addComponentMeta(
148: modelObject
149: .isDefault() ? "[default]"
150: : field
151: .getName(),
152: componentFieldName,
153: formClassField,
154: void.class,
155: new String[] {},
156: true,
157: ReadOnly.DEFAULT,
158: moMethod
159: .getParameterTypes()[0]);
160:
161: ErrorContext.removeLast();
162:
163: }
164: } catch (NoSuchFieldException e) {
165: // ignored
166: } finally {
167: ErrorContext.removeLast();
168: }
169: }
170:
171: ErrorContext.removeLast();
172:
173: }
174:
175: ErrorContext.removeLast();
176:
177: }
178: }
179:
180: for (Field field : boundComponentFields) {
181:
182: ErrorContext.put("processing BoundComponent field "
183: + field.getName() + " of type "
184: + field.getType().getName());
185:
186: BoundComponent boundComponent = field
187: .getAnnotation(BoundComponent.class);
188:
189: formMeta
190: .addComponentMeta(boundComponent.modelId(),
191: boundComponent.property().equals(
192: "[default]") ? field.getName()
193: : boundComponent.property(),
194: field, boundComponent.handler(),
195: boundComponent.handlerValues(), false,
196: boundComponent.readOnly(),
197: boundComponent.type());
198:
199: ErrorContext.removeLast();
200:
201: }
202:
203: formMeta.setAnnotationMetaCollected(true);
204: }
205:
206: ErrorContext.removeLast();
207: }
208:
209: public FormMeta getFormMeta(Class formClass) {
210: FormMeta formMeta = null;
211:
212: if (formMap.containsKey(formClass)) {
213:
214: // if key exists retrieve meta for mapping
215: formMeta = formMap.get(formClass);
216:
217: ErrorContext.put("- FormMeta retrieved for "
218: + formClass.getName());
219:
220: // if annotaion metadata has not been collected
221: if (!formMeta.isAnnotationMetaCollected())
222: collectAnnotationMeta(formClass);
223:
224: } else {
225:
226: ErrorContext.put("- New FormMeta created for "
227: + formClass.getName());
228:
229: collectAnnotationMeta(formClass);
230: formMeta = formMap.get(formClass);
231:
232: }
233:
234: return formMeta;
235: }
236:
237: }
|