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 }