001: package com.xoetrope.builder.pojo;
002:
003: import com.xoetrope.carousel.builder.XFormGeneratorInfo;
004: import com.xoetrope.carousel.builder.XFormGeneratorWizard;
005: import com.xoetrope.data.pojo.XPojoModelEx;
006: import java.awt.Point;
007: import java.awt.datatransfer.DataFlavor;
008: import java.awt.datatransfer.Transferable;
009: import java.util.ArrayList;
010: import java.util.Collection;
011: import java.util.HashMap;
012: import java.util.List;
013: import java.util.Map;
014: import javax.swing.JComponent;
015: import net.xoetrope.editor.dnd.PageDesignerDndHelper;
016: import net.xoetrope.editor.project.XEditorProject;
017: import net.xoetrope.editor.project.pages.BindingTransferHandler;
018: import net.xoetrope.editor.project.pages.PageDesigner;
019: import net.xoetrope.optional.data.pojo.XPojoHelper;
020: import net.xoetrope.xui.data.XModel;
021:
022: /**
023: * A transfer handler helper for the page designer
024: * <p> Copyright (c) Xoetrope Ltd., 2002-2007</p>
025: * <p> $Revision: 1.77 $</p>
026: * <p> License: see License.txt</p>
027: */
028:
029: public class PojoFormBuilderDndHelper implements PageDesignerDndHelper {
030: // max number of recursive calls when builing the form generator tree.
031: public static int MAX_LEVEL = 5;
032:
033: public boolean importData(XEditorProject project, PageDesigner pd,
034: JComponent c, Transferable t, Point pt) {
035: XModel model = null;
036: try {
037: model = (XModel) t
038: .getTransferData(BindingTransferHandler.XModelFlavor);
039: } catch (Exception ex) {
040: ex.printStackTrace();
041: return false;
042: }
043:
044: // this helper handles only POJO model nodes.
045: if (!(model instanceof XPojoModelEx))
046: return false;
047:
048: XFormGeneratorInfo builderInfo = getFormBuilderInfo((XPojoModelEx) model);
049: builderInfo.setGenerationParameter("numColumns", "2");
050:
051: XFormGeneratorWizard wizard = new XFormGeneratorWizard(project,
052: builderInfo);
053: wizard.setLocationRelativeTo(pd);
054: if (wizard.showDialog()) {
055: try {
056: PojoFormGenerator pojoFormGenerator = new PojoFormGenerator(
057: project, pd);
058: pojoFormGenerator.generatePanel(builderInfo, c, pt);
059: } catch (Exception ex) {
060: ex.printStackTrace();
061: }
062: }
063: return true;
064: }
065:
066: public boolean canImport(XEditorProject project, PageDesigner pd,
067: JComponent c, DataFlavor[] flavors) {
068: for (int i = 0; i < flavors.length; i++)
069: if (flavors[i].equals(BindingTransferHandler.XModelFlavor))
070: return true;
071: return false;
072: }
073:
074: /**
075: * Sets up the component type for the specified property
076: * @param formInfo Form Generator that will store the information
077: * @param propType type (class) of the property
078: * @param compName the name of the component
079: */
080: private void setProperty(XFormGeneratorInfo formInfo,
081: Class propType, String compName) {
082: boolean textArea = String.class.isAssignableFrom(propType);
083: if (textArea) {
084: formInfo.setProperty(compName, "component", "TextArea");
085: return;
086: }
087:
088: boolean checkBox = Boolean.class.isAssignableFrom(propType);
089: checkBox = checkBox || boolean.class.isAssignableFrom(propType);
090: if (checkBox) {
091: formInfo.setProperty(compName, "component", "CheckBox");
092: return;
093: }
094:
095: boolean numeric = Integer.class.isAssignableFrom(propType);
096: numeric = numeric || int.class.isAssignableFrom(propType);
097: numeric = numeric || Long.class.isAssignableFrom(propType);
098: numeric = numeric || long.class.isAssignableFrom(propType);
099: if (numeric) {
100: formInfo.setProperty(compName, "format", "decimal");
101: return;
102: }
103:
104: boolean list = Collection.class.isAssignableFrom(propType);
105: if (list) {
106: formInfo.setProperty(compName, "component", "List");
107: return;
108: }
109:
110: //TODO: check whether the "propType" is a complex class.
111: formInfo.setProperty(compName, "component", "Panel");
112: }
113:
114: /****************************************************************************/
115: /**
116: * Indicates whether the specified POJO has been already added
117: * to the tree.
118: * @param model XPojoModelEx object encapsulating the POJO
119: * @return true if the POJO is already present in the tree, false otherwise
120: */
121: private boolean hasBeenAdded(XPojoModelEx model,
122: Map<Class, List<Object>> addedNodes) {
123: Object pojo = model.getPojo();
124: Class pojoClass = pojo.getClass();
125:
126: // example: return "foo"; each instance returns the same object
127: if (XPojoHelper.isPrimitiveType(pojoClass))
128: return false;
129:
130: List<Object> objects = addedNodes.get(pojoClass);
131: if (objects == null)
132: addedNodes.put(pojoClass, objects = new ArrayList());
133:
134: for (Object object : objects)
135: if (object == pojo)
136: return true;
137:
138: objects.add(pojo);
139: return false;
140: }
141:
142: private String getModelName(XPojoModelEx model) {
143: String name = "";
144: while (model != null) {
145: name = (model.getId() + name);
146: XModel parent = model.getParent();
147: model = (parent instanceof XPojoModelEx ? (XPojoModelEx) parent
148: : null);
149: }
150: return name;
151: }
152:
153: // public XFormGeneratorInfo getFormBuilderInfo( XPojoModelEx model )
154: // {
155: // return getFormBuilderInfo( model, MAX_LEVEL, new HashMap() );
156: // }
157: public XFormGeneratorInfo getFormBuilderInfo(XPojoModelEx model) {
158: XFormGeneratorInfo formInfo = getFormBuilderInfo(model,
159: MAX_LEVEL, new HashMap());
160: fixSizes(formInfo);
161: return formInfo;
162: }
163:
164: private XFormGeneratorInfo getFormBuilderInfo(XPojoModelEx model,
165: int level, Map<Class, List<Object>> addedNodes) {
166: XFormGeneratorInfo formInfo = new XFormGeneratorInfo();
167:
168: if (hasBeenAdded(model, addedNodes))
169: return formInfo;
170:
171: // don't go too deep
172: if (level == 0)
173: return formInfo;
174:
175: // TODO: the name can get very long
176: String modelId = getModelName(model);
177:
178: int numChildren = model.getNumChildren();
179: for (int i = 0; i < numChildren; i++) {
180:
181: // check whether the child is a regular property
182: XModel c = model.get(i);
183: if (!(c instanceof XPojoModelEx))
184: continue;
185:
186: XPojoModelEx childModel = (XPojoModelEx) c;
187:
188: Class propertyType = childModel.getPojoClass();
189: if (propertyType == null)
190: continue;
191:
192: // if ( hasBeenAdded( childModel, addedNodes ))
193: // continue;
194:
195: String childId = childModel.getId();
196: childId = childId.substring(0, 1).toUpperCase()
197: + childId.substring(1);
198: String componentName = (modelId + childId);
199:
200: XFormGeneratorInfo childPanelInfo = null;
201: String bindingPath = null;
202:
203: // complex property, represented by an internal panel
204: if (XPojoHelper.needsAdapter(propertyType)) {
205: childPanelInfo = getFormBuilderInfo(childModel,
206: level - 1, addedNodes);
207: if (childPanelInfo.getNumFields() == 0)
208: continue;
209: }
210: // simple property, represented by a single component
211: else {
212: bindingPath = childModel.getBindingPath();
213: }
214:
215: formInfo.addField(componentName);
216: setProperty(formInfo, propertyType, componentName);
217:
218: formInfo.setProperty(componentName, "bindingPath",
219: bindingPath);
220: formInfo.setProperty(componentName, "childPanel",
221: childPanelInfo);
222: // display a property name on the prefix label
223: formInfo.setProperty(componentName, "prefix", childId);
224: }
225:
226: formInfo.setGenerationParameter("title", model.getId());
227: return formInfo;
228: }
229:
230: /**
231: * Changes the sizes of the internal panels
232: * @param parentInfo the parent panel
233: */
234: private void fixSizes(XFormGeneratorInfo parentInfo) {
235: int numFields = parentInfo.getNumFields();
236: for (int i = 0; i < numFields; i++) {
237: String fieldName = parentInfo.getFieldName(i);
238:
239: XFormGeneratorInfo childInfo = (XFormGeneratorInfo) parentInfo
240: .getProperty(fieldName, "childPanel");
241: if (childInfo == null)
242: continue;
243:
244: fixChildInfoSize(parentInfo, childInfo);
245: fixSizes(childInfo);
246: }
247: }
248:
249: private void fixChildInfoSize(XFormGeneratorInfo parentInfo,
250: XFormGeneratorInfo childInfo) {
251: int parentColWidth = Integer.parseInt(parentInfo
252: .getGenerationParameter("colWidth"));
253: int childColWidth = (int) (0.9 * parentColWidth);
254: childInfo.setGenerationParameter("colWidth", String
255: .valueOf(childColWidth));
256: }
257:
258: }
|