/* * 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.UUID; import org.modeshape.common.annotation.Immutable; import org.modeshape.common.text.TextDecoder; import org.modeshape.jcr.GraphI18n; 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; /** * The standard {@link ValueFactory} for {@link PropertyType#DECIMAL} values. */ @Immutable public class DecimalValueFactory extends AbstractValueFactory<BigDecimal> { /** * Create a new instance. * * @param decoder the text decoder; may be null if the default decoder should be used * @param factories the set of value factories, used to obtain the {@link ValueFactories#getStringFactory() string value * factory}; may not be null */ public DecimalValueFactory( TextDecoder decoder, ValueFactories factories ) { super(PropertyType.DECIMAL, decoder, factories); } @Override public ValueFactory<BigDecimal> with( ValueFactories valueFactories ) { return super.valueFactories == valueFactories ? this : new DecimalValueFactory(super.getDecoder(), valueFactories); } @Override public BigDecimal create( String value ) { if (value == null) return null; try { return new BigDecimal(value.trim()); } catch (NumberFormatException err) { throw new ValueFormatException(value, getPropertyType(), GraphI18n.errorConvertingType.text(String.class.getSimpleName(), BigDecimal.class.getSimpleName(), value), err); } } @Override public BigDecimal create( String value, TextDecoder decoder ) { // this probably doesn't really need to call the decoder, but by doing so then we don't care at all what the decoder does return create(getDecoder(decoder).decode(value.trim())); } @Override public BigDecimal create( int value ) { return BigDecimal.valueOf(value); } @Override public BigDecimal create( long value ) { return BigDecimal.valueOf(value); } @Override public BigDecimal create( boolean value ) { throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(), Boolean.class.getSimpleName(), value)); } @Override public BigDecimal create( float value ) { return BigDecimal.valueOf(value); } @Override public BigDecimal create( double value ) { return BigDecimal.valueOf(value); } @Override public BigDecimal create( BigDecimal value ) { return value; } @Override public BigDecimal create( Calendar value ) { if (value == null) return null; return create(value.getTimeInMillis()); } @Override public BigDecimal create( Date value ) { if (value == null) return null; return create(value.getTime()); } @Override public BigDecimal create( DateTime value ) throws ValueFormatException { if (value == null) return null; return create(value.getMilliseconds()); } @Override public BigDecimal create( Name value ) { throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(), Name.class.getSimpleName(), value)); } @Override public BigDecimal create( Path value ) { throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(), Path.class.getSimpleName(), value)); } @Override public BigDecimal create( Path.Segment value ) { throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(), Path.Segment.class.getSimpleName(), value)); } @Override public BigDecimal create( Reference value ) { throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(), Reference.class.getSimpleName(), value)); } @Override public BigDecimal create( URI value ) { throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(), URI.class.getSimpleName(), value)); } @Override public BigDecimal create( UUID value ) throws IoException { throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(), UUID.class.getSimpleName(), value)); } @Override public BigDecimal create( NodeKey value ) throws ValueFormatException { throw new ValueFormatException(value, getPropertyType(), GraphI18n.unableToCreateValue.text(getPropertyType().getName(), NodeKey.class.getSimpleName(), value)); } @Override public BigDecimal create( byte[] value ) { // First attempt to create a string from the value, then a long from the string ... return create(getStringValueFactory().create(value)); } @Override public BigDecimal create( BinaryValue value ) throws ValueFormatException, IoException { // First create a string and then create the boolean from the string value ... return create(getStringValueFactory().create(value)); } @Override public BigDecimal create( InputStream stream ) throws IoException { // First attempt to create a string from the value, then a double from the string ... return create(getStringValueFactory().create(stream)); } @Override public BigDecimal[] createEmptyArray( int length ) { return new BigDecimal[length]; } }