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 (C) Intalio, Inc. All Rights Reserved. 32 * 33 * $Id$ 34 */ 35 package org.exolab.castor.xml.handlers; 36 37 import java.lang.reflect.Array; 38 import java.util.StringTokenizer; 39 40 import org.exolab.castor.mapping.FieldHandler; 41 import org.exolab.castor.mapping.ValidityException; 42 import org.exolab.castor.xml.TypeValidator; 43 import org.exolab.castor.xml.ValidationException; 44 import org.exolab.castor.xml.XMLFieldHandler; 45 46 /** 47 * A FieldHandler for the XML Schema Collection type. 48 * <p> 49 * TODO : support all kind of XSList. 50 * 51 * @author <a href="blandin@intalio.com">Arnaud Blandin</a> 52 * @version $Revision$ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 2003) $ 53 */ 54 public class CollectionFieldHandler extends XMLFieldHandler { 55 56 /** The field handler to which we delegate. */ 57 private final FieldHandler _handler; 58 /** Type validator to use to validate an instance of this type. */ 59 private final TypeValidator _validator; 60 61 // ----------------/ 62 // - Constructors -/ 63 // ----------------/ 64 65 /** 66 * Creates a new CollectionFieldHandler using the given FieldHandler for delegation. 67 * 68 * @param fieldHandler the fieldHandler for delegation. 69 */ 70 public CollectionFieldHandler(final FieldHandler fieldHandler) { 71 this(fieldHandler, null); 72 } // -- CollectionFieldHandler 73 74 /** 75 * Creates a new CollectionFieldHandler using the given FieldHandler for delegation and the given 76 * type validator for validation. 77 * 78 * @param fieldHandler the fieldHandler for delegation. 79 * @param validator Type validator to use to validate an instance of this type. 80 */ 81 public CollectionFieldHandler(final FieldHandler fieldHandler, final TypeValidator validator) { 82 super(); 83 if (fieldHandler == null) { 84 String err = "The FieldHandler argument passed to " 85 + "the constructor of CollectionFieldHandler must not be null."; 86 throw new IllegalArgumentException(err); 87 } 88 this._handler = fieldHandler; 89 this._validator = validator; 90 } // -- CollectionFieldHandler 91 92 // ------------------/ 93 // - Public Methods -/ 94 // ------------------/ 95 96 /** 97 * Sets the value of the field associated with this descriptor. If paased a String, then String is 98 * tokenized and each token is added as an individual instance to the collection. 99 * 100 * @param target the object in which to set the value 101 * @param value the value of the field 102 * @throws IllegalStateException if any value provided fails validation. 103 */ 104 public void setValue(final Object target, final Object value) 105 throws java.lang.IllegalStateException { 106 if (value == null) { 107 return; 108 } 109 110 // If not a String, assume we are passed something the field handler understands 111 if (!(value instanceof String)) { 112 _handler.setValue(target, value); 113 return; 114 } 115 116 StringTokenizer temp = new StringTokenizer((java.lang.String) value, " "); 117 final int size = temp.countTokens(); 118 for (int i = 0; i < size; i++) { 119 String tempValue = temp.nextToken(); 120 try { 121 if (_validator != null) { 122 _validator.validate(tempValue, null); 123 } 124 } catch (ValidationException e) { 125 throw new IllegalStateException(e.getMessage()); 126 } 127 _handler.setValue(target, tempValue); 128 } 129 } // -- setValue 130 131 /** 132 * Gets the value of the field associated with this descriptor. If the value is an array, it 133 * returns a string 'representing' this array 134 * 135 * @param target the object from which to get the value 136 * @return the value of the field associated with this descriptor. 137 * @throws IllegalStateException if any value provided fails validation. 138 */ 139 public Object getValue(final Object target) throws java.lang.IllegalStateException { 140 // Needs to return the proper object 141 Object temp = _handler.getValue(target); 142 143 if (temp == null) { 144 return temp; 145 } 146 147 if (!temp.getClass().isArray()) { 148 return temp.toString(); 149 } 150 151 int size = Array.getLength(temp); 152 if (size == 0) { 153 return null; 154 } 155 156 StringBuilder result = new StringBuilder(); 157 for (int i = 0; i < size; i++) { 158 if (i > 0) { 159 result.append(' '); 160 } 161 Object obj = Array.get(temp, i); 162 result.append(obj); 163 } 164 return result.toString(); 165 } 166 167 /** 168 * Sets the value of the field to a default value. 169 * 170 * @param target The object to reset 171 * @throws IllegalStateException if the Java object has changed and is no longer supported by this 172 * handler or the handler is not compatible with the Java object 173 */ 174 public void resetValue(final Object target) throws java.lang.IllegalStateException { 175 _handler.resetValue(target); 176 } 177 178 /** 179 * Checks the field validity. Returns successfully if the field can be stored, is valid, etc, 180 * throws an exception otherwise. 181 * 182 * @param object The object 183 * @throws ValidityException The field is invalid, is required and null, or any other validity 184 * violation 185 * @throws IllegalStateException The Java object has changed and is no longer supported by this 186 * handler, or the handler is not compatiable with the Java object 187 */ 188 public void checkValidity(final Object object) throws ValidityException, IllegalStateException { 189 // -- do nothing for now 190 } // -- checkValidity 191 192 /** 193 * Creates a new instance of the object described by this field. 194 * 195 * @param parent The object for which the field is created 196 * @return A new instance of the field's value 197 * @throws IllegalStateException This field is a simple type and cannot be instantiated 198 */ 199 public Object newInstance(final Object parent) throws IllegalStateException { 200 return null; 201 } // -- newInstance 202 203 /** 204 * Returns true if the given object is an XMLFieldHandler that is equivalent to the delegated 205 * handler. An equivalent XMLFieldHandler is an XMLFieldHandler that is an instances of the same 206 * class. 207 * 208 * @param obj The object to compare to <code>this</code>. 209 * 210 * @return true if the given object is an XMLFieldHandler that is equivalent to this one. 211 */ 212 public boolean equals(final Object obj) { 213 if (obj == null || !(obj instanceof XMLFieldHandler)) { 214 return false; 215 } 216 return _handler.getClass().isInstance(obj); 217 } // -- equals 218 219 } // -- CollectionFieldHandler