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