/* * ModeShape (http://www.modeshape.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.modeshape.jcr.value.basic; import java.io.InputStream; import java.math.BigDecimal; import java.net.URI; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.UUID; import javax.jcr.RepositoryException; import org.modeshape.common.annotation.Immutable; import org.modeshape.common.text.TextDecoder; import org.modeshape.common.util.CheckArg; import org.modeshape.jcr.api.value.DateTime; import org.modeshape.jcr.cache.NodeKey; import org.modeshape.jcr.value.BinaryValue; import org.modeshape.jcr.value.IoException; import org.modeshape.jcr.value.Name; import org.modeshape.jcr.value.Path; import org.modeshape.jcr.value.PropertyType; import org.modeshape.jcr.value.Reference; import org.modeshape.jcr.value.ValueFactories; import org.modeshape.jcr.value.ValueFactory; import org.modeshape.jcr.value.ValueFormatException; /** * Abstract {@link ValueFactory}. * * @param <T> the property type */ @Immutable public abstract class AbstractValueFactory<T> implements ValueFactory<T> { protected final TextDecoder decoder; protected final PropertyType propertyType; protected final ValueFactories valueFactories; protected AbstractValueFactory( PropertyType type, TextDecoder decoder, ValueFactories valueFactories ) { CheckArg.isNotNull(type, "type"); this.propertyType = type; this.decoder = decoder != null ? decoder : DEFAULT_DECODER; this.valueFactories = valueFactories; } /** * @return stringValueFactory */ protected ValueFactory<String> getStringValueFactory() { return valueFactories.getStringFactory(); } /** * Get the text decoder. * * @return the decoder */ public TextDecoder getDecoder() { return this.decoder; } /** * Utility method to obtain either the supplied decoder (if not null) or this factory's {@link #getDecoder() decoder}. * * @param decoder the decoder, which may be null if this factory's {@link #getDecoder() is to be used} * @return the decoder; never null */ protected TextDecoder getDecoder( TextDecoder decoder ) { return decoder != null ? decoder : this.getDecoder(); } @Override public PropertyType getPropertyType() { return propertyType; } @Override public T create( Object value ) { if (value == null) return null; if (value instanceof String) return create((String)value); if (value instanceof Integer) return create(((Integer)value).intValue()); if (value instanceof Long) return create(((Long)value).longValue()); if (value instanceof Double) return create(((Double)value).doubleValue()); if (value instanceof Float) return create(((Float)value).floatValue()); if (value instanceof Boolean) return create(((Boolean)value).booleanValue()); if (value instanceof BigDecimal) return create((BigDecimal)value); if (value instanceof DateTime) return create((DateTime)value); if (value instanceof Calendar) return create((Calendar)value); if (value instanceof Date) return create((Date)value); if (value instanceof Name) return create((Name)value); if (value instanceof Path) return create((Path)value); if (value instanceof Path.Segment) return create((Path.Segment)value); if (value instanceof Reference) return create((Reference)value); if (value instanceof NodeKey) return create((NodeKey)value); if (value instanceof UUID) return create((UUID)value); if (value instanceof URI) return create((URI)value); if (value instanceof BinaryValue) return create((BinaryValue)value); if (value instanceof javax.jcr.Binary) { javax.jcr.Binary jcrBinary = (javax.jcr.Binary)value; try { return create(jcrBinary.getStream()); } catch (RepositoryException e) { throw new RuntimeException(e); } } if (value instanceof byte[]) return create((byte[])value); if (value instanceof InputStream) return create((InputStream)value); return create(value.toString()); } @Override public T[] create( BigDecimal[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( boolean[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( byte[][] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( Calendar[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( Date[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( DateTime[] values ) throws ValueFormatException { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( double[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( float[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( int[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( long[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( Name[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( Object[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( Path[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( Reference[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( String[] values, TextDecoder decoder ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i], decoder); } return result; } @Override public T[] create( String[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( URI[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( UUID[] values ) { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( NodeKey[] values ) throws ValueFormatException { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public T[] create( BinaryValue[] values ) throws ValueFormatException, IoException { if (values == null) return null; final int length = values.length; T[] result = createEmptyArray(length); for (int i = 0; i != length; ++i) { result[i] = create(values[i]); } return result; } @Override public Iterator<T> create( Iterator<?> values ) throws ValueFormatException, IoException { return new ConvertingIterator<T>(values, this); } @Override public Iterable<T> create( final Iterable<?> valueIterable ) throws ValueFormatException, IoException { return new Iterable<T>() { @Override public Iterator<T> iterator() { return create(valueIterable.iterator()); } }; } @Override public T create( InputStream stream, String hint ) throws ValueFormatException, IoException { return create(stream); } protected static class ConvertingIterator<ValueType> implements Iterator<ValueType> { private final Iterator<?> delegate; private final ValueFactory<ValueType> factory; protected ConvertingIterator( Iterator<?> delegate, ValueFactory<ValueType> factory ) { assert delegate != null; assert factory != null; this.delegate = delegate; this.factory = factory; } @Override public boolean hasNext() { return this.delegate.hasNext(); } @Override public ValueType next() { return factory.create(this.delegate.next()); } @Override public void remove() { this.delegate.remove(); } } }