001: /*
002: * Copyright 2006 Luca Garulli (luca.garulli@assetdata.it)
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package org.romaframework.aspect.view.echo2.form;
017:
018: import java.util.HashMap;
019: import java.util.Map;
020: import java.util.StringTokenizer;
021:
022: import nextapp.echo2.app.Button;
023: import nextapp.echo2.app.Column;
024: import nextapp.echo2.app.Component;
025: import nextapp.echo2.app.Insets;
026: import nextapp.echo2.app.Label;
027: import nextapp.echo2.app.Row;
028: import nextapp.echo2.app.Style;
029:
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032: import org.romaframework.aspect.view.ViewAspect;
033: import org.romaframework.aspect.view.ViewConstants;
034: import org.romaframework.aspect.view.echo2.component.NullComponent;
035: import org.romaframework.aspect.view.echo2.component.Titleable;
036: import org.romaframework.aspect.view.echo2.form.field.FieldContainer;
037: import org.romaframework.aspect.view.echo2.form.field.FieldContainerFactory;
038: import org.romaframework.aspect.view.echo2.look.LookAndFeelManager;
039: import org.romaframework.aspect.view.feature.ViewBaseFeatures;
040: import org.romaframework.aspect.view.feature.ViewClassFeatures;
041: import org.romaframework.aspect.view.form.ContentComponent;
042: import org.romaframework.core.GlobalConstants;
043: import org.romaframework.core.config.RomaApplicationContext;
044: import org.romaframework.core.flow.ObjectContext;
045: import org.romaframework.core.schema.SchemaObject;
046:
047: /**
048: * Dynamic form that render any object using reflection, annotation and external
049: * XML configuration files.
050: *
051: * @author Luca Garulli (luca.garulli@assetdata.it)
052: */
053: public class DefaultEntityForm extends EntityForm implements Titleable {
054: protected String orientation = ViewConstants.ORIENTATION_VERTICAL;
055: protected FieldContainer fieldContainer;
056: protected Row labelRow;
057: protected Component frame;
058: protected Map<String, Component> areas;
059: protected boolean enabled = true;
060: private Label componentTitle;
061: private static Log log = LogFactory.getLog(DefaultEntityForm.class);
062:
063: /**
064: * Creates a new <code>DefaultEntityForm</code> with no parent form
065: * associated.
066: */
067: public DefaultEntityForm() {
068: this (null);
069: }
070:
071: /**
072: * Creates a new <code>DefaultEntityForm</code>.
073: */
074: public DefaultEntityForm(ContentComponent iParent) {
075: super (iParent);
076: areas = new HashMap<String, Component>();
077: frame = new Column();
078: add(frame);
079: }
080:
081: public void activate() {
082: }
083:
084: // TODO cache the form by content and not by type
085: public void passivate() {
086: if (fieldContainer != null) {
087: fieldContainer.clear();
088: frame.remove(fieldContainer);
089: fieldContainer = null;
090: }
091: areas.clear();
092: }
093:
094: @Override
095: public void placeComponentInForm(String iArea, Component iComponent) {
096: Component areaContainer = null;
097: Map<String, Component> areas = getAreas();
098: SchemaObject schemaInstance = getSchemaInstance();
099: Component formFrame = getFrame();
100: if (iArea == null)
101: // NO AREAS: ASSIGN DEFAULT NAME
102: iArea = GlobalConstants.ROOT_CLASS;
103: // FIND THE NAMED AREA
104: areaContainer = areas.get(iArea);
105: if ((areaContainer == null || areaContainer instanceof NullComponent)
106: && iComponent != null
107: && !(iComponent instanceof Column)) {
108: // INSERT THE COMPONENT DIRECTLY
109: if (iArea == null)
110: // ASSIGN THE OBJECT ID AS NAME
111: iArea = iComponent.toString();
112: if (iComponent instanceof Button) {
113: // SPECIAL CASE: BUTTON ARE ALWAYS IN A TRUE CONTAINER
114: Component row = new Row();
115: row.add(iComponent);
116: ObjectContext.getInstance().getComponent(
117: LookAndFeelManager.class).assignStyle(row,
118: schemaInstance.getSchemaClass().getClazz());
119: areas.put(iArea, row);
120: if (areaContainer instanceof NullComponent)
121: replaceComponent(formFrame, row, areaContainer);
122: else
123: formFrame.add(row);
124: } else {
125: // INSERT THE COMPONENT DIRECTLY IN THE FORM'S MAIN COLUMN
126: areas.put(iArea, iComponent);
127: if (areaContainer instanceof NullComponent)
128: replaceComponent(formFrame, iComponent,
129: areaContainer);
130: else
131: formFrame.add(iComponent);
132: }
133: } else {
134: // CHECK IF THERE IS A CONTAINER
135: if (areaContainer instanceof Row
136: || areaContainer instanceof Column
137: || areaContainer instanceof FieldContainer) {
138: // THERE IS A CONTAINER:
139: } else {
140: // NO CONTAINER: CREATE IT
141: Component comp = areaContainer;
142: if (iComponent == null)
143: // INSERT A PLACE HOLDER
144: areaContainer = new NullComponent();
145: else if (getOrientation().equals(
146: ViewConstants.ORIENTATION_HORIZONTAL)) {
147: areaContainer = new Column();
148: } else {
149: areaContainer = new Row();
150: }
151: ObjectContext.getInstance().getComponent(
152: LookAndFeelManager.class).assignStyle(
153: areaContainer,
154: schemaInstance.getSchemaClass().getClazz(),
155: iArea, null);
156: areas.put(iArea, areaContainer);
157: if (comp != null)
158: replaceComponent(formFrame, areaContainer, comp);
159: else
160: // NO COMPONENT TO ADD: ADD ONLY THE CONTAINER AS LEAF
161: formFrame.add(areaContainer);
162: }
163: if (iComponent != null)
164: // ADD THE COMPONENT AT THE END OF CONTAINER
165: areaContainer.add(iComponent);
166: }
167: }
168:
169: private void replaceComponent(Component iFrame,
170: Component iAreaContainer, Component iComponentToRemove) {
171: for (int i = 0; i < iFrame.getComponentCount(); ++i) {
172: if (iFrame.getComponent(i).equals(iComponentToRemove)) {
173: iFrame.remove(iComponentToRemove);
174: iFrame.add(iAreaContainer, i);
175: if (!(iComponentToRemove instanceof NullComponent))
176: iAreaContainer.add(iComponentToRemove);
177: break;
178: }
179: }
180: }
181:
182: /**
183: * Render the content of Form.
184: *
185: * @param iContainerForm Form where to render
186: */
187: public void render(ContentComponent iFormToRender) {
188: if (schemaInstance == null)
189: return;
190: String styleName = (String) schemaInstance.getFeature(
191: ViewAspect.ASPECT_NAME, ViewBaseFeatures.STYLE);
192: Class<?> styleClass = schemaInstance.getSchemaClass()
193: .getClazz();
194: styleManager.assignStyle(this , styleClass, styleName);
195: styleManager.assignStyle(frame, styleClass, styleName);
196: styleManager.assignStyle(fieldContainer, styleClass, styleName);
197: // RENDER ALL FIELDS AND ACTIONS
198: SchemaObject obj = iFormToRender.getSchemaInstance();
199: if (obj != null) {
200: renderFormFields(obj, iFormToRender);
201: renderFormActions(obj, iFormToRender);
202: }
203: }
204:
205: @Override
206: public void addComponent(String iArea, Component iComponent) {
207: if (iArea != null && iArea.contains("/")) {
208: EntityForm form;
209: String area;
210: if (iArea.startsWith(AREA_PARENT_NAVIGATION)) {
211: // PARENT FORM
212: form = (EntityForm) getContainerComponent();
213: area = iArea.substring(AREA_PARENT_NAVIGATION.length());
214: } else {
215: int sepPos = iArea.indexOf("/");
216: form = (EntityForm) getFieldComponent(iArea.substring(
217: 0, sepPos));
218: area = iArea.substring(sepPos + 1);
219: }
220: // NAVIGATE THE UPPER FORM
221: form.addComponent(area, iComponent);
222: } else
223: // PLACE THE COMPONENT
224: placeComponentInForm(iArea, iComponent);
225: }
226:
227: @Override
228: public void setMetaDataSchema(SchemaObject iSchema) {
229: super .setMetaDataSchema(iSchema);
230: String customLabel = (String) schemaInstance.getFeature(
231: ViewAspect.ASPECT_NAME, ViewBaseFeatures.LABEL);
232: if (customLabel != null)
233: setTitle(customLabel);
234: // SETUP THE FIELD CONTAINER
235: try {
236: fieldContainer = RomaApplicationContext.getInstance()
237: .getBean(FieldContainerFactory.class)
238: .getComponentInstance(ViewConstants.LAYOUT_GRID);
239: } catch (Exception e) {
240: log.error("[DefaultEntityForm.setMetaData] error", e);
241: }
242: fieldContainer.init((Integer) iSchema.getFeature(
243: ViewAspect.ASPECT_NAME, ViewClassFeatures.COLUMNS));
244: addComponent(null, fieldContainer);
245: String orderAreas = (String) iSchema.getFeature(
246: ViewAspect.ASPECT_NAME, ViewClassFeatures.ORDER_AREAS);
247: if (orderAreas != null) {
248: // CREARE NOW DEFINED AREAS TO MANTAIN ORDER
249: StringTokenizer tokenizer = new StringTokenizer(orderAreas,
250: " ");
251: for (short areaNum = 0; tokenizer.hasMoreTokens(); ++areaNum) {
252: placeComponentInForm(tokenizer.nextToken(), null);
253: }
254: }
255: }
256:
257: public void setTitle(String iTitle) {
258: if (iTitle != null && iTitle.length() == 0)
259: iTitle = null;
260: if (componentTitle == null && iTitle != null) {
261: // CREATE TITLE COMPONENTS
262: labelRow = new Row();
263: frame.add(labelRow, 0);
264: componentTitle = new Label();
265: styleManager.assignStyle(componentTitle, schemaInstance
266: .getSchemaClass().getClazz());
267: labelRow.setInsets(new Insets(5));
268: labelRow.add(componentTitle);
269: } else {
270: if (iTitle == null && componentTitle != null) {
271: // REMOVE TITLE COMPONENTS
272: labelRow.removeAll();
273: frame.remove(labelRow);
274: componentTitle = null;
275: }
276: }
277: if (componentTitle != null)
278: componentTitle.setText(iTitle);
279: }
280:
281: @Override
282: public void setStyle(Style newValue) {
283: if (newValue.getProperty("orientation") != null)
284: setOrientation((String) newValue.getProperty("orientation"));
285: super .setStyle(newValue);
286: }
287:
288: public String getOrientation() {
289: return orientation;
290: }
291:
292: public void setOrientation(String iOrientation) {
293: if (iOrientation.equals(orientation))
294: return;
295: this .orientation = iOrientation;
296: Component[] components = frame.getComponents();
297: Component newFrame;
298: if (iOrientation.equals(ViewConstants.ORIENTATION_HORIZONTAL)) {
299: newFrame = new Row();
300: } else {
301: newFrame = new Column();
302: }
303: removeAll();
304: add(newFrame);
305: styleManager.assignStyle(newFrame, schemaInstance
306: .getSchemaClass().getClazz(), (String) schemaInstance
307: .getFeature(ViewAspect.ASPECT_NAME,
308: ViewBaseFeatures.STYLE));
309: for (Component c : components) {
310: newFrame.add(c);
311: }
312: frame = newFrame;
313: }
314:
315: public Component getFrame() {
316: return frame;
317: }
318:
319: Map<String, Component> getAreas() {
320: return areas;
321: }
322:
323: public String getTitle() {
324: return componentTitle.getText();
325: }
326: }
|