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