001 /* 002 * JBoss DNA (http://www.jboss.org/dna) 003 * See the COPYRIGHT.txt file distributed with this work for information 004 * regarding copyright ownership. Some portions may be licensed 005 * to Red Hat, Inc. under one or more contributor license agreements. 006 * See the AUTHORS.txt file in the distribution for a full listing of 007 * individual contributors. 008 * 009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA 010 * is licensed to you under the terms of the GNU Lesser General Public License as 011 * published by the Free Software Foundation; either version 2.1 of 012 * the License, or (at your option) any later version. 013 * 014 * JBoss DNA is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 017 * Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this software; if not, write to the Free 021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 023 */ 024 package org.jboss.dna.graph.property.basic; 025 026 import java.io.InputStream; 027 import java.io.Reader; 028 import java.math.BigDecimal; 029 import java.net.URI; 030 import java.util.Calendar; 031 import java.util.Date; 032 import java.util.Iterator; 033 import java.util.UUID; 034 import net.jcip.annotations.Immutable; 035 import org.jboss.dna.common.text.TextDecoder; 036 import org.jboss.dna.common.util.CheckArg; 037 import org.jboss.dna.graph.property.Binary; 038 import org.jboss.dna.graph.property.DateTime; 039 import org.jboss.dna.graph.property.IoException; 040 import org.jboss.dna.graph.property.Name; 041 import org.jboss.dna.graph.property.Path; 042 import org.jboss.dna.graph.property.PropertyType; 043 import org.jboss.dna.graph.property.Reference; 044 import org.jboss.dna.graph.property.ValueFactory; 045 import org.jboss.dna.graph.property.ValueFormatException; 046 047 /** 048 * Abstract {@link ValueFactory}. 049 * 050 * @author Randall Hauch 051 * @author John Verhaeg 052 * @param <T> the property type 053 */ 054 @Immutable 055 public abstract class AbstractValueFactory<T> implements ValueFactory<T> { 056 057 private final TextDecoder decoder; 058 private final PropertyType propertyType; 059 private final ValueFactory<String> stringValueFactory; 060 061 protected AbstractValueFactory( PropertyType type, 062 TextDecoder decoder, 063 ValueFactory<String> stringValueFactory ) { 064 CheckArg.isNotNull(type, "type"); 065 this.propertyType = type; 066 this.decoder = decoder != null ? decoder : DEFAULT_DECODER; 067 this.stringValueFactory = stringValueFactory; 068 } 069 070 /** 071 * @return stringValueFactory 072 */ 073 protected ValueFactory<String> getStringValueFactory() { 074 return this.stringValueFactory; 075 } 076 077 /** 078 * Get the text decoder. 079 * 080 * @return the decoder 081 */ 082 public TextDecoder getDecoder() { 083 return this.decoder; 084 } 085 086 /** 087 * Utility method to obtain either the supplied decoder (if not null) or this factory's {@link #getDecoder() decoder}. 088 * 089 * @param decoder the decoder, which may be null if this factory's {@link #getDecoder() is to be used} 090 * @return the decoder; never null 091 */ 092 protected TextDecoder getDecoder( TextDecoder decoder ) { 093 return decoder != null ? decoder : this.getDecoder(); 094 } 095 096 /** 097 * {@inheritDoc} 098 */ 099 public PropertyType getPropertyType() { 100 return propertyType; 101 } 102 103 /** 104 * {@inheritDoc} 105 */ 106 public T create( Object value ) { 107 if (value == null) return null; 108 if (value instanceof String) return create((String)value); 109 if (value instanceof Integer) return create(((Integer)value).intValue()); 110 if (value instanceof Long) return create(((Long)value).longValue()); 111 if (value instanceof Double) return create(((Double)value).doubleValue()); 112 if (value instanceof Float) return create(((Float)value).floatValue()); 113 if (value instanceof Boolean) return create(((Boolean)value).booleanValue()); 114 if (value instanceof BigDecimal) return create((BigDecimal)value); 115 if (value instanceof DateTime) return create((DateTime)value); 116 if (value instanceof Calendar) return create((Calendar)value); 117 if (value instanceof Date) return create((Date)value); 118 if (value instanceof Name) return create((Name)value); 119 if (value instanceof Path) return create((Path)value); 120 if (value instanceof Reference) return create((Reference)value); 121 if (value instanceof URI) return create((URI)value); 122 if (value instanceof Binary) return create((Binary)value); 123 if (value instanceof byte[]) return create((byte[])value); 124 if (value instanceof InputStream) return create((InputStream)value, 0); 125 if (value instanceof Reader) return create((Reader)value, 0); 126 return create(value.toString()); 127 } 128 129 protected abstract T[] createEmptyArray( int length ); 130 131 /** 132 * {@inheritDoc} 133 */ 134 public T[] create( BigDecimal[] values ) { 135 if (values == null) return null; 136 final int length = values.length; 137 T[] result = createEmptyArray(length); 138 for (int i = 0; i != length; ++i) { 139 result[i] = create(values[i]); 140 } 141 return result; 142 } 143 144 /** 145 * {@inheritDoc} 146 */ 147 public T[] create( boolean[] values ) { 148 if (values == null) return null; 149 final int length = values.length; 150 T[] result = createEmptyArray(length); 151 for (int i = 0; i != length; ++i) { 152 result[i] = create(values[i]); 153 } 154 return result; 155 } 156 157 /** 158 * {@inheritDoc} 159 */ 160 public T[] create( byte[][] values ) { 161 if (values == null) return null; 162 final int length = values.length; 163 T[] result = createEmptyArray(length); 164 for (int i = 0; i != length; ++i) { 165 result[i] = create(values[i]); 166 } 167 return result; 168 } 169 170 /** 171 * {@inheritDoc} 172 */ 173 public T[] create( Calendar[] values ) { 174 if (values == null) return null; 175 final int length = values.length; 176 T[] result = createEmptyArray(length); 177 for (int i = 0; i != length; ++i) { 178 result[i] = create(values[i]); 179 } 180 return result; 181 } 182 183 /** 184 * {@inheritDoc} 185 */ 186 public T[] create( Date[] values ) { 187 if (values == null) return null; 188 final int length = values.length; 189 T[] result = createEmptyArray(length); 190 for (int i = 0; i != length; ++i) { 191 result[i] = create(values[i]); 192 } 193 return result; 194 } 195 196 /** 197 * {@inheritDoc} 198 * 199 * @see org.jboss.dna.graph.property.ValueFactory#create(org.jboss.dna.graph.property.DateTime[]) 200 */ 201 public T[] create( DateTime[] values ) throws ValueFormatException { 202 if (values == null) return null; 203 final int length = values.length; 204 T[] result = createEmptyArray(length); 205 for (int i = 0; i != length; ++i) { 206 result[i] = create(values[i]); 207 } 208 return result; 209 } 210 211 /** 212 * {@inheritDoc} 213 */ 214 public T[] create( double[] values ) { 215 if (values == null) return null; 216 final int length = values.length; 217 T[] result = createEmptyArray(length); 218 for (int i = 0; i != length; ++i) { 219 result[i] = create(values[i]); 220 } 221 return result; 222 } 223 224 /** 225 * {@inheritDoc} 226 */ 227 public T[] create( float[] values ) { 228 if (values == null) return null; 229 final int length = values.length; 230 T[] result = createEmptyArray(length); 231 for (int i = 0; i != length; ++i) { 232 result[i] = create(values[i]); 233 } 234 return result; 235 } 236 237 /** 238 * {@inheritDoc} 239 */ 240 public T[] create( int[] values ) { 241 if (values == null) return null; 242 final int length = values.length; 243 T[] result = createEmptyArray(length); 244 for (int i = 0; i != length; ++i) { 245 result[i] = create(values[i]); 246 } 247 return result; 248 } 249 250 /** 251 * {@inheritDoc} 252 */ 253 public T[] create( long[] values ) { 254 if (values == null) return null; 255 final int length = values.length; 256 T[] result = createEmptyArray(length); 257 for (int i = 0; i != length; ++i) { 258 result[i] = create(values[i]); 259 } 260 return result; 261 } 262 263 /** 264 * {@inheritDoc} 265 */ 266 public T[] create( Name[] values ) { 267 if (values == null) return null; 268 final int length = values.length; 269 T[] result = createEmptyArray(length); 270 for (int i = 0; i != length; ++i) { 271 result[i] = create(values[i]); 272 } 273 return result; 274 } 275 276 /** 277 * {@inheritDoc} 278 */ 279 public T[] create( Object[] values ) { 280 if (values == null) return null; 281 final int length = values.length; 282 T[] result = createEmptyArray(length); 283 for (int i = 0; i != length; ++i) { 284 result[i] = create(values[i]); 285 } 286 return result; 287 } 288 289 /** 290 * {@inheritDoc} 291 */ 292 public T[] create( Path[] values ) { 293 if (values == null) return null; 294 final int length = values.length; 295 T[] result = createEmptyArray(length); 296 for (int i = 0; i != length; ++i) { 297 result[i] = create(values[i]); 298 } 299 return result; 300 } 301 302 /** 303 * {@inheritDoc} 304 */ 305 public T[] create( Reference[] values ) { 306 if (values == null) return null; 307 final int length = values.length; 308 T[] result = createEmptyArray(length); 309 for (int i = 0; i != length; ++i) { 310 result[i] = create(values[i]); 311 } 312 return result; 313 } 314 315 /** 316 * {@inheritDoc} 317 */ 318 public T[] create( String[] values, 319 TextDecoder decoder ) { 320 if (values == null) return null; 321 final int length = values.length; 322 T[] result = createEmptyArray(length); 323 for (int i = 0; i != length; ++i) { 324 result[i] = create(values[i], decoder); 325 } 326 return result; 327 } 328 329 /** 330 * {@inheritDoc} 331 */ 332 public T[] create( String[] values ) { 333 if (values == null) return null; 334 final int length = values.length; 335 T[] result = createEmptyArray(length); 336 for (int i = 0; i != length; ++i) { 337 result[i] = create(values[i]); 338 } 339 return result; 340 } 341 342 /** 343 * {@inheritDoc} 344 */ 345 public T[] create( URI[] values ) { 346 if (values == null) return null; 347 final int length = values.length; 348 T[] result = createEmptyArray(length); 349 for (int i = 0; i != length; ++i) { 350 result[i] = create(values[i]); 351 } 352 return result; 353 } 354 355 /** 356 * {@inheritDoc} 357 * 358 * @see org.jboss.dna.graph.property.ValueFactory#create(java.util.UUID[]) 359 */ 360 public T[] create( UUID[] values ) { 361 if (values == null) return null; 362 final int length = values.length; 363 T[] result = createEmptyArray(length); 364 for (int i = 0; i != length; ++i) { 365 result[i] = create(values[i]); 366 } 367 return result; 368 } 369 370 /** 371 * {@inheritDoc} 372 * 373 * @see org.jboss.dna.graph.property.ValueFactory#create(org.jboss.dna.graph.property.Binary[]) 374 */ 375 public T[] create( Binary[] values ) throws ValueFormatException, IoException { 376 if (values == null) return null; 377 final int length = values.length; 378 T[] result = createEmptyArray(length); 379 for (int i = 0; i != length; ++i) { 380 result[i] = create(values[i]); 381 } 382 return result; 383 } 384 385 /** 386 * {@inheritDoc} 387 * 388 * @see org.jboss.dna.graph.property.ValueFactory#create(java.util.Iterator) 389 */ 390 public Iterator<T> create( Iterator<?> values ) throws ValueFormatException, IoException { 391 return new ConvertingIterator<T>(values, this); 392 } 393 394 /** 395 * {@inheritDoc} 396 * 397 * @see org.jboss.dna.graph.property.ValueFactory#create(java.lang.Iterable) 398 */ 399 public Iterable<T> create( final Iterable<?> valueIterable ) throws ValueFormatException, IoException { 400 return new Iterable<T>() { 401 402 public Iterator<T> iterator() { 403 return create(valueIterable.iterator()); 404 } 405 }; 406 } 407 408 protected static class ConvertingIterator<ValueType> implements Iterator<ValueType> { 409 private final Iterator<?> delegate; 410 private final ValueFactory<ValueType> factory; 411 412 protected ConvertingIterator( Iterator<?> delegate, 413 ValueFactory<ValueType> factory ) { 414 assert delegate != null; 415 assert factory != null; 416 this.delegate = delegate; 417 this.factory = factory; 418 } 419 420 /** 421 * {@inheritDoc} 422 * 423 * @see java.util.Iterator#hasNext() 424 */ 425 public boolean hasNext() { 426 return this.delegate.hasNext(); 427 } 428 429 /** 430 * {@inheritDoc} 431 * 432 * @see java.util.Iterator#next() 433 */ 434 public ValueType next() { 435 return factory.create(this.delegate.next()); 436 } 437 438 /** 439 * {@inheritDoc} 440 * 441 * @see java.util.Iterator#remove() 442 */ 443 public void remove() { 444 this.delegate.remove(); 445 } 446 } 447 448 }