1 /* 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided that the 4 * following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright statements and 7 * notices. Redistributions must also contain a copy of this document. 8 * 9 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * 13 * 3. The name "Exolab" must not be used to endorse or promote products derived 14 * from this Software without prior written permission of Intalio, Inc. For 15 * written permission, please contact info@exolab.org. 16 * 17 * 4. Products derived from this Software may not be called "Exolab" nor may 18 * "Exolab" appear in their names without prior written permission of Intalio, 19 * Inc. Exolab is a registered trademark of Intalio, Inc. 20 * 21 * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/). 22 * 23 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY 24 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR 27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 * Copyright 2000 (C) Intalio, Inc. All Rights Reserved. 35 * 36 * $Id$ 37 */ 38 package org.exolab.castor.xml.handlers; 39 40 import java.lang.reflect.Array; 41 import java.util.StringTokenizer; 42 43 import org.exolab.castor.mapping.FieldHandler; 44 import org.exolab.castor.mapping.ValidityException; 45 import org.exolab.castor.xml.TypeValidator; 46 import org.exolab.castor.xml.ValidationException; 47 import org.exolab.castor.xml.XMLFieldHandler; 48 49 /** 50 * A FieldHandler for the XML Schema Collection type. 51 * <p> 52 * TODO : support all kind of XSList. 53 * 54 * @author <a href="blandin@intalio.com">Arnaud Blandin</a> 55 * @version $Revision$ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 56 * 2003) $ 57 */ 58 public class CollectionFieldHandler extends XMLFieldHandler { 59 60 /** The field handler to which we delegate. */ 61 private final FieldHandler _handler; 62 /** Type validator to use to validate an instance of this type. */ 63 private final TypeValidator _validator; 64 65 // ----------------/ 66 // - Constructors -/ 67 // ----------------/ 68 69 /** 70 * Creates a new CollectionFieldHandler using the given FieldHandler for 71 * delegation. 72 * 73 * @param fieldHandler the fieldHandler for delegation. 74 */ 75 public CollectionFieldHandler(final FieldHandler fieldHandler) { 76 this(fieldHandler, null); 77 } // -- CollectionFieldHandler 78 79 /** 80 * Creates a new CollectionFieldHandler using the given FieldHandler for 81 * delegation and the given type validator for validation. 82 * 83 * @param fieldHandler the fieldHandler for delegation. 84 * @param validator Type validator to use to validate an instance of this type. 85 */ 86 public CollectionFieldHandler(final FieldHandler fieldHandler, final TypeValidator validator) { 87 super(); 88 if (fieldHandler == null) { 89 String err = "The FieldHandler argument passed to " 90 + "the constructor of CollectionFieldHandler must not be null."; 91 throw new IllegalArgumentException(err); 92 } 93 this._handler = fieldHandler; 94 this._validator = validator; 95 } // -- CollectionFieldHandler 96 97 // ------------------/ 98 // - Public Methods -/ 99 // ------------------/ 100 101 /** 102 * Sets the value of the field associated with this descriptor. If paased a 103 * String, then String is tokenized and each token is added as an individual 104 * instance to the collection. 105 * 106 * @param target the object in which to set the value 107 * @param value the value of the field 108 * @throws IllegalStateException if any value provided fails validation. 109 */ 110 public void setValue(final Object target, final Object value) 111 throws java.lang.IllegalStateException { 112 if (value == null) { 113 return; 114 } 115 116 // If not a String, assume we are passed something the field handler understands 117 if (!(value instanceof String)) { 118 _handler.setValue(target, value); 119 return; 120 } 121 122 StringTokenizer temp = new StringTokenizer((java.lang.String) value, " "); 123 final int size = temp.countTokens(); 124 for (int i = 0; i < size; i++) { 125 String tempValue = temp.nextToken(); 126 try { 127 if (_validator != null) { 128 _validator.validate(tempValue, null); 129 } 130 } catch (ValidationException e) { 131 throw new IllegalStateException(e.getMessage()); 132 } 133 _handler.setValue(target, tempValue); 134 } 135 } // -- setValue 136 137 /** 138 * Gets the value of the field associated with this descriptor. If the value 139 * is an array, it returns a string 'representing' this array 140 * 141 * @param target the object from which to get the value 142 * @return the value of the field associated with this descriptor. 143 * @throws IllegalStateException if any value provided fails validation. 144 */ 145 public Object getValue(final Object target) throws java.lang.IllegalStateException { 146 // Needs to return the proper object 147 Object temp = _handler.getValue(target); 148 149 if (temp == null) { 150 return temp; 151 } 152 153 if (!temp.getClass().isArray()) { 154 return temp.toString(); 155 } 156 157 int size = Array.getLength(temp); 158 if (size == 0) { 159 return null; 160 } 161 162 StringBuffer result = new StringBuffer(); 163 for (int i = 0; i < size; i++) { 164 if (i > 0) { 165 result.append(' '); 166 } 167 Object obj = Array.get(temp, i); 168 result.append(obj.toString()); 169 } 170 return result.toString(); 171 } 172 173 /** 174 * Sets the value of the field to a default value. 175 * 176 * @param target The object to reset 177 * @throws IllegalStateException if the Java object has changed and is no 178 * longer supported by this handler or the handler is not 179 * compatible with the Java object 180 */ 181 public void resetValue(final Object target) throws java.lang.IllegalStateException { 182 _handler.resetValue(target); 183 } 184 185 /** 186 * Checks the field validity. Returns successfully if the field can be 187 * stored, is valid, etc, throws an exception otherwise. 188 * 189 * @param object The object 190 * @throws ValidityException The field is invalid, is required and null, or 191 * any other validity violation 192 * @throws IllegalStateException The Java object has changed and is no 193 * longer supported by this handler, or the handler is not 194 * compatiable with the Java object 195 */ 196 public void checkValidity(final Object object) throws ValidityException, IllegalStateException { 197 // -- do nothing for now 198 } // -- checkValidity 199 200 /** 201 * Creates a new instance of the object described by this field. 202 * 203 * @param parent The object for which the field is created 204 * @return A new instance of the field's value 205 * @throws IllegalStateException This field is a simple type and cannot be 206 * instantiated 207 */ 208 public Object newInstance(final Object parent) throws IllegalStateException { 209 return null; 210 } // -- newInstance 211 212 /** 213 * Returns true if the given object is an XMLFieldHandler that is equivalent 214 * to the delegated handler. An equivalent XMLFieldHandler is an 215 * XMLFieldHandler that is an instances of the same class. 216 * @param obj The object to compare to <code>this</code>. 217 * 218 * @return true if the given object is an XMLFieldHandler that is equivalent 219 * to this one. 220 */ 221 public boolean equals(final Object obj) { 222 if (obj == null || !(obj instanceof XMLFieldHandler)) { 223 return false; 224 } 225 return _handler.getClass().isInstance(obj); 226 } //-- equals 227 228 } //-- CollectionFieldHandler