Author: desruisseaux
Date: Tue Mar 12 12:54:31 2013
New Revision: 1455514
URL: http://svn.apache.org/r1455514
Log:
Reduces the size of NumberConverter, since this is not Apache SIS job to
provide a framework for converters
(there is other Apache projects for that). Begin the port of ServiceRegistry,
to be completed later.
Added:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java
(with props)
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
(with props)
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java
(with props)
Modified:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
Modified:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java?rev=1455514&r1=1455513&r2=1455514&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java
[UTF-8] Tue Mar 12 12:54:31 2013
@@ -16,6 +16,7 @@
*/
package org.apache.sis.internal.converter;
+import java.io.Serializable;
import net.jcip.annotations.Immutable;
import org.apache.sis.util.ObjectConverter;
@@ -35,7 +36,12 @@ import org.apache.sis.util.ObjectConvert
* @module
*/
@Immutable
-class ClassPair<S,T> {
+class ClassPair<S,T> implements Serializable {
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = -9157788501686115L;
+
/**
* The source class.
*/
Added:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java?rev=1455514&view=auto
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java
(added)
+++
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java
[UTF-8] Tue Mar 12 12:54:31 2013
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sis.internal.converter;
+
+import java.util.Map;
+import java.util.LinkedHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import net.jcip.annotations.ThreadSafe;
+import org.apache.sis.internal.util.SystemListener;
+import org.apache.sis.util.ObjectConverter;
+
+
+/**
+ * A collection of {@link ObjectConverter} instances.
+ * A converter from the given <var>source type</var> to the given <var>target
type</var> can be
+ * obtained by a call to {@link #converter(Class, Class)}. If no converter
exists for the given
+ * source and target types, then this registry searches for a suitable
converter accepting a
+ * parent class of the given source type, or returning a sub-class of the
given target type.
+ *
+ * <p>New instances of {@code ConverterRegistry} are initially empty. Custom
converters must be
+ * explicitly {@linkplain #register registered}. However a system-wide
registry initialized
+ * with default converters is provided by the {@link #SYSTEM} constant.</p>
+ *
+ * {@section Note about conversions from interfaces}
+ * {@code ConverterRegistry} is primarily designed for handling converters
from classes to
+ * other classes. Handling of interfaces are not prohibited (and actually
sometime supported),
+ * but their behavior may be more ambiguous than in the case of classes
because of
+ * multi-inheritance in interface hierarchy.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3 (derived from geotk-3.20)
+ * @version 0.3
+ * @module
+ */
+@ThreadSafe
+public class ConverterRegistry {
+ /**
+ * The default system-wide instance. This register is initialized with
conversions between
+ * some basic Java and SIS objects, like conversions between {@link
java.util.Date} and
+ * {@link java.lang.Long}. Those conversions are defined for the lifetime
of the JVM.
+ *
+ * <p>If a temporary set of converters is desired, a new instance of
{@code ConverterRegistry}
+ * should be created explicitly instead.</p>
+ *
+ * {@section Adding system-wide converters}
+ * Applications can add system-wide custom providers either by explicit
call to the
+ * {@link #register(ObjectConverter)} method on the system converter, or
by listing
+ * the fully qualified classnames of their {@link ObjectConverter}
instances in the
+ * following file (see {@link ServiceLoader} for more info about services
loading):
+ *
+ * {@preformat text
+ * META-INF/services/org.apache.sis.util.converter.ObjectConverter
+ * }
+ */
+ public static final ConverterRegistry SYSTEM = new ConverterRegistry();
+ static {
+ SystemListener.add(new SystemListener() {
+ @Override protected void classpathChanged() {
+ SYSTEM.clear();
+ }
+ });
+ }
+
+ /**
+ * The map of converters of any kind. We use a single read/write lock for
the whole map
+ * because write operations will be rare (so {@code ConcurrentHashMap} may
be an overkill).
+ */
+ private final Map<ClassPair<?,?>, SystemConverter<?,?>> converters;
+
+ /**
+ * The locks for the {@link #converters} map.
+ */
+ private final ReadWriteLock locks;
+
+ /**
+ * Creates an initially empty set of object converters.
+ */
+ public ConverterRegistry() {
+ converters = new LinkedHashMap<>();
+ locks = new ReentrantReadWriteLock();
+ }
+
+ /**
+ * Removes all converters from this registry.
+ */
+ public void clear() {
+ final Lock lock = locks.writeLock();
+ lock.lock();
+ try {
+ converters.clear();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns an unique instance of the given converter. If a converter
already exists for the
+ * same source an target classes, then that converter is returned.
Otherwise that converter
+ * is cached if {@code cache} is {@code true} and returned.
+ *
+ * @param converter The converter to look for a unique instance.
+ * @param cache Whether to cache the given converter if there is no
existing instance.
+ * @return A previously existing instance if one exists, or the given
converter otherwise.
+ */
+ @SuppressWarnings("unchecked")
+ final <S,T> ObjectConverter<S,T> unique(final SystemConverter<S,T>
converter, final boolean cache) {
+ SystemConverter<S,T> existing;
+ Lock lock = locks.readLock();
+ lock.lock();
+ try {
+ existing = (SystemConverter<S,T>) converters.get(converter);
+ } finally {
+ lock.unlock();
+ }
+ /*
+ * If no instance existed before for the source and target classes,
stores this
+ * instance in the pool. However we will need to check again during
the write
+ * operation in case an other thread had the time to add an instance
in the pool.
+ */
+ if (existing == null) {
+ if (!cache) {
+ return converter;
+ }
+ lock = locks.writeLock();
+ lock.lock();
+ try {
+ existing = (SystemConverter<S,T>) converters.put(converter,
converter);
+ if (existing != null) {
+ converters.put(existing, existing);
+ } else {
+ existing = converter;
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+ return existing;
+ }
+}
Propchange:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java?rev=1455514&r1=1455513&r2=1455514&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java
[UTF-8] Tue Mar 12 12:54:31 2013
@@ -16,20 +16,31 @@
*/
package org.apache.sis.internal.converter;
-import java.io.Serializable;
-import java.io.ObjectStreamException;
+import java.util.Set;
+import java.util.EnumSet;
import net.jcip.annotations.Immutable;
import org.apache.sis.util.Numbers;
import org.apache.sis.util.ObjectConverter;
-import org.apache.sis.util.resources.Errors;
+import org.apache.sis.math.FunctionProperty;
/**
- * Handles conversions from {@link java.lang.Number} to various objects.
+ * Handles conversions from {@link java.lang.Number} to other numbers.
+ * This class supports only the type supported by {@link Numbers}.
*
- * @param <S> The source type. All shared instances will declare {@link
Number},
- * but some more specific types will occasionally need to be
declared
- * for inverse converters.
+ * {@section Performance note}
+ * We provide a single class for all supported kinds of {@code Number} and
delegate the actual
+ * work to the {@code Numbers} static methods. This is not a very efficient
way to do the work.
+ * For example it may be more efficient to provide specialized subclasses for
each target class,
+ * so we don't have to execute the {@code switch} inside the {@code Numbers}
class every time a
+ * value is converted. However performance is not the primary concern here,
since those converters
+ * will typically be used by code doing more costly work (e.g. the {@code
sis-metadata} module
+ * providing {@code Map} views using Java reflection). So we rather try to be
more compact.
+ * If nevertheless performance appear to be a problem, consider reverting to
revision 1455255,
+ * which was using one subclass per target type as described above.
+ *
+ * @param <S> The source number type.
+ * @param <T> The target number type.
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3 (derived from geotk-2.4)
@@ -37,470 +48,90 @@ import org.apache.sis.util.resources.Err
* @module
*/
@Immutable
-abstract class NumberConverter<S extends Number, T> extends
InjectiveConverter<S,T> implements Serializable {
+final class NumberConverter<S extends Number, T extends Number> extends
SystemConverter<S,T> {
/**
* For cross-version compatibility.
*/
private static final long serialVersionUID = -8715054480508622025L;
/**
- * The source class.
- */
- private final Class<S> sourceClass;
-
- /**
- * For inner classes only.
+ * Creates a new converter for the given source and target classes.
+ * This constructor does not verify the validity of parameter values.
+ * It is caller's responsibility to ensure that the given class are
+ * supported by the {@link Numbers} methods.
*/
- NumberConverter(final Class<S> sourceClass) {
- this.sourceClass = sourceClass;
+ NumberConverter(final Class<S> sourceClass, final Class<T> targetClass) {
+ super(sourceClass, targetClass);
}
/**
- * Returns the source class given at construction time.
+ * Declares this converter as a injective or surjective function,
+ * depending on whether conversions loose information or not.
*/
@Override
- public final Class<S> getSourceClass() {
- return sourceClass;
+ public Set<FunctionProperty> properties() {
+ return EnumSet.of(Numbers.widestClass(sourceClass, targetClass) ==
targetClass
+ ? FunctionProperty.INJECTIVE :
FunctionProperty.SURJECTIVE,
+ FunctionProperty.ORDER_PRESERVING,
FunctionProperty.INVERTIBLE);
}
/**
- * Default implementation suitable only for subclasses having a target
class assignable
- * to {@link java.lang.Number}. In particular, the {@code Comparable} and
{@code String}
- * subclasses <strong>must</strong> override this method.
+ * Converts the given number to the target type if that type is different.
*/
@Override
- @SuppressWarnings("unchecked")
- public ObjectConverter<T,S> inverse() {
- assert Number.class.isAssignableFrom(getTargetClass()) : this;
- return (ObjectConverter<T,S>) create((Class<? extends Number>)
getTargetClass(), sourceClass);
+ public T convert(final S source) {
+ return Numbers.cast(source, targetClass);
}
/**
- * Creates a converter between numbers of the given classes.
+ * Returns the inverse of this converter.
*/
- @SuppressWarnings("unchecked") // Only for the last line.
- private static <S extends Number, T extends Number> ObjectConverter<S,T>
- create(final Class<S> sourceClass, final Class<T> targetClass)
- {
- final ObjectConverter<S,?> c;
- switch (Numbers.getEnumConstant(targetClass)) {
- case Numbers.DOUBLE: c = new Double<> (sourceClass); break;
- case Numbers.FLOAT: c = new Float<> (sourceClass); break;
- case Numbers.LONG: c = new Long<> (sourceClass); break;
- case Numbers.INTEGER: c = new Integer<> (sourceClass); break;
- case Numbers.SHORT: c = new Short<> (sourceClass); break;
- case Numbers.BYTE: c = new Byte<> (sourceClass); break;
- case Numbers.BIG_INTEGER: c = new BigInteger<>(sourceClass); break;
- case Numbers.BIG_DECIMAL: c = new BigDecimal<>(sourceClass); break;
- default: throw new AssertionError(targetClass);
- }
- return (ObjectConverter<S,T>) c;
- }
-
- /**
- * Returns the singleton instance on deserialization if the type is {@link
Number}.
- */
- final Object readResolve() throws ObjectStreamException {
- return (sourceClass == Number.class) ? singleton() : this;
+ @Override
+ public ObjectConverter<T,S> inverse() {
+ return new NumberConverter<>(targetClass, sourceClass).unique();
}
/**
- * Returns the singleton instance of this converter.
- */
- abstract NumberConverter<Number,T> singleton();
-
- /**
* Converter from numbers to comparables. This special case exists because
{@link Number}
* does not implement {@link java.lang.Comparable} directly, but all known
subclasses do.
*/
@Immutable
- static final class Comparable<S extends Number> extends NumberConverter<S,
java.lang.Comparable<?>> {
+ static final class Comparable<S extends Number> extends SystemConverter<S,
java.lang.Comparable<?>> {
/**
* For cross-version compatibility.
*/
private static final long serialVersionUID = 3716134638218072176L;
/**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
- */
- static final Comparable<Number> INSTANCE = new
Comparable<>(Number.class);
-
- /**
* Creates a new converter from the given type of numbers to {@code
Comparable} instances.
*/
+ @SuppressWarnings({"rawtypes","unchecked"})
Comparable(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override @SuppressWarnings({"rawtypes","unchecked"})
- public Class<java.lang.Comparable<?>> getTargetClass() {
- return (Class) java.lang.Comparable.class;
- }
-
- /** Converts the given number to a {@code Comparable} if its type is
different. */
- @Override public java.lang.Comparable<?> convert(final Number source) {
- if (source == null || source instanceof java.lang.Comparable<?>) {
- return (java.lang.Comparable<?>) source;
- }
- return (java.lang.Comparable<?>) Numbers.narrowestNumber(source);
- }
-
- /** Non-invertible converter (for now). */
- @Override public ObjectConverter<java.lang.Comparable<?>, S> inverse()
{
- throw new UnsupportedOperationException(Errors.format(
- Errors.Keys.UnsupportedOperation_1, "inverse"));
- }
-
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.lang.Comparable<?>> singleton()
{
- return INSTANCE;
- }
- }
-
- /**
- * Converter from numbers to doubles.
- */
- @Immutable
- static final class Double<S extends Number> extends NumberConverter<S,
java.lang.Double> {
- /**
- * For cross-version compatibility.
- */
- private static final long serialVersionUID = 1643009985070268985L;
-
- /**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
- */
- static final Double<Number> INSTANCE = new Double<>(Number.class);
-
- /**
- * Creates a new converter from the given type of numbers to {@code
Double} instances.
- */
- Double(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override public Class<java.lang.Double> getTargetClass() {
- return java.lang.Double.class;
- }
-
- /** Converts the given number to a {@code Double} if its type is
different. */
- @Override public java.lang.Double convert(final S source) {
- if (source == null || source instanceof java.lang.Double) {
- return (java.lang.Double) source;
- }
- return java.lang.Double.valueOf(source.doubleValue());
- }
-
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.lang.Double> singleton() {
- return INSTANCE;
- }
- }
-
- /**
- * Converter from numbers to floats.
- */
- @Immutable
- static final class Float<S extends Number> extends NumberConverter<S,
java.lang.Float> {
- /**
- * For cross-version compatibility.
- */
- private static final long serialVersionUID = -5900985555014433974L;
-
- /**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
- */
- static final Float<Number> INSTANCE = new Float<>(Number.class);
-
- /**
- * Creates a new converter from the given type of numbers to {@code
Float} instances.
- */
- Float(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override public Class<java.lang.Float> getTargetClass() {
- return java.lang.Float.class;
- }
-
- /** Converts the given number to a {@code Float} if its type is
different. */
- @Override public java.lang.Float convert(final S source) {
- if (source == null || source instanceof java.lang.Float) {
- return (java.lang.Float) source;
- }
- return java.lang.Float.valueOf(source.floatValue());
- }
-
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.lang.Float> singleton() {
- return INSTANCE;
- }
- }
-
- /**
- * Converter from numbers to longs.
- */
- @Immutable
- static final class Long<S extends Number> extends NumberConverter<S,
java.lang.Long> {
- /**
- * For cross-version compatibility.
- */
- private static final long serialVersionUID = -5320144566275003574L;
-
- /**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
- */
- static final Long<Number> INSTANCE = new Long<>(Number.class);
-
- /**
- * Creates a new converter from the given type of numbers to {@code
Long} instances.
- */
- Long(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override public Class<java.lang.Long> getTargetClass() {
- return java.lang.Long.class;
- }
-
- /** Converts the given number to a {@code Long} if its type is
different. */
- @Override public java.lang.Long convert(final S source) {
- if (source == null || source instanceof java.lang.Long) {
- return (java.lang.Long) source;
- }
- return java.lang.Long.valueOf(source.longValue());
- }
-
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.lang.Long> singleton() {
- return INSTANCE;
- }
- }
-
- /**
- * Converter from numbers to integers.
- */
- @Immutable
- static final class Integer<S extends Number> extends NumberConverter<S,
java.lang.Integer> {
- /**
- * For cross-version compatibility.
- */
- private static final long serialVersionUID = 2661178278691398269L;
-
- /**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
- */
- static final Integer<Number> INSTANCE = new Integer<>(Number.class);
-
- /**
- * Creates a new converter from the given type of numbers to {@code
Integer} instances.
- */
- Integer(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override public Class<java.lang.Integer> getTargetClass() {
- return java.lang.Integer.class;
- }
-
- /** Converts the given number to an {@code Integer} if its type is
different. */
- @Override public java.lang.Integer convert(final S source) {
- if (source == null || source instanceof java.lang.Integer) {
- return (java.lang.Integer) source;
- }
- return java.lang.Integer.valueOf(source.intValue());
+ super(sourceClass, (Class) java.lang.Comparable.class);
}
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.lang.Integer> singleton() {
- return INSTANCE;
- }
- }
-
- /**
- * Converter from numbers to shorts.
- */
- @Immutable
- static final class Short<S extends Number> extends NumberConverter<S,
java.lang.Short> {
- /**
- * For cross-version compatibility.
- */
- private static final long serialVersionUID = -5943559376400249179L;
-
/**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
+ * If the source class implements {@code Comparable}, then this
converter is bijective.
+ * Otherwise there is no known property for this converter.
*/
- static final Short<Number> INSTANCE = new Short<>(Number.class);
-
- /**
- * Creates a new converter from the given type of numbers to {@code
Short} instances.
- */
- Short(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override public Class<java.lang.Short> getTargetClass() {
- return java.lang.Short.class;
- }
-
- /** Converts the given number to a {@code Short} if its type is
different. */
- @Override public java.lang.Short convert(final S source) {
- if (source == null || source instanceof java.lang.Short) {
- return (java.lang.Short) source;
+ @Override
+ public Set<FunctionProperty> properties() {
+ if (Comparable.class.isAssignableFrom(sourceClass)) {
+ return EnumSet.of(FunctionProperty.INJECTIVE,
FunctionProperty.SURJECTIVE,
+ FunctionProperty.ORDER_PRESERVING);
}
- return java.lang.Short.valueOf(source.shortValue());
+ return EnumSet.noneOf(FunctionProperty.class);
}
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.lang.Short> singleton() {
- return INSTANCE;
- }
- }
-
- /**
- * Converter from numbers to shorts.
- */
- @Immutable
- static final class Byte<S extends Number> extends NumberConverter<S,
java.lang.Byte> {
/**
- * For cross-version compatibility.
+ * Converts the given number to a {@code Comparable} if its type is
different.
*/
- private static final long serialVersionUID = 1381038535870541045L;
-
- /**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
- */
- static final Byte<Number> INSTANCE = new Byte<>(Number.class);
-
- /**
- * Creates a new converter from the given type of numbers to {@code
Byte} instances.
- */
- Byte(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override public Class<java.lang.Byte> getTargetClass() {
- return java.lang.Byte.class;
- }
-
- /** Converts the given number to a {@code Byte} if its type is
different. */
- @Override public java.lang.Byte convert(final S source) {
- if (source == null || source instanceof java.lang.Byte) {
- return (java.lang.Byte) source;
- }
- return java.lang.Byte.valueOf(source.byteValue());
- }
-
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.lang.Byte> singleton() {
- return INSTANCE;
- }
- }
-
- /**
- * Converter from numbers to {@link java.math.BigDecimal}.
- */
- @Immutable
- static final class BigDecimal<S extends Number> extends NumberConverter<S,
java.math.BigDecimal> {
- /**
- * For cross-version compatibility.
- */
- private static final long serialVersionUID = -6318144992861058878L;
-
- /**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
- */
- static final BigDecimal<Number> INSTANCE = new
BigDecimal<>(Number.class);
-
- /**
- * Creates a new converter from the given type of numbers to {@code
BigDecimal} instances.
- */
- BigDecimal(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override public Class<java.math.BigDecimal> getTargetClass() {
- return java.math.BigDecimal.class;
- }
-
- /** Converts the given number to a {@code BigDecimal} if its type is
different. */
- @Override public java.math.BigDecimal convert(final S source) {
- if (source == null || source instanceof java.math.BigDecimal) {
- return (java.math.BigDecimal) source;
- }
- if (source instanceof java.math.BigInteger) {
- return new java.math.BigDecimal((java.math.BigInteger) source);
- }
- if (Numbers.isInteger(source.getClass())) {
- return java.math.BigDecimal.valueOf(source.longValue());
- }
- return java.math.BigDecimal.valueOf(source.doubleValue());
- }
-
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.math.BigDecimal> singleton() {
- return INSTANCE;
- }
- }
-
- /**
- * Converter from numbers to {@link java.math.BigInteger}.
- */
- @Immutable
- static final class BigInteger<S extends Number> extends NumberConverter<S,
java.math.BigInteger> {
- /**
- * For cross-version compatibility.
- */
- private static final long serialVersionUID = 5940724099300523246L;
-
- /**
- * The usually shared instance. {@link ConverterRegistry} needs only
the {@link Number}
- * type. Other types are created only by {@code
StringConverter.Foo.inverse()} methods.
- */
- static final BigInteger<Number> INSTANCE = new
BigInteger<>(Number.class);
-
- /**
- * Creates a new converter from the given type of numbers to {@code
BigInteger} instances.
- */
- BigInteger(final Class<S> sourceClass) {
- super(sourceClass);
- }
-
- /** Returns the destination type (same for all instances of this
class). */
- @Override public Class<java.math.BigInteger> getTargetClass() {
- return java.math.BigInteger.class;
- }
-
- /** Converts the given number to a {@code BigInteger} if its type is
different. */
- @Override public java.math.BigInteger convert(final S source) {
- if (source == null || source instanceof java.math.BigInteger) {
- return (java.math.BigInteger) source;
- }
- if (source instanceof java.math.BigDecimal) {
- return ((java.math.BigDecimal) source).toBigInteger();
+ @Override
+ public java.lang.Comparable<?> convert(final Number source) {
+ if (source == null || source instanceof java.lang.Comparable<?>) {
+ return (java.lang.Comparable<?>) source;
}
- return java.math.BigInteger.valueOf(source.longValue());
- }
-
- /** Returns the singleton instance on deserialization. */
- @Override NumberConverter<Number, java.math.BigInteger> singleton() {
- return INSTANCE;
+ return (java.lang.Comparable<?>) Numbers.narrowestNumber(source);
}
}
}
Added:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java?rev=1455514&view=auto
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
(added)
+++
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
[UTF-8] Tue Mar 12 12:54:31 2013
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sis.internal.converter;
+
+import java.io.ObjectStreamException;
+import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.util.resources.Errors;
+
+
+/**
+ * Base class of all converters defined in the {@code org.apache.sis.internal}
package.
+ * Those converters are returned by system-wide {@link ConverterRegitry}, and
cached for
+ * reuse.
+ *
+ * @param <S> The base type of source objects.
+ * @param <T> The base type of converted objects.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3
+ * @version 0.3
+ * @module
+ */
+abstract class SystemConverter<S,T> extends ClassPair<S,T> implements
ObjectConverter<S,T> {
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = 885663610056067478L;
+
+ /**
+ * Creates a new converter for the given source and target classes.
+ *
+ * @param sourceClass The {@linkplain ObjectConverter#getSourceClass()
source class}.
+ * @param targetClass The {@linkplain ObjectConverter#getTargetClass()
target class}.
+ */
+ SystemConverter(final Class<S> sourceClass, final Class<T> targetClass) {
+ super(sourceClass, targetClass);
+ }
+
+ /**
+ * Returns the source class given at construction time.
+ */
+ @Override
+ public final Class<S> getSourceClass() {
+ return sourceClass;
+ }
+
+ /**
+ * Returns the target class given at construction time.
+ */
+ @Override
+ public final Class<T> getTargetClass() {
+ return targetClass;
+ }
+
+ /**
+ * Unsupported by default. To be overridden by subclasses that support
this operation.
+ */
+ @Override
+ public ObjectConverter<T, S> inverse() throws
UnsupportedOperationException {
+ throw new UnsupportedOperationException(Errors.format(
+ Errors.Keys.UnsupportedOperation_1, "inverse"));
+ }
+
+ /**
+ * Returns an unique instance of this converter. If a converter already
exists for the same
+ * source an target classes, then this converter is returned. Otherwise
this converter is
+ * cached and returned.
+ */
+ final ObjectConverter<S,T> unique() {
+ return ConverterRegistry.SYSTEM.unique(this, true);
+ }
+
+ /**
+ * Returns the singleton instance on deserialization, if any. If no
instance already exist
+ * in the virtual machine, we do not cache the instance (for now) for
security reasons.
+ */
+ protected final Object readResolve() throws ObjectStreamException {
+ return ConverterRegistry.SYSTEM.unique(this, false);
+ }
+}
Propchange:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java?rev=1455514&r1=1455513&r2=1455514&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
[UTF-8] Tue Mar 12 12:54:31 2013
@@ -419,8 +419,8 @@ public final class Numbers extends Stati
}
/**
- * Returns the number of the smallest class capable to hold the specified
value. If the
- * given value is {@code null}, then this method returns {@code null}.
Otherwise this
+ * Returns the given number wrapped in the smallest class capable to hold
the specified value.
+ * If the given value is {@code null}, then this method returns {@code
null}. Otherwise this
* method delegates to {@link #narrowestNumber(double)} or {@link
#narrowestNumber(long)}
* depending on the value type.
*
@@ -517,7 +517,8 @@ public final class Numbers extends Stati
/**
* Casts a number to the specified class. The class must by one of {@link
Byte},
- * {@link Short}, {@link Integer}, {@link Long}, {@link Float} or {@link
Double}.
+ * {@link Short}, {@link Integer}, {@link Long}, {@link Float}, {@link
Double},
+ * {@link BigInteger} or {@link BigDecimal}.
* This method makes the following choice:
*
* <ul>
@@ -528,10 +529,6 @@ public final class Numbers extends Stati
* <li>And likewise for all remaining known types.</li>
* </ul>
*
- * {@note This method is intentionally restricted to primitive types.
Other types
- * like <code>BigDecimal</code> are not the purpose of this method.
- * See <code>ObjectConverter</code> for more generic methods.}
- *
* This method does not verify if the given type is wide enough for the
given value,
* because the type has typically been calculated by {@link
#widestClass(Class, Class)}
* or {@link #narrowestClass(Number)}. If nevertheless the given type is
not wide enough,
@@ -552,20 +549,47 @@ public final class Numbers extends Stati
if (number == null || number.getClass() == type) {
return (N) number;
}
- if (type == Double .class) return (N) Double
.valueOf(number.doubleValue());
- if (type == Float .class) return (N) Float .valueOf(number.
floatValue());
- if (type == Long .class) return (N) Long .valueOf(number.
longValue());
- if (type == Integer.class) return (N) Integer.valueOf(number.
intValue());
- if (type == Short .class) return (N) Short .valueOf(number.
shortValue());
- if (type == Byte .class) return (N) Byte .valueOf(number.
byteValue());
- throw unknownType(type);
+ switch (getEnumConstant(type)) {
+ case BYTE: return (N) Byte .valueOf(number. byteValue());
+ case SHORT: return (N) Short .valueOf(number. shortValue());
+ case INTEGER: return (N) Integer.valueOf(number. intValue());
+ case LONG: return (N) Long .valueOf(number. longValue());
+ case FLOAT: return (N) Float .valueOf(number. floatValue());
+ case DOUBLE: return (N) Double .valueOf(number.doubleValue());
+ case BIG_INTEGER: {
+ final BigInteger c;
+ if (number instanceof BigDecimal) {
+ c = ((BigDecimal) number).toBigInteger();
+ } else {
+ c = BigInteger.valueOf(number.longValue());
+ }
+ return (N) c;
+ }
+ case BIG_DECIMAL: {
+ final BigDecimal c;
+ if (number instanceof BigInteger) {
+ c =new BigDecimal((BigInteger) number);
+ } else if (isInteger(number.getClass())) {
+ c = BigDecimal.valueOf(number.longValue());
+ } else {
+ c = BigDecimal.valueOf(number.doubleValue());
+ }
+ return (N) c;
+ }
+ default: {
+ if (type.isInstance(number)) {
+ return (N) number;
+ }
+ throw unknownType(type);
+ }
+ }
}
/**
* Wraps the given value in a {@code Number} of the specified class.
- * The given type shall be one of {@link Byte}, {@link Short}, {@link
Integer},
- * {@link Long}, {@link Float} or {@link Double} classes. Furthermore, the
given
- * value shall be convertible to the given class without precision lost,
+ * The given type shall be one of {@link Byte}, {@link Short}, {@link
Integer}, {@link Long},
+ * {@link Float}, {@link Double}, {@link BigInteger} and {@link
BigDecimal} classes.
+ * Furthermore, the given value shall be convertible to the given class
without precision lost,
* otherwise an {@link IllegalArgumentException} will be thrown.
*
* @param <N> The wrapper class.
@@ -581,13 +605,17 @@ public final class Numbers extends Stati
throws IllegalArgumentException
{
final N number;
- if (type == Double .class) return (N) Double .valueOf(value);
// No need to verify.
- else if (type == Float .class) number = (N) Float .valueOf((float)
value);
- else if (type == Long .class) number = (N) Long .valueOf((long)
value);
- else if (type == Integer.class) number = (N) Integer.valueOf((int)
value);
- else if (type == Short .class) number = (N) Short .valueOf((short)
value);
- else if (type == Byte .class) number = (N) Byte .valueOf((byte)
value);
- else throw unknownType(type);
+ switch (getEnumConstant(type)) {
+ case BYTE: number = (N) Byte .valueOf((byte) value);
break;
+ case SHORT: number = (N) Short .valueOf((short) value);
break;
+ case INTEGER: number = (N) Integer .valueOf((int) value);
break;
+ case LONG: number = (N) Long .valueOf((long) value);
break;
+ case FLOAT: number = (N) Float .valueOf((float) value);
break;
+ case DOUBLE: return (N) Double .valueOf(value); // No
need to verify.
+ case BIG_INTEGER: number = (N) BigInteger.valueOf((long) value);
break;
+ case BIG_DECIMAL: return (N) BigDecimal.valueOf(value); // No
need to verify.
+ default: throw unknownType(type);
+ }
if (Double.doubleToLongBits(number.doubleValue()) !=
Double.doubleToLongBits(value)) {
throw new
IllegalArgumentException(Errors.format(Errors.Keys.CanNotConvertValue_2, value,
type));
}
@@ -596,6 +624,7 @@ public final class Numbers extends Stati
/**
* Converts the specified string into a value object. The value object can
be an instance of
+ * {@link BigDecimal}, {@link BigInteger},
* {@link Double}, {@link Float}, {@link Long}, {@link Integer}, {@link
Short}, {@link Byte},
* {@link Boolean}, {@link Character} or {@link String} according the
specified type. This
* method makes the following choice:
@@ -608,11 +637,6 @@ public final class Numbers extends Stati
* <li>And likewise for all remaining known types.</li>
* </ul>
*
- * {@note This method is intentionally restricted to primitive types, with
the addition of
- * <code>String</code> which can be though as an identity
operation. Other types
- * like <code>BigDecimal</code> are not the purpose of this method.
See the
- * <code>ConverterRegistry</code> class for a more generic method.}
- *
* @param <T> The requested type.
* @param value the value to parse.
* @param type The requested type.
@@ -628,26 +652,30 @@ public final class Numbers extends Stati
if (value == null || type == String.class) {
return (T) value;
}
- if (type == Character.class) {
- /*
- * If the string is empty, returns 0 which means "end of string"
in C/C++
- * and NULL in Unicode standard. If non-empty, take only the first
char.
- * This is somewhat consistent with Boolean.valueOf(...) which is
quite
- * lenient about the parsing as well, and throwing a
NumberFormatException
- * for those would not be appropriate.
- */
- return (T) Character.valueOf(value.isEmpty() ? 0 :
value.charAt(0));
+ switch (getEnumConstant(type)) {
+ case CHARACTER: {
+ /*
+ * If the string is empty, returns 0 which means "end of
string" in C/C++
+ * and NULL in Unicode standard. If non-empty, take only the
first char.
+ * This is somewhat consistent with Boolean.valueOf(...) which
is quite
+ * lenient about the parsing as well, and throwing a
NumberFormatException
+ * for those would not be appropriate.
+ */
+ return (T) Character.valueOf(value.isEmpty() ? 0 :
value.charAt(0));
+ }
+ // Do not trim whitespaces. It is up to the caller to do that if
he wants.
+ // For such low level function, we are better to avoid hidden
initiative.
+ case BOOLEAN: return (T) Boolean.valueOf(value);
+ case BYTE: return (T) Byte .valueOf(value);
+ case SHORT: return (T) Short .valueOf(value);
+ case INTEGER: return (T) Integer.valueOf(value);
+ case LONG: return (T) Long .valueOf(value);
+ case FLOAT: return (T) Float .valueOf(value);
+ case DOUBLE: return (T) Double .valueOf(value);
+ case BIG_INTEGER: return (T) new BigInteger(value);
+ case BIG_DECIMAL: return (T) new BigDecimal(value);
+ default: throw unknownType(type);
}
- // Do not trim whitespaces. It is up to the caller to do that if he
wants.
- // For such low level function, we are better to avoid hidden
initiative.
- if (type == Double .class) return (T) Double .valueOf(value);
- if (type == Float .class) return (T) Float .valueOf(value);
- if (type == Long .class) return (T) Long .valueOf(value);
- if (type == Integer.class) return (T) Integer.valueOf(value);
- if (type == Short .class) return (T) Short .valueOf(value);
- if (type == Byte .class) return (T) Byte .valueOf(value);
- if (type == Boolean.class) return (T) Boolean.valueOf(value);
- throw unknownType(type);
}
/**
Added:
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java?rev=1455514&view=auto
==============================================================================
---
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java
(added)
+++
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java
[UTF-8] Tue Mar 12 12:54:31 2013
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sis.internal.converter;
+
+import java.math.BigInteger;
+import java.math.BigDecimal;
+import org.apache.sis.math.FunctionProperty;
+import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.util.UnconvertibleObjectException;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assert.*;
+
+
+/**
+ * Tests the various {@link NumberConverter} implementations.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.3 (derived from geotk-2.4)
+ * @version 0.3
+ * @module
+ */
+public final strictfp class NumberConverterTest extends TestCase {
+ /**
+ * Asserts that conversion of the given {@code source} value produces
+ * the given {@code target} value, and tests the inverse conversion.
+ */
+ private static <S extends Number, T extends Number> void
runInvertibleConversion(
+ final ObjectConverter<S,T> c, final S source, final T target)
+ throws UnconvertibleObjectException
+ {
+ assertEquals("Forward conversion.", target, c.convert(source));
+ assertEquals("Inverse conversion.", source,
c.inverse().convert(target));
+ assertSame("Inconsistent inverse.", c, c.inverse().inverse());
+ assertTrue("Invertible converters shall declare this capability.",
+ c.properties().contains(FunctionProperty.INVERTIBLE));
+ }
+
+ /**
+ * Tests conversions to {@link Byte} values.
+ */
+ @Test
+ public void testByte() {
+ final ObjectConverter<Integer, Byte> c =
+ new NumberConverter<>(Integer.class, Byte.class).unique();
+ runInvertibleConversion(c, Integer.valueOf(-8), Byte.valueOf((byte)
-8));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+
+ /**
+ * Tests conversions to {@link Short} values.
+ */
+ @Test
+ public void testShort() {
+ final ObjectConverter<Integer, Short> c =
+ new NumberConverter<>(Integer.class, Short.class).unique();
+ runInvertibleConversion(c, Integer.valueOf(-8), Short.valueOf((short)
-8));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+
+ /**
+ * Tests conversions to {@link Integer} values.
+ */
+ @Test
+ public void testInteger() {
+ final ObjectConverter<Float, Integer> c =
+ new NumberConverter<>(Float.class, Integer.class).unique();
+ runInvertibleConversion(c, Float.valueOf(-8), Integer.valueOf(-8));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+
+ /**
+ * Tests conversions to {@link Long} values.
+ */
+ @Test
+ public void testLong() {
+ final ObjectConverter<Float, Long> c =
+ new NumberConverter<>(Float.class, Long.class).unique();
+ runInvertibleConversion(c, Float.valueOf(-8), Long.valueOf(-8));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+
+ /**
+ * Tests conversions to {@link Float} values.
+ */
+ @Test
+ public void testFloat() {
+ final ObjectConverter<Double, Float> c =
+ new NumberConverter<>(Double.class, Float.class).unique();
+ runInvertibleConversion(c, Double.valueOf(2.5), Float.valueOf(2.5f));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+
+ /**
+ * Tests conversions to {@link Double} values.
+ */
+ @Test
+ public void testDouble() {
+ final ObjectConverter<BigDecimal, Double> c =
+ new NumberConverter<>(BigDecimal.class, Double.class).unique();
+ runInvertibleConversion(c, BigDecimal.valueOf(2.5),
Double.valueOf(2.5));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+
+ /**
+ * Tests conversions to {@link BigInteger} values.
+ */
+ @Test
+ public void testBigInteger() {
+ final ObjectConverter<Double, BigInteger> c =
+ new NumberConverter<>(Double.class, BigInteger.class).unique();
+ runInvertibleConversion(c, Double.valueOf(1000),
BigInteger.valueOf(1000));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+
+ /**
+ * Tests conversions to {@link BigDecimal} values.
+ */
+ @Test
+ public void testBigDecimal() {
+ final ObjectConverter<Double, BigDecimal> c =
+ new NumberConverter<>(Double.class, BigDecimal.class).unique();
+ runInvertibleConversion(c, Double.valueOf(2.5),
BigDecimal.valueOf(2.5));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+
+ /**
+ * Tests conversions to comparable objects. Should returns the object
unchanged
+ * since all {@link Number} subclasses are comparable.
+ */
+ @Test
+ public void testComparable() {
+ final ObjectConverter<Number,Comparable<?>> c =
+ new NumberConverter.Comparable<>(Number.class).unique();
+ final Integer value = 8;
+ assertSame(value, c.convert(value));
+ assertSame("Deserialization shall resolves to the singleton
instance.", c, assertSerializedEquals(c));
+ }
+}
Propchange:
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java?rev=1455514&r1=1455513&r2=1455514&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java
[UTF-8] Tue Mar 12 12:54:31 2013
@@ -31,6 +31,7 @@ import org.apache.sis.math.FunctionPrope
import org.apache.sis.util.ObjectConverter;
import org.apache.sis.util.UnconvertibleObjectException;
import org.apache.sis.util.iso.SimpleInternationalString;
+import org.apache.sis.test.TestCase;
import org.junit.Test;
import static org.apache.sis.test.Assert.*;
@@ -44,7 +45,7 @@ import static org.apache.sis.test.Assert
* @version 0.3
* @module
*/
-public final strictfp class StringConverterTest {
+public final strictfp class StringConverterTest extends TestCase {
/**
* Asserts that conversion of the given {@code source} value produces
* the given {@code target} value, and tests the inverse conversion.
Modified:
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1455514&r1=1455513&r2=1455514&view=diff
==============================================================================
---
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
[UTF-8] (original)
+++
sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
[UTF-8] Tue Mar 12 12:54:31 2013
@@ -95,6 +95,7 @@ import org.junit.runners.Suite;
org.apache.sis.internal.converter.URLConverterTest.class,
org.apache.sis.internal.converter.FileConverterTest.class,
org.apache.sis.internal.converter.StringConverterTest.class,
+ org.apache.sis.internal.converter.NumberConverterTest.class,
org.apache.sis.internal.converter.FallbackConverterTest.class,
// XML most basic types.