001: package com.xoetrope.data.pojo;
002:
003: import java.lang.reflect.Method;
004: import java.util.Iterator;
005: import java.util.Set;
006: import java.util.SortedMap;
007: import java.util.TreeMap;
008:
009: /**
010: * A structures begin used to store the pojo properties
011: */
012: public class XPojoProperties {
013: // regular POJO properties
014: private SortedMap properties;
015: // transient properties
016: private SortedMap transientProperties;
017: // stores the property names
018: private String[] propertyKeys;
019: // stores the transient property names
020: private String[] transientPropertyKeys;
021:
022: /**
023: * Creates a new instance of XPojoProperties
024: */
025: public XPojoProperties() {
026: properties = new TreeMap();
027: transientProperties = new TreeMap();
028: }
029:
030: /**
031: * A structure for storing regular POJO
032: * property details.
033: */
034: private class Property {
035: public Method getter = null;
036: public Method setter = null;
037: public Class collectionOf = null;
038: }
039:
040: /**
041: * A structure for storing transient POJO
042: * property details.
043: */
044: private class TransientProperty {
045: public Class propertyType = null;
046: public Class collectionOf = null;
047: }
048:
049: /**
050: * Gets the names of the regular POJO properties
051: * @return set containing the names
052: */
053: public Set getPropertyNames() {
054: return properties.keySet();
055: }
056:
057: /**
058: * Gets the names of the transient properties
059: * @return set containing the names
060: */
061: public Set getTransientPropertyNames() {
062: return transientProperties.keySet();
063: }
064:
065: /**
066: * Gets the property details associated with the given
067: * property name.
068: * @param propertyName the name of the property
069: * @return the requested property
070: */
071: private Property getProperty(String propertyName) {
072: Property property = (Property) properties.get(propertyName);
073: if (property == null) {
074: // remove the transient property if one exists
075: if (transientProperties.containsKey(propertyName))
076: transientProperties.remove(propertyName);
077: // add a new property to the list of properties
078: properties.put(propertyName, property = new Property());
079: }
080: return property;
081: }
082:
083: /**
084: * Gets the transient property details associated with the
085: * given property name.
086: * @param propertyName the name of the property
087: * @return the requested property
088: */
089: public TransientProperty getTransientProperty(String propertyName) {
090: TransientProperty property = (TransientProperty) transientProperties
091: .get(propertyName);
092: if (property == null) {
093: // remove a "regular" property if one exists
094: if (properties.containsKey(propertyName))
095: properties.remove(propertyName);
096: // add a new property to the list of transient properties
097: transientProperties.put(propertyName,
098: property = new TransientProperty());
099: }
100: return property;
101: }
102:
103: /**
104: * Maps the specified property name to the specified getter method
105: * @param propertyName the name of the property
106: * @param propertyValue the getter method of the property
107: */
108: protected void setPropertyGetter(String propertyName,
109: Method propertyValue) {
110: if (propertyName != null)
111: getProperty(propertyName).getter = propertyValue;
112: }
113:
114: /**
115: * Returns the getter of the specified property.
116: * @param propertyName the name of the property whose getter
117: * is to be retrieved
118: * @return the getter method
119: */
120: public Method getPropertyGetter(String propertyName) {
121: Property property = (Property) properties.get(propertyName);
122: return (property != null ? property.getter : null);
123: }
124:
125: /**
126: * Maps the specified property name to the specified setter method
127: * @param propertyName the name of the property
128: * @param propertyValue the setter method of the property
129: */
130: protected void setPropertySetter(String propertyName,
131: Method propertyValue) {
132: if (propertyName != null)
133: getProperty(propertyName).setter = propertyValue;
134: }
135:
136: /**
137: * Returns the setter of the specified property.
138: * @param property the name of the property whose
139: * setter is to be retrieved
140: * @return the setter method.
141: */
142: public Method getPropertySetter(String propertyName) {
143: Property property = (Property) properties.get(propertyName);
144: return (property != null ? property.setter : null);
145: }
146:
147: /*
148: * Marks that the specified collection is intended to store elements
149: * of the specified type.
150: * @param propertyName the name of the property holding a collection.
151: * @param collectionType the type of the collection elements.
152: */
153: protected void setCollectionType(String propertyName,
154: Class collectionType) {
155: if (propertyName != null)
156: getProperty(propertyName).collectionOf = collectionType;
157: }
158:
159: /**
160: * Returns the class whose instances are stored by the
161: * specified collection
162: * @param propertyName the name of the property
163: * holding a collection
164: * @return the Class object.
165: */
166: protected Class getCollectionType(String propertyName) {
167: Property property = (Property) properties.get(propertyName);
168: return (property != null ? property.collectionOf : null);
169: }
170:
171: /**
172: * Sets the type of the specified property.
173: * @param propertyName the name of the property.
174: * @param type the class whose istance is held by the property
175: */
176: protected void setTransientPropertyType(String propertyName,
177: Class type) {
178: if (propertyName != null)
179: getTransientProperty(propertyName).propertyType = type;
180: }
181:
182: /**
183: * Gets the class whose istance is held by the specified
184: * transient property.
185: * @param propertyName the name of the property whose type
186: * is to be retrieved
187: * @return the type of the property
188: */
189: public Class getTransientPropertyType(String propertyName) {
190: TransientProperty property = (TransientProperty) transientProperties
191: .get(propertyName);
192: return (property != null ? property.propertyType : null);
193: }
194:
195: /**
196: * Marks that the specified transient collection is intended to store elements
197: * of the specified type.
198: * @param propertyName the name of the property holding a collection
199: * @param collectionType the type of the collection elements.
200: */
201: protected void setTransientCollectionType(String propertyName,
202: Class collectionType) {
203: if (propertyName != null)
204: getTransientProperty(propertyName).collectionOf = collectionType;
205: }
206:
207: /**
208: * Returns the class whose instances are stored by the specified
209: * transient collection.
210: * @param propertyName the name of the transient property holding
211: * a collection.
212: * @return the Class object.
213: */
214: public Class getTransientCollectionType(String propertyName) {
215: TransientProperty property = (TransientProperty) transientProperties
216: .get(propertyName);
217: return (property != null ? property.collectionOf : null);
218: }
219:
220: /**
221: * Gets the name of the property at the specified index
222: * @param idx the index of the requested property
223: * @return the name of the property
224: */
225: protected String getPropertyName(int idx) {
226: String propertyName = null;
227: if (idx < propertyKeys.length)
228: propertyName = propertyKeys[idx];
229: else if (idx - propertyKeys.length < transientPropertyKeys.length)
230: propertyName = transientPropertyKeys[idx
231: - propertyKeys.length];
232: return propertyName;
233: }
234:
235: /**
236: * Gets the property value located at the specified index.
237: * @param idx the index of the requested property
238: * @return the getter method of the Class object.
239: */
240: protected Object getProperty(int idx) {
241: String propertyName = getPropertyName(idx);
242: Object propertyValue = getPropertyGetter(propertyName);
243: return (propertyValue != null ? propertyValue
244: : getTransientPropertyType(propertyName));
245: }
246:
247: /**
248: * Gets the setter of the property located at the specified index
249: * @param idx the index of the property whose setter is to be returned.
250: * @return the setter method
251: */
252: protected Method getPropertySetter(int idx) {
253: String propertyName = getPropertyName(idx);
254: return (propertyName != null ? getPropertySetter(propertyName)
255: : null);
256: }
257:
258: /**
259: * Gets the total number of properties
260: * @return the number of properties
261: */
262: protected int getNumProperties() {
263: return (properties.keySet().size() + transientProperties
264: .keySet().size());
265: }
266:
267: /**
268: * Create the table containing property names
269: * and transient property names
270: */
271: protected void createKeyTables() {
272: // create the "regular" property keys table
273: Set keySet1 = properties.keySet();
274: propertyKeys = new String[keySet1.size()];
275: Iterator iter1 = keySet1.iterator();
276: for (int i = 0; iter1.hasNext(); i++)
277: propertyKeys[i] = (String) iter1.next();
278:
279: // create the transient property keys table
280: Set keySet2 = transientProperties.keySet();
281: transientPropertyKeys = new String[keySet2.size()];
282: Iterator iter2 = keySet2.iterator();
283: for (int i = 0; iter2.hasNext(); i++)
284: transientPropertyKeys[i] = (String) iter2.next();
285: }
286:
287: }
|