001: /*
002: * Copyright (c) 2004 JETA Software, Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without modification,
005: * are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JETA Software nor the names of its contributors may
015: * be used to endorse or promote products derived from this software without
016: * specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
021: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
022: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
023: * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
024: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
025: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026: * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jeta.forms.store.bean;
031:
032: import java.awt.Component;
033: import java.util.Collection;
034: import java.util.Iterator;
035:
036: import javax.swing.JTable;
037: import javax.swing.table.DefaultTableModel;
038:
039: import com.jeta.forms.beanmgr.BeanManager;
040: import com.jeta.forms.gui.beans.JETABean;
041: import com.jeta.forms.gui.beans.JETAPropertyDescriptor;
042: import com.jeta.forms.gui.common.FormException;
043: import com.jeta.forms.logger.FormsLogger;
044: import com.jeta.forms.store.memento.PropertiesMemento;
045: import com.jeta.forms.store.properties.ColorHolder;
046: import com.jeta.forms.store.properties.FontProperty;
047: import com.jeta.open.registry.JETARegistry;
048:
049: /**
050: * An implementation of BeanDeserializer that defines how a bean is instantiated
051: * and intialized from a PropertiesMemento instance. See
052: * {@link com.jeta.forms.store.memento.PropertiesMemento}
053: *
054: * @author Jeff Tassin
055: */
056: public class DefaultBeanDeserializer implements BeanDeserializer {
057: /**
058: * The properties that are used as a basis for creating and initializing a
059: * JETABean.
060: */
061: private PropertiesMemento m_memento;
062:
063: /**
064: * Creates a <code>DefaultBeanDeserializer</code> instance with the
065: * specified PropertiesMemento object.
066: *
067: * @param memento
068: * the properties memento that will be used to create and
069: * initialize java beans.
070: */
071: public DefaultBeanDeserializer(PropertiesMemento memento) {
072: m_memento = memento;
073: }
074:
075: /**
076: * Returns the PropertiesMemento object that is used to create and
077: * initialize java bean instances.
078: *
079: * @return the properties memento associated with this deserializer.
080: */
081: public PropertiesMemento getProperties() {
082: return m_memento;
083: }
084:
085: /**
086: * Creates an unitialized Java Bean component using the properties memento
087: * associated with this deserializer.
088: *
089: * @return a default Java Bean component.
090: */
091: public Component createBean() throws FormException {
092: try {
093: Class bean_class = null;
094:
095: try {
096: /**
097: * first, try the bean manager. This is for Java beans that were
098: * imported in the designer
099: */
100: BeanManager bmgr = (BeanManager) JETARegistry
101: .lookup(BeanManager.COMPONENT_ID);
102: if (bmgr != null) {
103: bean_class = bmgr.getBeanClass(m_memento
104: .getBeanClassName());
105: }
106: } catch (Exception e) {
107: FormsLogger.severe(e);
108: }
109:
110: if (bean_class == null) {
111: bean_class = Class
112: .forName(m_memento.getBeanClassName());
113: }
114:
115: Component comp = (Component) bean_class.newInstance();
116: return comp;
117: } catch (Exception e) {
118: FormsLogger.severe(e);
119:
120: if (e instanceof FormException)
121: throw (FormException) e;
122: throw new FormException(e);
123: }
124: }
125:
126: /**
127: * Sets the property values of a java bean using the PropertiesMemento
128: * contained by this deserializer. Both standard and custom property values
129: * are set.
130: *
131: * @param jbean
132: * the container for the Java bean that will be intialize
133: */
134: public void initializeBean(JETABean jbean) throws FormException {
135: if (jbean == null)
136: return;
137:
138: try {
139: Component comp = jbean.getDelegate();
140: /**
141: * Special handling for JList because we need to set the list model
142: * to DefaultListModel this is for the custom ItemsProperty. It
143: * might be better to provide specialized JList and JTable
144: * deserializers in the future.
145: */
146: if (comp instanceof javax.swing.JList) {
147: ((javax.swing.JList) comp)
148: .setModel(new javax.swing.DefaultListModel());
149: } else if (comp instanceof JTable) {
150: JTable table = (JTable) comp;
151: Object model = table.getModel();
152: /**
153: * Add a few default columns and rows to give the table a little
154: * more identity on the form. Do this only if this is not a
155: * specialized type of JTable where the table model might be set
156: * in the derived class.
157: */
158: if ((model instanceof DefaultTableModel)) {
159: DefaultTableModel tmodel = (DefaultTableModel) model;
160: if (tmodel.getColumnCount() == 0) {
161: tmodel.addColumn("A");
162: tmodel.addColumn("B");
163: tmodel.addRow(new Object[] { "", "" });
164: tmodel.addRow(new Object[] { "", "" });
165: }
166: }
167: }
168:
169: if (comp != null) {
170: Collection jeta_pds = jbean.getPropertyDescriptors();
171: Iterator iter = jeta_pds.iterator();
172: while (iter.hasNext()) {
173: JETAPropertyDescriptor jpd = (JETAPropertyDescriptor) iter
174: .next();
175: try {
176: if (m_memento.containsProperty(jpd.getName())) {
177: Object prop_value = m_memento
178: .getPropertyValue(jpd.getName());
179: // System.out.println( "default bean deserializer
180: // prop
181: // descriptor: " + jpd.getName() + " mementovalue: "
182: // +
183: // prop_value + " comp: " + comp.getClass() );
184:
185: if (prop_value instanceof FontProperty) {
186: /**
187: * we need to do this because de-serialized
188: * fonts from Linux(and probabaly Windows) have
189: * problems on OS X
190: */
191: prop_value = ((FontProperty) prop_value)
192: .getFont();
193: } else if (prop_value instanceof ColorHolder) {
194: /**
195: * Some Look and Feels use specialized Color
196: * objects that are invalid if the L&F is not
197: * present in the classpath. We don't form files
198: * to be dependent on any look and feel, so we
199: * need to store color holders instead of Color
200: * objects
201: */
202: prop_value = ((ColorHolder) prop_value)
203: .getColor();
204: }
205:
206: /**
207: * We allow properties to be stored as strings in
208: * the memento. So check if it can be converted to
209: * the appropriate type (only support Primitive
210: * conversions for now )
211: */
212: jpd.setPropertyValue(jbean, convertValue(
213: jpd.getPropertyType(), prop_value));
214: }
215: } catch (Exception e) {
216: FormsLogger.debug(e);
217: }
218: }
219:
220: /**
221: * Always store the component name. I've encountered some Java
222: * Beans that don't define the 'name' property in the BeanInfo
223: * class. Since this architecture depends on the component name,
224: * we need to store it here regardless of whether it is declared
225: * in the bean info
226: */
227: try {
228: if (m_memento.containsProperty("name"))
229: comp.setName((String) m_memento
230: .getPropertyValue("name"));
231: } catch (Exception e) {
232: FormsLogger.severe(e);
233: }
234: }
235: } catch (Exception e) {
236: e.printStackTrace();
237:
238: if (e instanceof FormException)
239: throw (FormException) e;
240: throw new FormException(e);
241: }
242: }
243:
244: /**
245: * Converts a stored property value to the correct type in the bean. This is
246: * mainly to support storing Java primitives as String objects (when storing
247: * to XML).
248: */
249: private Object convertValue(Class c, Object prop_value) {
250:
251: String propclass = prop_value == null ? "null" : prop_value
252: .getClass().getName();
253: if (prop_value instanceof String) {
254: String sval = (String) prop_value;
255: if (c == Boolean.class || c == boolean.class)
256: return Boolean.valueOf(sval);
257: else if (c == Byte.class || c == byte.class)
258: return Byte.valueOf(sval);
259: else if (c == Character.class || c == char.class)
260: return new Character(sval.length() == 0 ? '\0' : sval
261: .charAt(0));
262: else if (c == Short.class || c == short.class)
263: return Short.valueOf(sval);
264: else if (c == Integer.class || c == int.class)
265: return Integer.valueOf(sval);
266: else if (c == Long.class || c == long.class)
267: return Long.valueOf(sval);
268: else if (c == Float.class || c == float.class)
269: return Float.valueOf(sval);
270: else if (c == Double.class || c == double.class)
271: return Double.valueOf(sval);
272: }
273: return prop_value;
274: }
275:
276: }
|