View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph.property.basic;
25  
26  import java.io.InputStream;
27  import java.io.Reader;
28  import java.math.BigDecimal;
29  import java.net.URI;
30  import java.util.Calendar;
31  import java.util.Date;
32  import java.util.Iterator;
33  import java.util.UUID;
34  import net.jcip.annotations.Immutable;
35  import org.modeshape.common.text.TextDecoder;
36  import org.modeshape.common.util.CheckArg;
37  import org.modeshape.graph.property.Binary;
38  import org.modeshape.graph.property.DateTime;
39  import org.modeshape.graph.property.IoException;
40  import org.modeshape.graph.property.Name;
41  import org.modeshape.graph.property.Path;
42  import org.modeshape.graph.property.PropertyType;
43  import org.modeshape.graph.property.Reference;
44  import org.modeshape.graph.property.ValueFactory;
45  import org.modeshape.graph.property.ValueFormatException;
46  
47  /**
48   * Abstract {@link ValueFactory}.
49   * 
50   * @param <T> the property type
51   */
52  @Immutable
53  public abstract class AbstractValueFactory<T> implements ValueFactory<T> {
54  
55      private final TextDecoder decoder;
56      private final PropertyType propertyType;
57      private final ValueFactory<String> stringValueFactory;
58  
59      protected AbstractValueFactory( PropertyType type,
60                                      TextDecoder decoder,
61                                      ValueFactory<String> stringValueFactory ) {
62          CheckArg.isNotNull(type, "type");
63          this.propertyType = type;
64          this.decoder = decoder != null ? decoder : DEFAULT_DECODER;
65          this.stringValueFactory = stringValueFactory;
66      }
67  
68      /**
69       * @return stringValueFactory
70       */
71      protected ValueFactory<String> getStringValueFactory() {
72          return this.stringValueFactory;
73      }
74  
75      /**
76       * Get the text decoder.
77       * 
78       * @return the decoder
79       */
80      public TextDecoder getDecoder() {
81          return this.decoder;
82      }
83  
84      /**
85       * Utility method to obtain either the supplied decoder (if not null) or this factory's {@link #getDecoder() decoder}.
86       * 
87       * @param decoder the decoder, which may be null if this factory's {@link #getDecoder() is to be used}
88       * @return the decoder; never null
89       */
90      protected TextDecoder getDecoder( TextDecoder decoder ) {
91          return decoder != null ? decoder : this.getDecoder();
92      }
93  
94      /**
95       * {@inheritDoc}
96       */
97      public PropertyType getPropertyType() {
98          return propertyType;
99      }
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 DateTime) return create((DateTime)value);
114         if (value instanceof Calendar) return create((Calendar)value);
115         if (value instanceof Date) return create((Date)value);
116         if (value instanceof Name) return create((Name)value);
117         if (value instanceof Path) return create((Path)value);
118         if (value instanceof Reference) return create((Reference)value);
119         if (value instanceof URI) return create((URI)value);
120         if (value instanceof Binary) return create((Binary)value);
121         if (value instanceof byte[]) return create((byte[])value);
122         if (value instanceof InputStream) return create((InputStream)value, 0);
123         if (value instanceof Reader) return create((Reader)value, 0);
124         return create(value.toString());
125     }
126 
127     protected abstract T[] createEmptyArray( int length );
128 
129     /**
130      * {@inheritDoc}
131      */
132     public T[] create( BigDecimal[] values ) {
133         if (values == null) return null;
134         final int length = values.length;
135         T[] result = createEmptyArray(length);
136         for (int i = 0; i != length; ++i) {
137             result[i] = create(values[i]);
138         }
139         return result;
140     }
141 
142     /**
143      * {@inheritDoc}
144      */
145     public T[] create( boolean[] values ) {
146         if (values == null) return null;
147         final int length = values.length;
148         T[] result = createEmptyArray(length);
149         for (int i = 0; i != length; ++i) {
150             result[i] = create(values[i]);
151         }
152         return result;
153     }
154 
155     /**
156      * {@inheritDoc}
157      */
158     public T[] create( byte[][] values ) {
159         if (values == null) return null;
160         final int length = values.length;
161         T[] result = createEmptyArray(length);
162         for (int i = 0; i != length; ++i) {
163             result[i] = create(values[i]);
164         }
165         return result;
166     }
167 
168     /**
169      * {@inheritDoc}
170      */
171     public T[] create( Calendar[] values ) {
172         if (values == null) return null;
173         final int length = values.length;
174         T[] result = createEmptyArray(length);
175         for (int i = 0; i != length; ++i) {
176             result[i] = create(values[i]);
177         }
178         return result;
179     }
180 
181     /**
182      * {@inheritDoc}
183      */
184     public T[] create( Date[] values ) {
185         if (values == null) return null;
186         final int length = values.length;
187         T[] result = createEmptyArray(length);
188         for (int i = 0; i != length; ++i) {
189             result[i] = create(values[i]);
190         }
191         return result;
192     }
193 
194     /**
195      * {@inheritDoc}
196      * 
197      * @see org.modeshape.graph.property.ValueFactory#create(org.modeshape.graph.property.DateTime[])
198      */
199     public T[] create( DateTime[] values ) throws ValueFormatException {
200         if (values == null) return null;
201         final int length = values.length;
202         T[] result = createEmptyArray(length);
203         for (int i = 0; i != length; ++i) {
204             result[i] = create(values[i]);
205         }
206         return result;
207     }
208 
209     /**
210      * {@inheritDoc}
211      */
212     public T[] create( double[] values ) {
213         if (values == null) return null;
214         final int length = values.length;
215         T[] result = createEmptyArray(length);
216         for (int i = 0; i != length; ++i) {
217             result[i] = create(values[i]);
218         }
219         return result;
220     }
221 
222     /**
223      * {@inheritDoc}
224      */
225     public T[] create( float[] values ) {
226         if (values == null) return null;
227         final int length = values.length;
228         T[] result = createEmptyArray(length);
229         for (int i = 0; i != length; ++i) {
230             result[i] = create(values[i]);
231         }
232         return result;
233     }
234 
235     /**
236      * {@inheritDoc}
237      */
238     public T[] create( int[] values ) {
239         if (values == null) return null;
240         final int length = values.length;
241         T[] result = createEmptyArray(length);
242         for (int i = 0; i != length; ++i) {
243             result[i] = create(values[i]);
244         }
245         return result;
246     }
247 
248     /**
249      * {@inheritDoc}
250      */
251     public T[] create( long[] values ) {
252         if (values == null) return null;
253         final int length = values.length;
254         T[] result = createEmptyArray(length);
255         for (int i = 0; i != length; ++i) {
256             result[i] = create(values[i]);
257         }
258         return result;
259     }
260 
261     /**
262      * {@inheritDoc}
263      */
264     public T[] create( Name[] values ) {
265         if (values == null) return null;
266         final int length = values.length;
267         T[] result = createEmptyArray(length);
268         for (int i = 0; i != length; ++i) {
269             result[i] = create(values[i]);
270         }
271         return result;
272     }
273 
274     /**
275      * {@inheritDoc}
276      */
277     public T[] create( Object[] values ) {
278         if (values == null) return null;
279         final int length = values.length;
280         T[] result = createEmptyArray(length);
281         for (int i = 0; i != length; ++i) {
282             result[i] = create(values[i]);
283         }
284         return result;
285     }
286 
287     /**
288      * {@inheritDoc}
289      */
290     public T[] create( Path[] values ) {
291         if (values == null) return null;
292         final int length = values.length;
293         T[] result = createEmptyArray(length);
294         for (int i = 0; i != length; ++i) {
295             result[i] = create(values[i]);
296         }
297         return result;
298     }
299 
300     /**
301      * {@inheritDoc}
302      */
303     public T[] create( Reference[] values ) {
304         if (values == null) return null;
305         final int length = values.length;
306         T[] result = createEmptyArray(length);
307         for (int i = 0; i != length; ++i) {
308             result[i] = create(values[i]);
309         }
310         return result;
311     }
312 
313     /**
314      * {@inheritDoc}
315      */
316     public T[] create( String[] values,
317                        TextDecoder decoder ) {
318         if (values == null) return null;
319         final int length = values.length;
320         T[] result = createEmptyArray(length);
321         for (int i = 0; i != length; ++i) {
322             result[i] = create(values[i], decoder);
323         }
324         return result;
325     }
326 
327     /**
328      * {@inheritDoc}
329      */
330     public T[] create( String[] values ) {
331         if (values == null) return null;
332         final int length = values.length;
333         T[] result = createEmptyArray(length);
334         for (int i = 0; i != length; ++i) {
335             result[i] = create(values[i]);
336         }
337         return result;
338     }
339 
340     /**
341      * {@inheritDoc}
342      */
343     public T[] create( URI[] values ) {
344         if (values == null) return null;
345         final int length = values.length;
346         T[] result = createEmptyArray(length);
347         for (int i = 0; i != length; ++i) {
348             result[i] = create(values[i]);
349         }
350         return result;
351     }
352 
353     /**
354      * {@inheritDoc}
355      * 
356      * @see org.modeshape.graph.property.ValueFactory#create(java.util.UUID[])
357      */
358     public T[] create( UUID[] values ) {
359         if (values == null) return null;
360         final int length = values.length;
361         T[] result = createEmptyArray(length);
362         for (int i = 0; i != length; ++i) {
363             result[i] = create(values[i]);
364         }
365         return result;
366     }
367 
368     /**
369      * {@inheritDoc}
370      * 
371      * @see org.modeshape.graph.property.ValueFactory#create(org.modeshape.graph.property.Binary[])
372      */
373     public T[] create( Binary[] values ) throws ValueFormatException, IoException {
374         if (values == null) return null;
375         final int length = values.length;
376         T[] result = createEmptyArray(length);
377         for (int i = 0; i != length; ++i) {
378             result[i] = create(values[i]);
379         }
380         return result;
381     }
382 
383     /**
384      * {@inheritDoc}
385      * 
386      * @see org.modeshape.graph.property.ValueFactory#create(java.util.Iterator)
387      */
388     public Iterator<T> create( Iterator<?> values ) throws ValueFormatException, IoException {
389         return new ConvertingIterator<T>(values, this);
390     }
391 
392     /**
393      * {@inheritDoc}
394      * 
395      * @see org.modeshape.graph.property.ValueFactory#create(java.lang.Iterable)
396      */
397     public Iterable<T> create( final Iterable<?> valueIterable ) throws ValueFormatException, IoException {
398         return new Iterable<T>() {
399 
400             public Iterator<T> iterator() {
401                 return create(valueIterable.iterator());
402             }
403         };
404     }
405 
406     protected static class ConvertingIterator<ValueType> implements Iterator<ValueType> {
407         private final Iterator<?> delegate;
408         private final ValueFactory<ValueType> factory;
409 
410         protected ConvertingIterator( Iterator<?> delegate,
411                                       ValueFactory<ValueType> factory ) {
412             assert delegate != null;
413             assert factory != null;
414             this.delegate = delegate;
415             this.factory = factory;
416         }
417 
418         /**
419          * {@inheritDoc}
420          * 
421          * @see java.util.Iterator#hasNext()
422          */
423         public boolean hasNext() {
424             return this.delegate.hasNext();
425         }
426 
427         /**
428          * {@inheritDoc}
429          * 
430          * @see java.util.Iterator#next()
431          */
432         public ValueType next() {
433             return factory.create(this.delegate.next());
434         }
435 
436         /**
437          * {@inheritDoc}
438          * 
439          * @see java.util.Iterator#remove()
440          */
441         public void remove() {
442             this.delegate.remove();
443         }
444     }
445 
446 }