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 Path.Segment) return create((Path.Segment)value);
119         if (value instanceof Reference) return create((Reference)value);
120         if (value instanceof URI) return create((URI)value);
121         if (value instanceof Binary) return create((Binary)value);
122         if (value instanceof byte[]) return create((byte[])value);
123         if (value instanceof InputStream) return create((InputStream)value, 0);
124         if (value instanceof Reader) return create((Reader)value, 0);
125         return create(value.toString());
126     }
127 
128     protected abstract T[] createEmptyArray( int length );
129 
130     /**
131      * {@inheritDoc}
132      */
133     public T[] create( BigDecimal[] values ) {
134         if (values == null) return null;
135         final int length = values.length;
136         T[] result = createEmptyArray(length);
137         for (int i = 0; i != length; ++i) {
138             result[i] = create(values[i]);
139         }
140         return result;
141     }
142 
143     /**
144      * {@inheritDoc}
145      */
146     public T[] create( boolean[] values ) {
147         if (values == null) return null;
148         final int length = values.length;
149         T[] result = createEmptyArray(length);
150         for (int i = 0; i != length; ++i) {
151             result[i] = create(values[i]);
152         }
153         return result;
154     }
155 
156     /**
157      * {@inheritDoc}
158      */
159     public T[] create( byte[][] values ) {
160         if (values == null) return null;
161         final int length = values.length;
162         T[] result = createEmptyArray(length);
163         for (int i = 0; i != length; ++i) {
164             result[i] = create(values[i]);
165         }
166         return result;
167     }
168 
169     /**
170      * {@inheritDoc}
171      */
172     public T[] create( Calendar[] values ) {
173         if (values == null) return null;
174         final int length = values.length;
175         T[] result = createEmptyArray(length);
176         for (int i = 0; i != length; ++i) {
177             result[i] = create(values[i]);
178         }
179         return result;
180     }
181 
182     /**
183      * {@inheritDoc}
184      */
185     public T[] create( Date[] values ) {
186         if (values == null) return null;
187         final int length = values.length;
188         T[] result = createEmptyArray(length);
189         for (int i = 0; i != length; ++i) {
190             result[i] = create(values[i]);
191         }
192         return result;
193     }
194 
195     /**
196      * {@inheritDoc}
197      * 
198      * @see org.modeshape.graph.property.ValueFactory#create(org.modeshape.graph.property.DateTime[])
199      */
200     public T[] create( DateTime[] values ) throws ValueFormatException {
201         if (values == null) return null;
202         final int length = values.length;
203         T[] result = createEmptyArray(length);
204         for (int i = 0; i != length; ++i) {
205             result[i] = create(values[i]);
206         }
207         return result;
208     }
209 
210     /**
211      * {@inheritDoc}
212      */
213     public T[] create( double[] values ) {
214         if (values == null) return null;
215         final int length = values.length;
216         T[] result = createEmptyArray(length);
217         for (int i = 0; i != length; ++i) {
218             result[i] = create(values[i]);
219         }
220         return result;
221     }
222 
223     /**
224      * {@inheritDoc}
225      */
226     public T[] create( float[] values ) {
227         if (values == null) return null;
228         final int length = values.length;
229         T[] result = createEmptyArray(length);
230         for (int i = 0; i != length; ++i) {
231             result[i] = create(values[i]);
232         }
233         return result;
234     }
235 
236     /**
237      * {@inheritDoc}
238      */
239     public T[] create( int[] values ) {
240         if (values == null) return null;
241         final int length = values.length;
242         T[] result = createEmptyArray(length);
243         for (int i = 0; i != length; ++i) {
244             result[i] = create(values[i]);
245         }
246         return result;
247     }
248 
249     /**
250      * {@inheritDoc}
251      */
252     public T[] create( long[] values ) {
253         if (values == null) return null;
254         final int length = values.length;
255         T[] result = createEmptyArray(length);
256         for (int i = 0; i != length; ++i) {
257             result[i] = create(values[i]);
258         }
259         return result;
260     }
261 
262     /**
263      * {@inheritDoc}
264      */
265     public T[] create( Name[] values ) {
266         if (values == null) return null;
267         final int length = values.length;
268         T[] result = createEmptyArray(length);
269         for (int i = 0; i != length; ++i) {
270             result[i] = create(values[i]);
271         }
272         return result;
273     }
274 
275     /**
276      * {@inheritDoc}
277      */
278     public T[] create( Object[] values ) {
279         if (values == null) return null;
280         final int length = values.length;
281         T[] result = createEmptyArray(length);
282         for (int i = 0; i != length; ++i) {
283             result[i] = create(values[i]);
284         }
285         return result;
286     }
287 
288     /**
289      * {@inheritDoc}
290      */
291     public T[] create( Path[] values ) {
292         if (values == null) return null;
293         final int length = values.length;
294         T[] result = createEmptyArray(length);
295         for (int i = 0; i != length; ++i) {
296             result[i] = create(values[i]);
297         }
298         return result;
299     }
300 
301     /**
302      * {@inheritDoc}
303      */
304     public T[] create( Reference[] values ) {
305         if (values == null) return null;
306         final int length = values.length;
307         T[] result = createEmptyArray(length);
308         for (int i = 0; i != length; ++i) {
309             result[i] = create(values[i]);
310         }
311         return result;
312     }
313 
314     /**
315      * {@inheritDoc}
316      */
317     public T[] create( String[] values,
318                        TextDecoder decoder ) {
319         if (values == null) return null;
320         final int length = values.length;
321         T[] result = createEmptyArray(length);
322         for (int i = 0; i != length; ++i) {
323             result[i] = create(values[i], decoder);
324         }
325         return result;
326     }
327 
328     /**
329      * {@inheritDoc}
330      */
331     public T[] create( String[] values ) {
332         if (values == null) return null;
333         final int length = values.length;
334         T[] result = createEmptyArray(length);
335         for (int i = 0; i != length; ++i) {
336             result[i] = create(values[i]);
337         }
338         return result;
339     }
340 
341     /**
342      * {@inheritDoc}
343      */
344     public T[] create( URI[] values ) {
345         if (values == null) return null;
346         final int length = values.length;
347         T[] result = createEmptyArray(length);
348         for (int i = 0; i != length; ++i) {
349             result[i] = create(values[i]);
350         }
351         return result;
352     }
353 
354     /**
355      * {@inheritDoc}
356      * 
357      * @see org.modeshape.graph.property.ValueFactory#create(java.util.UUID[])
358      */
359     public T[] create( UUID[] values ) {
360         if (values == null) return null;
361         final int length = values.length;
362         T[] result = createEmptyArray(length);
363         for (int i = 0; i != length; ++i) {
364             result[i] = create(values[i]);
365         }
366         return result;
367     }
368 
369     /**
370      * {@inheritDoc}
371      * 
372      * @see org.modeshape.graph.property.ValueFactory#create(org.modeshape.graph.property.Binary[])
373      */
374     public T[] create( Binary[] values ) throws ValueFormatException, IoException {
375         if (values == null) return null;
376         final int length = values.length;
377         T[] result = createEmptyArray(length);
378         for (int i = 0; i != length; ++i) {
379             result[i] = create(values[i]);
380         }
381         return result;
382     }
383 
384     /**
385      * {@inheritDoc}
386      * 
387      * @see org.modeshape.graph.property.ValueFactory#create(java.util.Iterator)
388      */
389     public Iterator<T> create( Iterator<?> values ) throws ValueFormatException, IoException {
390         return new ConvertingIterator<T>(values, this);
391     }
392 
393     /**
394      * {@inheritDoc}
395      * 
396      * @see org.modeshape.graph.property.ValueFactory#create(java.lang.Iterable)
397      */
398     public Iterable<T> create( final Iterable<?> valueIterable ) throws ValueFormatException, IoException {
399         return new Iterable<T>() {
400 
401             public Iterator<T> iterator() {
402                 return create(valueIterable.iterator());
403             }
404         };
405     }
406 
407     protected static class ConvertingIterator<ValueType> implements Iterator<ValueType> {
408         private final Iterator<?> delegate;
409         private final ValueFactory<ValueType> factory;
410 
411         protected ConvertingIterator( Iterator<?> delegate,
412                                       ValueFactory<ValueType> factory ) {
413             assert delegate != null;
414             assert factory != null;
415             this.delegate = delegate;
416             this.factory = factory;
417         }
418 
419         /**
420          * {@inheritDoc}
421          * 
422          * @see java.util.Iterator#hasNext()
423          */
424         public boolean hasNext() {
425             return this.delegate.hasNext();
426         }
427 
428         /**
429          * {@inheritDoc}
430          * 
431          * @see java.util.Iterator#next()
432          */
433         public ValueType next() {
434             return factory.create(this.delegate.next());
435         }
436 
437         /**
438          * {@inheritDoc}
439          * 
440          * @see java.util.Iterator#remove()
441          */
442         public void remove() {
443             this.delegate.remove();
444         }
445     }
446 
447 }