View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 2000-2004 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  package org.exolab.castor.xml.descriptors;
36  
37  import java.util.ArrayList;
38  import java.util.List;
39  
40  import org.exolab.castor.mapping.AccessMode;
41  import org.exolab.castor.mapping.ClassDescriptor;
42  import org.exolab.castor.mapping.FieldDescriptor;
43  import org.exolab.castor.util.IteratorEnumeration;
44  import org.exolab.castor.xml.NodeType;
45  import org.exolab.castor.xml.TypeValidator;
46  import org.exolab.castor.xml.XMLFieldDescriptor;
47  import org.exolab.castor.xml.XMLFieldHandler;
48  import org.exolab.castor.xml.util.XMLFieldDescriptorImpl;
49  
50  /**
51   * The default java.util.List class descriptor.
52   *
53   * @author <a href="mailto:kvisco-at-intalio.com">Keith Visco</a>
54   * @version $Revision$ $Date: 2004-12-16 22:49:25 -0700 (Thu, 16 Dec 2004) $
55   */
56  public class ListClassDescriptor extends BaseDescriptor {
57  
58    /** The set of attribute descriptors. */
59    private static final XMLFieldDescriptor[] NO_ATTRIBUTES = new XMLFieldDescriptor[0];
60    /** The content descriptor. */
61    private static final XMLFieldDescriptorImpl NO_CONTENT = null;
62  
63    // --------------------/
64    // - Member Variables -/
65    // --------------------/
66  
67    /** The set of element descriptors. */
68    private final XMLFieldDescriptor[] _elements;
69    /** The set of field descriptors. */
70    private final FieldDescriptor[] _fields;
71    /** Our field descriptor. */
72    private final XMLFieldDescriptorImpl _desc = null;
73  
74    /** The XML name for the described object. */
75    private String _xmlName = null;
76    /** The desired XML name space for the described object. */
77    private String _nsURI = null;
78    /** The type validator for this instance. */
79    private TypeValidator _validator = null;
80  
81    // ----------------/
82    // - Constructors -/
83    // ----------------/
84  
85    /**
86     * No-arg constructor.
87     */
88    public ListClassDescriptor() {
89      this(null);
90    } // -- ListClassDescriptor
91  
92    /**
93     * Constructs a List Class Descriptor with the given XML name.
94     * 
95     * @param xmlName XML schema item name of the element we describe.
96     */
97    public ListClassDescriptor(final String xmlName) {
98      super();
99  
100     _xmlName = xmlName;
101 
102     // -- Create FieldDescriptor
103     XMLFieldDescriptorImpl desc =
104         new XMLFieldDescriptorImpl(Object.class, "item", _xmlName, NodeType.Element);
105 
106     desc.setMultivalued(true);
107     desc.setMatches("*");
108     desc.setHandler(new XMLFieldHandler() {
109 
110       /**
111        * {@inheritDoc}
112        */
113       public Object getValue(final Object object) throws IllegalStateException {
114         List list = (java.util.List) object;
115         return new IteratorEnumeration(list.iterator());
116       }
117 
118       /**
119        * {@inheritDoc}
120        */
121       public void setValue(final Object object, final Object value)
122           throws IllegalStateException, IllegalArgumentException {
123         try {
124           ((java.util.List) object).add(value);
125         } catch (Exception ex) {
126           throw new IllegalStateException(ex.toString());
127         }
128       }
129 
130       /**
131        * {@inheritDoc}
132        */
133       public Object newInstance(final Object parent) {
134         return new ArrayList();
135       }
136     });
137 
138     _fields = new FieldDescriptor[1];
139     _fields[0] = desc;
140 
141     _elements = new XMLFieldDescriptor[1];
142     _elements[0] = desc;
143   } // -- ListClassDescriptor()
144 
145   // -----------/
146   // - Methods -/
147   // -----------/
148 
149   /**
150    * Returns the set of attribute XMLFieldDescriptors.
151    *
152    * @return an array of XMLFieldDescriptors for all members that should be marshaled as attributes
153    */
154   public XMLFieldDescriptor[] getAttributeDescriptors() {
155     return NO_ATTRIBUTES;
156   } // -- getAttributeDescriptors()
157 
158   /**
159    * Returns the Class that this ClassDescriptor describes.
160    *
161    * @return the Class that this ClassDescriptor describes
162    */
163   public Class<?> getJavaClass() {
164     return java.util.List.class;
165   } // -- getClassType()
166 
167   /**
168    * Returns the set of element MarshalDescriptors.
169    *
170    * @return an array of MarshalDescriptors for all members that should be marshaled as Elements
171    */
172   public XMLFieldDescriptor[] getElementDescriptors() {
173     return _elements;
174   } // -- getElementDescriptors()
175 
176   /**
177    * Returns the class descriptor of the class extended by this class.
178    *
179    * @return The extended class descriptor
180    */
181   public ClassDescriptor getExtends() {
182     return null;
183   } // -- getExtends
184 
185   /**
186    * Returns a list of fields represented by this descriptor.
187    *
188    * @return A list of fields
189    */
190   public FieldDescriptor[] getFields() {
191     return _fields;
192   } // -- getFields
193 
194   /**
195    * Returns the descriptor for dealing with Text content.
196    * 
197    * @return the XMLFieldDescriptor for dealing with Text content
198    */
199   public XMLFieldDescriptor getContentDescriptor() {
200     return NO_CONTENT;
201   } // -- getContentDescriptor()
202 
203   /**
204    * Returns the XML field descriptor matching the given xml name and nodeType. If NodeType is null,
205    * then either an AttributeDescriptor, or ElementDescriptor may be returned. Null is returned if
206    * no matching descriptor is available.
207    *
208    * @param name the xml name to match against
209    * @param namespace the namespace uri
210    * @param nodeType the NodeType to match against, or null if the node type is not known.
211    * @return the matching descriptor, or null if no matching descriptor is available.
212    */
213   public XMLFieldDescriptor getFieldDescriptor(final String name, final String namespace,
214       final NodeType nodeType) {
215     if (nodeType == null || nodeType == NodeType.Element) {
216       for (int i = 0; i < _elements.length; i++) {
217         XMLFieldDescriptor desc = _elements[i];
218         if (desc != null && desc.matches(name)) {
219           return desc;
220         }
221       }
222     }
223     return null;
224   } // -- getFieldDescriptor
225 
226   /**
227    * @return the namespace prefix to use when marshaling as XML.
228    */
229   public String getNameSpacePrefix() {
230     return null;
231   } // -- getNameSpacePrefix
232 
233   /**
234    * @return the namespace URI used when marshalling and unmarshalling as XML.
235    */
236   public String getNameSpaceURI() {
237     return _nsURI;
238   } // -- getNameSpaceURI
239 
240   /**
241    * Returns the identity field, null if this class has no identity.
242    *
243    * @return The identity field
244    */
245   public FieldDescriptor getIdentity() {
246     return null;
247   } // -- getIdentity
248 
249   /**
250    * Returns the access mode specified for this class.
251    *
252    * @return The access mode
253    */
254   public AccessMode getAccessMode() {
255     return null;
256   } // -- getAccessMode
257 
258   /**
259    * Returns a specific validator for the class described by this ClassDescriptor. A null value may
260    * be returned if no specific validator exists.
261    *
262    * @return the type validator for the class described by this ClassDescriptor.
263    */
264   public TypeValidator getValidator() {
265     return _validator;
266   } // -- getValidator
267 
268   /**
269    * Returns the XML Name for the Class being described.
270    *
271    * @return the XML name.
272    */
273   public String getXMLName() {
274     return _xmlName;
275   } // -- getXMLName
276 
277   /**
278    * Sets the type validator to use for this list.
279    * 
280    * @param validator the type validator to use for this list.
281    */
282   public void setValidator(final TypeValidator validator) {
283     this._validator = validator;
284   } // -- setValidator
285 
286   /**
287    * Sets the XML Name for the described object.
288    *
289    * @param xmlName the XML name to use for the described object.
290    */
291   public void setXMLName(final String xmlName) {
292     if (xmlName != null && xmlName.length() > 0) {
293       _xmlName = xmlName;
294       _desc.setXMLName(xmlName);
295     }
296   } // -- setXMLName
297 
298   /**
299    * Sets the desired namespace URI for the described object.
300    *
301    * @param nsURI is the desired namespace URI
302    */
303   public void setNameSpaceURI(final String nsURI) {
304     this._nsURI = nsURI;
305   } // -- setNameSpaceURI
306 
307   /**
308    * Returns true if the given object represented by this XMLClassDescriptor can accept a member
309    * whose name is given. An XMLClassDescriptor can accept a field if it contains a descriptor that
310    * matches the given name and if the given object can hold this field (i.e a value is not already
311    * set for this field).
312    *
313    * @param name the xml name of the field to check
314    * @param namespace the namespace uri
315    * @param object the object represented by this XMLCLassDescriptor
316    * @return true if the given object represented by this XMLClassDescriptor can accept a member
317    *         whose name is given.
318    */
319   public boolean canAccept(final String name, final String namespace, final Object object) {
320     // ListClassDescriptor only contains one FieldDescriptor that matches with
321     // a wild-card '*', just return true since it can accept any object
322     return true;
323   }
324 
325 } // -- class: ListClassDescriptor