View Javadoc
1   package org.exolab.castor.mapping.loader;
2   
3   import java.util.Comparator;
4   import java.util.HashMap;
5   import java.util.HashSet;
6   import java.util.Map;
7   import java.util.Set;
8   
9   import org.exolab.castor.mapping.ClassDescriptor;
10  import org.exolab.castor.mapping.FieldDescriptor;
11  import org.exolab.castor.mapping.FieldHandler;
12  import org.exolab.castor.mapping.xml.types.FieldMappingCollectionType;
13  
14  public class FieldDescriptorImpl implements FieldDescriptor {
15  
16      /** A reference to the containing class descriptor (parent). */
17      private ClassDescriptor _parent;
18  
19      /** The name of the field. */
20      private String _fieldName;
21  
22      /** The type of the field. */
23      private Class<?> _fieldType;
24  
25      /** The type class descriptor, if this field is of a type known by a descriptor. */
26      private ClassDescriptor _classDescriptor;
27      
28      /** The field handler for get/set field value. */
29      private FieldHandler _handler;
30  
31      /** True if the field is transient and should not be saved/stored. */
32      private boolean _transient;
33  
34      /** True if the described field type is immutable. */
35      private boolean _immutable;
36      
37      /** True if the field type is required. */
38      private boolean _required;
39  
40      /** True if access to field is direct. */
41      private boolean _direct;
42      
43      /** True if access to field is lazy. */
44      private boolean _lazy;
45      
46      /** True if the object described by this descriptor is multi-valued. */
47      private boolean _multivalued;
48      
49      /** True if the field is part of the identity of the class. */
50      private boolean _identity;
51  
52      /** The name of a class that implements the {@link Comparator} interface. */
53      private String _comparator;
54  
55      /** The name of the 'getter' method used to obtain the value of a property. */
56      private String _getMethod;
57  
58      /** The name of the 'setter' method used to set the value of a property. */
59      private String _setMethod;
60  
61      /** The name of the 'create' method used to create an instance of a property. */
62      private String _createMethod;
63      
64      /** The type of the collection, if the field is multi-valued. */
65      private FieldMappingCollectionType _collection;
66  
67      /**
68       * Map holding the properties set and read by natures.
69       */
70      private Map<String, Object> _properties = new HashMap<String, Object>();
71  
72      /**
73       * Map holding the available natures.
74       */
75      private Set<String> _natures = new HashSet<String>();
76      
77      /**
78       * Creates a default instance of a field descriptor.
79       */
80      protected FieldDescriptorImpl() { }
81  
82      /**
83       * Constructs a new field descriptor.
84       *
85       * @param fieldName The field name
86       * @param typeInfo The field type information
87       * @param handler The field handler (may be null)
88       * @param isTransitive True if the field is transient
89       */
90      public FieldDescriptorImpl(final String fieldName, 
91              final TypeInfo typeInfo,
92              final FieldHandler handler, 
93              final boolean isTransitive) {
94          
95          if (fieldName == null) {
96              throw new IllegalArgumentException("Internal error. Field name not specified.");
97          }
98          
99          if (handler == null) {
100             throw new IllegalArgumentException("Internal error. No FieldHandler provided.");
101         }
102         
103         setFieldName(fieldName);
104         setFieldType(typeInfo.getFieldType());
105         setHandler(handler);
106         setTransient(isTransitive);
107         setImmutable(typeInfo.isImmutable());
108         setRequired(typeInfo.isRequired());
109         setMultivalued(typeInfo.getCollectionHandler() != null);
110     }
111 
112     /**
113      * @see org.exolab.castor.mapping.FieldDescriptor#setContainingClassDescriptor(
114      *      org.exolab.castor.mapping.ClassDescriptor)
115      * {@inheritDoc}
116      */
117     public final void setContainingClassDescriptor(final ClassDescriptor parent) {
118         _parent = parent;
119     }
120     
121     /**
122      * @see org.exolab.castor.mapping.FieldDescriptor#getContainingClassDescriptor()
123      * {@inheritDoc}
124      */
125     public final ClassDescriptor getContainingClassDescriptor() {
126         return _parent;
127     }
128     
129     /**
130      * Set the name of the field.
131      * 
132      * @param fieldName Field name.
133      */
134     public final void setFieldName(final String fieldName) {
135         _fieldName = fieldName;
136     }
137 
138     /**
139      * @see org.exolab.castor.mapping.FieldDescriptor#getFieldName()
140      * {@inheritDoc}
141      */
142     public final String getFieldName() {
143         return _fieldName;
144     }
145 
146     /**
147      * Set the type of the field.
148      * 
149      * @param fieldType Field type.
150      */
151     public final void setFieldType(final Class<?> fieldType) {
152         _fieldType = fieldType;
153     }
154 
155     /**
156      * @see org.exolab.castor.mapping.FieldDescriptor#getFieldType()
157      * {@inheritDoc}
158      */
159     public final Class<?> getFieldType() {
160         return _fieldType;
161     }
162 
163     /**
164      * Set the ClassDescriptor for the described field.
165      *
166      * @param classDescriptor The ClassDescriptor for the described field.
167      */
168     public final void setClassDescriptor(final ClassDescriptor classDescriptor) {
169         _classDescriptor = classDescriptor;
170     }
171 
172     /**
173      * @see org.exolab.castor.mapping.FieldDescriptor#getClassDescriptor()
174      * {@inheritDoc}
175      */
176     public final ClassDescriptor getClassDescriptor() {
177         return _classDescriptor;
178     }
179 
180     /**
181      * Set the FieldHandler for the field being described by this FieldDescriptor.
182      *
183      * @param handler The FieldHandler for the field being described.
184      */
185     public final void setHandler(final FieldHandler handler) {
186         _handler = handler;
187     }
188 
189     /**
190      * @see org.exolab.castor.mapping.FieldDescriptor#getHandler()
191      * {@inheritDoc}
192      */
193     public final FieldHandler getHandler() {
194         return _handler;
195     }
196 
197     /**
198      * Sets whether or not the describled field is 'transient'.
199      * 
200      * @param isTransient The flag indicating if the described field is 'transient'.
201      */
202     public final void setTransient(final boolean isTransient) {
203         _transient = isTransient;
204     }
205 
206     /**
207      * @see org.exolab.castor.mapping.FieldDescriptor#isTransient()
208      * {@inheritDoc}
209      */
210     public final boolean isTransient() {
211         return _transient;
212     }
213 
214     /**
215      * Set the immutable flag which indicates that changes to this Field result in a
216      * new Object to be created, such as java.lang.String. It serves to identify fields
217      * which should not be constructed until all the data is available.
218      * 
219      * @param immutable Flag which if true indicates that the field is immutable.
220      */
221     public final void setImmutable(final boolean immutable) {
222         _immutable = immutable;
223     }
224 
225     /**
226      * @see org.exolab.castor.mapping.FieldDescriptor#isImmutable()
227      * {@inheritDoc}
228      */
229     public final boolean isImmutable() {
230         return _immutable;
231     }
232 
233     /**
234      * Set whether or not the described field is required.
235      * 
236      * @param required The flag indicating whether or not the described field is required.
237      */
238     public final void setRequired(final boolean required) {
239         _required = required;
240     }
241 
242     /**
243      * @see org.exolab.castor.mapping.FieldDescriptor#isRequired()
244      * {@inheritDoc}
245      */
246     public final boolean isRequired() {
247         return _required;
248     }
249 
250     /**
251      * Set wheter the object described by this descriptor is multivalued or not.
252      * 
253      * @param multivalued True if the object described by this descriptor is multivalued.
254      */
255     public final void setMultivalued(final boolean multivalued) {
256         _multivalued = multivalued;
257     }
258     
259     /**
260      * @see org.exolab.castor.mapping.FieldDescriptor#isMultivalued()
261      * {@inheritDoc}
262      */
263     public final boolean isMultivalued() {
264         return _multivalued;
265     }
266     
267     /**
268      * Set wether the described field is part of the identity of the class it belongs to.
269      * 
270      * @param identity <code>true</code> if field is part of the classes identity.
271      */
272     public final void setIdentity(final boolean identity) {
273         _identity = identity;
274     }
275     
276     /**
277      * Is the described field is part of the identity of the class it belongs to?
278      * 
279      * @return <code>true</code> if field is part of the classes identity.
280      */
281     public final boolean isIdentity() {
282         return _identity;
283     }
284 
285     /**
286      * @see org.exolab.castor.builder.info.nature.PropertyHolder#
287      *      getProperty(java.lang.String)
288      * @param name
289      *            of the property
290      * @return value of the property
291      */
292     public Object getProperty(final String name) {
293         return _properties.get(name);
294     }
295 
296     /**
297      * @see org.exolab.castor.builder.info.nature.PropertyHolder#
298      *      setProperty(java.lang.String, java.lang.Object)
299      * @param name
300      *            of the property
301      * @param value
302      *            of the property
303      */
304     public void setProperty(final String name, final Object value) {
305         _properties.put(name, value);
306     }
307 
308     /**
309      * @see org.exolab.castor.builder.info.nature.NatureExtendable#
310      *      addNature(java.lang.String)
311      * @param nature
312      *            ID of the Nature
313      */
314     public void addNature(final String nature) {
315         _natures.add(nature);
316     }
317 
318     /**
319      * @see org.exolab.castor.builder.info.nature.NatureExtendable#
320      *      hasNature(java.lang.String)
321      * @param nature
322      *            ID of the Nature
323      * @return true if the Nature ID was added.
324      */
325     public boolean hasNature(final String nature) {
326         return _natures.contains(nature);
327     }
328 
329     public String getComparator() {
330         return _comparator;
331     }
332 
333     public void setComparator(String comparator) {
334         _comparator = comparator;
335     }
336 
337     public FieldMappingCollectionType getCollection() {
338         return _collection;
339     }
340 
341     public void setCollection(FieldMappingCollectionType collection) {
342         _collection = collection;
343     }
344 
345     public boolean isDirect() {
346         return _direct;
347     }
348 
349     public void setDirect(boolean direct) {
350         _direct = direct;
351     }
352 
353     public String getGetMethod() {
354         return _getMethod;
355     }
356 
357     public void setGetMethod(String getMethod) {
358         _getMethod = getMethod;
359     }
360 
361     public String getSetMethod() {
362         return _setMethod;
363     }
364 
365     public void setSetMethod(String setMethod) {
366         _setMethod = setMethod;
367     }
368 
369     public String getCreateMethod() {
370         return _createMethod;
371     }
372 
373     public void setCreateMethod(String createMethod) {
374         _createMethod = createMethod;
375     }
376 
377     public boolean isLazy() {
378         return _lazy;
379     }
380 
381     public void setLazy(boolean lazy) {
382         _lazy = lazy;
383     }
384 
385     public String toString() {
386         StringBuffer buffer = new StringBuffer();
387         buffer.append(getFieldName() + "(" + getFieldType().getName() + ")");
388         // TODO[WG]: find a way to emit additional nature-specific information.
389 //        try {
390 //            Class natureClass = Class.forName("org.exolab.castor.jdo.engine.nature.FieldDescriptorJDONature");
391 //            if (hasNature(natureClass.getName())) {
392 //                FieldDescriptorJDONature jdoNature = new FieldDescriptorJDONature(this);
393 //                buffer.append(jdoNature.getSQLName() == null ? "" : " AS " 
394 //                    + jdoNature.getSQLName()[0]);
395 //            }
396 //        } catch (ClassNotFoundException e) {
397 //            // ignore
398 //        }
399         return buffer.toString();
400     }
401 
402 }