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 }