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.properties;
031:
032: import java.io.IOException;
033: import java.lang.reflect.Method;
034: import java.util.Collection;
035: import java.util.HashMap;
036: import java.util.Iterator;
037:
038: import com.jeta.forms.gui.beans.JETABean;
039: import com.jeta.forms.store.JETAObjectInput;
040: import com.jeta.forms.store.JETAObjectOutput;
041:
042: /**
043: * This class is used to manage a set if integer options for a bean property -
044: * for example, the options to set the horizontal alignment for the text in a
045: * JLabel. In the designer we don't want to display integer values to the user,
046: * instead we provide table of String descriptions that map to an associated
047: * integer value. The user is shown the strings in a combo. When the user makes
048: * a selection, the corresponding integer value is set in the bean.
049: *
050: * @author Jeff Tassin
051: */
052: public class TransformOptionsProperty extends JETAProperty implements
053: TransformProperty {
054: static final long serialVersionUID = -1652327155513571580L;
055:
056: /**
057: * The version of this class
058: */
059: public static final int VERSION = 3;
060:
061: /**
062: * The set of options available to the user m_options<String,Integer> where
063: * the String is the human readable name for the property value Integer is
064: * the actual property value.
065: */
066: private transient HashMap m_options = new HashMap();
067:
068: /**
069: * The default property value
070: */
071: private int m_default_value;
072:
073: /**
074: * The getter method for the property
075: */
076: private Method m_getter;
077:
078: /**
079: * The name of the getter method
080: */
081: private String m_getter_name;
082:
083: /**
084: * The setter method for the property
085: */
086: private Method m_setter;
087:
088: /**
089: * The name of the setter method
090: */
091: private String m_setter_name;
092:
093: /**
094: * The bean this property is bound to.
095: */
096: private transient JETABean m_bean;
097:
098: /**
099: * Creates an uninitialized <code>TransformOptionsProperty</code>
100: */
101: public TransformOptionsProperty() {
102:
103: }
104:
105: /**
106: * Creates a <code>TransformOptionsProperty</code> with the specified
107: * property name and methods.
108: *
109: * @param propName
110: * the name of the property associated with this transform.
111: * @param getMethod
112: * the name of the bean method to get the property value
113: * @param setMethdo
114: * the name of the bean method to set the property value
115: * @param options
116: * an Nx2 array of options for this transform. The first column
117: * is the integer value for the property. The second column is a
118: * human readable name that will be displayed in the designer
119: * properties table.
120: */
121: public TransformOptionsProperty(String propName, String getMethod,
122: String setMethod, Object[][] options) {
123: super (propName);
124: m_getter_name = getMethod;
125: m_setter_name = setMethod;
126: for (int index = 0; index < options.length; index++) {
127: String option = (String) options[index][0];
128: Integer value = (Integer) options[index][1];
129: if (index == 0)
130: m_default_value = value.intValue();
131:
132: m_options.put(option, value);
133: }
134: }
135:
136: /**
137: * Returns true if this property equals the given object.
138: */
139: public boolean equals(Object obj) {
140: if (obj == this )
141: return true;
142:
143: /** @JMT fix. this is a hack. */
144: if (obj instanceof Integer) {
145: return (((Integer) obj).intValue() == getPropertyValue());
146: } else if (obj instanceof TransformOptionsProperty) {
147: TransformOptionsProperty prop = (TransformOptionsProperty) obj;
148: return (prop.getPropertyValue() == getPropertyValue());
149: } else
150: return false;
151: }
152:
153: /**
154: * Returns the JETABean associated with this property. The JETABean contains
155: * the underlying Java bean.
156: *
157: * @return the bean this property is bound to.
158: */
159: public JETABean getBean() {
160: return m_bean;
161: }
162:
163: /**
164: * Returns the human readable string for the current property value of the
165: * Java bean associated with this object.
166: *
167: * @return the selected value
168: */
169: public Object getCurrentItem() {
170: int pval = getPropertyValue();
171: Iterator iter = m_options.keySet().iterator();
172: while (iter.hasNext()) {
173: String option = (String) iter.next();
174: Integer ival = (Integer) m_options.get(option);
175: if (ival.intValue() == pval)
176: return option;
177: }
178: return null;
179: }
180:
181: /**
182: * Return a collection of human readable options (Strings) for the
183: * associated property.
184: *
185: * @return the set of options available to the user
186: */
187: public Collection getOptions() {
188: return m_options.keySet();
189: }
190:
191: /**
192: * Returns the current property value of the Java bean associated with this
193: * property
194: *
195: * @return the current property value.
196: */
197: public int getPropertyValue() {
198: try {
199: Integer ival = (Integer) m_getter.invoke(getBean()
200: .getDelegate(), new Object[0]);
201: return ival.intValue();
202: } catch (Exception e) {
203: e.printStackTrace();
204: return m_default_value;
205: }
206: }
207:
208: /**
209: * Returns the setter method for this property
210: *
211: * @return the setter method for the property
212: */
213: public Method getWriteMethod() {
214: return m_setter;
215: }
216:
217: /**
218: * Returns true if this object is not serialiable.
219: *
220: * @return true if this object is not serializable
221: */
222: public boolean isTransient() {
223: return true;
224: }
225:
226: /**
227: * Sets the bean this property is bound to. This must be called right after
228: * initalization or de-serialization because the bean cannot get/set the
229: * properties on the bean without a reference to it.
230: */
231: public void setBean(JETABean bean) {
232: try {
233: m_bean = bean;
234: if (bean != null) {
235: Class c = bean.getDelegate().getClass();
236: m_getter = c.getMethod(m_getter_name, new Class[0]);
237: m_setter = c.getMethod(m_setter_name,
238: new Class[] { int.class });
239: }
240:
241: } catch (Exception e) {
242: e.printStackTrace();
243: }
244: }
245:
246: /**
247: * Sets this property to the specified value. If required, the value is
248: * first transformed to an integer. The associated Java bean is updated.
249: */
250: public void setValue(Object option) {
251: try {
252: Integer ival = null;
253: if (option instanceof String) {
254: String sval = (String) option;
255: ival = (Integer) m_options.get(sval);
256: if (ival == null) {
257: /**
258: * try to convert to an integer. this can happen when
259: * storing forms to XML. The option value will be restored
260: * as a String.
261: */
262: try {
263: ival = Integer.valueOf((String) option);
264: } catch (Exception e) {
265: // ignore here
266: }
267: }
268: } else if (option instanceof Integer) {
269: ival = (Integer) option;
270: } else if (option instanceof TransformOptionsProperty) {
271: ival = new Integer(((TransformOptionsProperty) option)
272: .getPropertyValue());
273: }
274:
275: if (ival != null) {
276: m_setter.invoke(getBean().getDelegate(),
277: new Object[] { ival });
278: }
279: } catch (Exception e) {
280: if (option != null) {
281: System.out
282: .println("TransformOptionsProperty.setValue failed: "
283: + option.getClass());
284: }
285: e.printStackTrace();
286: }
287: }
288:
289: /**
290: * Return the number of options in this property.
291: *
292: * @return the number of options in this property
293: */
294: public int size() {
295: return m_options.size();
296: }
297:
298: /**
299: * Updates the given bean with the latest value of this property.
300: */
301: public void updateBean(JETABean jbean) {
302: setBean(jbean);
303: }
304:
305: /**
306: * JETAPersistable Implementation
307: */
308: public void read(JETAObjectInput in) throws ClassNotFoundException,
309: IOException {
310: int version = in.readVersion();
311: }
312:
313: /**
314: * JETAPersistable Implementation
315: */
316: public void write(JETAObjectOutput out) throws IOException {
317: out.writeVersion(VERSION);
318: }
319:
320: public String toString() {
321: return "transform value: " + getPropertyValue();
322: }
323: }
|