sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1455255 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/internal/converter/ main/java/org/apache/sis/io/ main/java/org/apache/sis/util/ test/java/org/apache/sis/internal/converter/ test/java/org/apache/sis/test/suite/
Date Mon, 11 Mar 2013 17:48:04 GMT
Author: desruisseaux
Date: Mon Mar 11 17:48:03 2013
New Revision: 1455255

URL: http://svn.apache.org/r1455255
Log:
Reorganized some converters in a more systematic way, and added test cases.
In the next commit, we will try to reduce the size of this stuff by replacing
many constants by Map<Class,?>.

Added:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java   (with props)
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java   (with props)
Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FileConverter.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/internal/converter/StringConverter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URIConverter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URLConverter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.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/FallbackConverterTest.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FileConverterTest.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URIConverterTest.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URLConverterTest.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/FileConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FileConverter.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FileConverter.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/FileConverter.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -55,34 +55,6 @@ abstract class FileConverter<T> extends 
     }
 
     /**
-     * Converter from {@link File} to {@link java.lang.String}.
-     */
-    @Immutable
-    static final class String extends FileConverter<java.lang.String> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = -6811286687809954151L;
-        /** The unique, shared instance. */ static final String INSTANCE = new String();
-        /** For {@link #INSTANCE} only.  */ private String() {}
-
-        @Override public Class<java.lang.String> getTargetClass() {
-            return java.lang.String.class;
-        }
-
-        @Override public java.lang.String convert(final File source) {
-            return (source != null) ? source.getPath() : null;
-        }
-
-        /** Returns the inverse, since this converter is "almost" bijective. */
-        @Override public ObjectConverter<java.lang.String, File> inverse() {
-            return StringConverter.File.INSTANCE;
-        }
-
-        /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
-            return INSTANCE;
-        }
-    }
-
-    /**
      * Converter from {@link File} to {@link java.net.URI}.
      * Note that this converter change relative paths to absolute paths.
      */

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=1455255&r1=1455254&r2=1455255&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] Mon Mar 11 17:48:03 2013
@@ -20,53 +20,126 @@ import java.io.Serializable;
 import java.io.ObjectStreamException;
 import net.jcip.annotations.Immutable;
 import org.apache.sis.util.Numbers;
+import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.util.resources.Errors;
 
 
 /**
  * Handles conversions from {@link java.lang.Number} to various objects.
  *
+ * @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.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)
  * @version 0.3
  * @module
  */
 @Immutable
-abstract class NumberConverter<T> extends SurjectiveConverter<Number,T> implements Serializable {
+abstract class NumberConverter<S extends Number, T> extends InjectiveConverter<S,T> implements Serializable {
     /**
      * For cross-version compatibility.
      */
     private static final long serialVersionUID = -8715054480508622025L;
 
     /**
+     * The source class.
+     */
+    private final Class<S> sourceClass;
+
+    /**
      * For inner classes only.
      */
-    NumberConverter() {
+    NumberConverter(final Class<S> sourceClass) {
+        this.sourceClass = sourceClass;
     }
 
     /**
-     * Returns the source class, which is always {@link Number}.
+     * Returns the source class given at construction time.
      */
     @Override
-    public final Class<Number> getSourceClass() {
-        return Number.class;
+    public final Class<S> getSourceClass() {
+        return sourceClass;
+    }
+
+    /**
+     * 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.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public ObjectConverter<T,S> inverse() {
+        assert Number.class.isAssignableFrom(getTargetClass()) : this;
+        return (ObjectConverter<T,S>) create((Class<? extends Number>) getTargetClass(), sourceClass);
+    }
+
+    /**
+     * Creates a converter between numbers of the given classes.
+     */
+    @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;
+    }
+
+    /**
+     * 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 extends NumberConverter<java.lang.Comparable<?>> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 3716134638218072176L;
-        /** The unique, shared instance. */ static final Comparable INSTANCE = new Comparable();
-        /** For {@link #INSTANCE} only.  */ private Comparable() {}
+    static final class Comparable<S extends Number> extends NumberConverter<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.
+         */
+        Comparable(final Class<S> sourceClass) {
+            super(sourceClass);
+        }
 
-        @Override
-        @SuppressWarnings({"rawtypes","unchecked"})
+        /** 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;
@@ -74,31 +147,14 @@ abstract class NumberConverter<T> extend
             return (java.lang.Comparable<?>) Numbers.narrowestNumber(source);
         }
 
-        /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
-            return INSTANCE;
-        }
-    }
-
-    /**
-     * Converter from numbers to strings.
-     */
-    @Immutable
-    static final class String extends NumberConverter<java.lang.String> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 1460382215827540172L;
-        /** The unique, shared instance. */ static final String INSTANCE = new String();
-        /** For {@link #INSTANCE} only.  */ private String() {}
-
-        @Override public Class<java.lang.String> getTargetClass() {
-            return java.lang.String.class;
-        }
-
-        @Override public java.lang.String convert(final Number source) {
-            return (source != null) ? source.toString() : null;
+        /** 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. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.lang.Comparable<?>> singleton() {
             return INSTANCE;
         }
     }
@@ -107,21 +163,40 @@ abstract class NumberConverter<T> extend
      * Converter from numbers to doubles.
      */
     @Immutable
-    static final class Double extends NumberConverter<java.lang.Double> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 1643009985070268985L;
-        /** The unique, shared instance. */ static final Double INSTANCE = new Double();
-        /** For {@link #INSTANCE} only.  */ private Double() {}
+    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;
         }
 
-        @Override public java.lang.Double convert(final Number source) {
-            return (source != null) ? java.lang.Double.valueOf(source.doubleValue()) : null;
+        /** 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. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.lang.Double> singleton() {
             return INSTANCE;
         }
     }
@@ -130,21 +205,40 @@ abstract class NumberConverter<T> extend
      * Converter from numbers to floats.
      */
     @Immutable
-    static final class Float extends NumberConverter<java.lang.Float> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = -5900985555014433974L;
-        /** The unique, shared instance. */ static final Float INSTANCE = new Float();
-        /** For {@link #INSTANCE} only.  */ private Float() {}
+    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;
         }
 
-        @Override public java.lang.Float convert(final Number source) {
-            return (source != null) ? java.lang.Float.valueOf(source.floatValue()) : null;
+        /** 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. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.lang.Float> singleton() {
             return INSTANCE;
         }
     }
@@ -153,21 +247,40 @@ abstract class NumberConverter<T> extend
      * Converter from numbers to longs.
      */
     @Immutable
-    static final class Long extends NumberConverter<java.lang.Long> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = -5320144566275003574L;
-        /** The unique, shared instance. */ static final Long INSTANCE = new Long();
-        /** For {@link #INSTANCE} only.  */ private Long() {}
+    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;
         }
 
-        @Override public java.lang.Long convert(final Number source) {
-            return (source != null) ? java.lang.Long.valueOf(source.longValue()) : null;
+        /** 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. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.lang.Long> singleton() {
             return INSTANCE;
         }
     }
@@ -176,21 +289,40 @@ abstract class NumberConverter<T> extend
      * Converter from numbers to integers.
      */
     @Immutable
-    static final class Integer extends NumberConverter<java.lang.Integer> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 2661178278691398269L;
-        /** The unique, shared instance. */ static final Integer INSTANCE = new Integer();
-        /** For {@link #INSTANCE} only.  */ private Integer() {}
+    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;
         }
 
-        @Override public java.lang.Integer convert(final Number source) {
-            return (source != null) ? java.lang.Integer.valueOf(source.intValue()) : null;
+        /** 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());
         }
 
         /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.lang.Integer> singleton() {
             return INSTANCE;
         }
     }
@@ -199,21 +331,40 @@ abstract class NumberConverter<T> extend
      * Converter from numbers to shorts.
      */
     @Immutable
-    static final class Short extends NumberConverter<java.lang.Short> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = -5943559376400249179L;
-        /** The unique, shared instance. */ static final Short INSTANCE = new Short();
-        /** For {@link #INSTANCE} only.  */ private Short() {}
+    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.
+         */
+        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;
         }
 
-        @Override public java.lang.Short convert(final Number source) {
-            return (source != null) ? java.lang.Short.valueOf(source.shortValue()) : null;
+        /** 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;
+            }
+            return java.lang.Short.valueOf(source.shortValue());
         }
 
         /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.lang.Short> singleton() {
             return INSTANCE;
         }
     }
@@ -222,21 +373,40 @@ abstract class NumberConverter<T> extend
      * Converter from numbers to shorts.
      */
     @Immutable
-    static final class Byte extends NumberConverter<java.lang.Byte> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 1381038535870541045L;
-        /** The unique, shared instance. */ static final Byte INSTANCE = new Byte();
-        /** For {@link #INSTANCE} only.  */ private Byte() {}
+    static final class Byte<S extends Number> extends NumberConverter<S, java.lang.Byte> {
+        /**
+         * For cross-version compatibility.
+         */
+        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;
         }
 
-        @Override public java.lang.Byte convert(final Number source) {
-            return (source != null) ? java.lang.Byte.valueOf(source.byteValue()) : null;
+        /** 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. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.lang.Byte> singleton() {
             return INSTANCE;
         }
     }
@@ -245,20 +415,33 @@ abstract class NumberConverter<T> extend
      * Converter from numbers to {@link java.math.BigDecimal}.
      */
     @Immutable
-    static final class BigDecimal extends NumberConverter<java.math.BigDecimal> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = -6318144992861058878L;
-        /** The unique, shared instance. */ static final BigDecimal INSTANCE = new BigDecimal();
-        /** For {@link #INSTANCE} only.  */ private BigDecimal() {}
+    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;
         }
 
-        @Override public java.math.BigDecimal convert(final Number source) {
-            if (source == null) {
-                return null;
-            }
-            if (source instanceof java.math.BigDecimal) {
+        /** 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) {
@@ -271,7 +454,7 @@ abstract class NumberConverter<T> extend
         }
 
         /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.math.BigDecimal> singleton() {
             return INSTANCE;
         }
     }
@@ -280,20 +463,33 @@ abstract class NumberConverter<T> extend
      * Converter from numbers to {@link java.math.BigInteger}.
      */
     @Immutable
-    static final class BigInteger extends NumberConverter<java.math.BigInteger> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 5940724099300523246L;
-        /** The unique, shared instance. */ static final BigInteger INSTANCE = new BigInteger();
-        /** For {@link #INSTANCE} only.  */ private BigInteger() {}
+    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;
         }
 
-        @Override public java.math.BigInteger convert(final Number source) {
-            if (source == null) {
-                return null;
-            }
-            if (source instanceof java.math.BigInteger) {
+        /** 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) {
@@ -303,7 +499,7 @@ abstract class NumberConverter<T> extend
         }
 
         /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
+        @Override NumberConverter<Number, java.math.BigInteger> singleton() {
             return INSTANCE;
         }
     }

Added: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java?rev=1455255&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java (added)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -0,0 +1,181 @@
+/*
+ * 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.Locale;
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+import org.opengis.util.InternationalString;
+import net.jcip.annotations.Immutable;
+import org.apache.sis.util.ObjectConverter;
+
+
+/**
+ * Handles conversions from arbitrary objects to {@link String}. This converter is
+ * suitable to any object for which the {@link #toString()} method is sufficient.
+ *
+ * @param <S> The source type.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+@Immutable
+class ObjectToString<S> extends InjectiveConverter<S,String> implements Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 1460382215827540172L;
+
+    /**
+     * The shared instance for international strings.
+     */
+    static final ObjectToString<InternationalString> I18N = new ObjectToString<>(InternationalString.class, StringConverter.InternationalString.INSTANCE);
+
+    /**
+     * The shared instance for numbers. {@link ConverterRegistry} needs only the {@link Number}
+     * type. Other subtypes are created only by {@code StringConverter.Foo.inverse()} methods.
+     */
+    static final ObjectToString<Number> NUMBER = new ObjectToString<>(Number.class, StringConverter.Number.INSTANCE);
+
+    /**
+     * The shared instance for booleans.
+     */
+    static final ObjectToString<Boolean> BOOLEAN = new ObjectToString<>(Boolean.class, StringConverter.Boolean.INSTANCE);
+
+    /**
+     * The shared instance for URI.
+     * This converter does not encode the string, i.e. the conversion is performed with
+     * the {@link URI#toString()} method rather than {@link URI#toASCIIString()}. We do
+     * that in order to avoid too many transformations if we convert back and forward to
+     * {@code String}.
+     */
+    static final ObjectToString<File> FILE = new ObjectToString<>(File.class, StringConverter.File.INSTANCE);
+
+    /**
+     * The shared instance for URI.
+     * This converter does not encode the string, i.e. the conversion is performed with
+     * the {@link URI#toString()} method rather than {@link URI#toASCIIString()}. We do
+     * that in order to avoid too many transformations if we convert back and forward to
+     * {@code String}.
+     */
+    static final ObjectToString<URI> URI = new ObjectToString<>(URI.class, StringConverter.URI.INSTANCE);
+
+    /**
+     * The shared instance for URL.
+     * This converter does not encode the string. We do that in order to avoid too many
+     * transformations if we convert back and forward to {@code String}.
+     */
+    static final ObjectToString<URL> URL = new ObjectToString<>(URL.class, StringConverter.URL.INSTANCE);
+
+    /**
+     * The shared instance for locales.
+     */
+    static final ObjectToString<Locale> LOCALE = new ObjectToString<>(Locale.class, StringConverter.Locale.INSTANCE);
+
+    /**
+     * The shared instance for character sets.
+     */
+    static final ObjectToString<java.nio.charset.Charset> CHARSET = new Charset();
+
+    /**
+     * The source class.
+     */
+    private final Class<S> sourceClass;
+
+    /**
+     * The inverse converter specified at construction time.
+     */
+    private final ObjectConverter<String, S> inverse;
+
+    /**
+     * Creates a new converter from the given type of objects to {@code String} instances.
+     */
+    ObjectToString(final Class<S> sourceClass, final ObjectConverter<String, S> inverse) {
+        this.sourceClass = sourceClass;
+        this.inverse = inverse;
+    }
+
+    /**
+     * Returns the source class given at construction time.
+     */
+    @Override
+    public final Class<S> getSourceClass() {
+        return sourceClass;
+    }
+
+    /**
+     * Returns the destination type (same for all instances of this class).
+     */
+    @Override
+    public final Class<String> getTargetClass() {
+        return String.class;
+    }
+
+    /**
+     * Converts the given number to a string.
+     */
+    @Override
+    public String convert(final S source) {
+        return (source != null) ? source.toString() : null;
+    }
+
+    /**
+     * Returns the inverse given at construction time.
+     */
+    @Override
+    public final ObjectConverter<String, S> inverse() {
+        return inverse;
+    }
+
+    /**
+     * Returns the singleton instance on deserialization.
+     */
+    final Object readResolve() throws ObjectStreamException {
+        if (sourceClass == InternationalString.class) return I18N;
+        if (sourceClass == Number .class) return NUMBER;
+        if (sourceClass == Boolean.class) return BOOLEAN;
+        if (sourceClass == File   .class) return FILE;
+        if (sourceClass == URI    .class) return URI;
+        if (sourceClass == URL    .class) return URL;
+        if (sourceClass == Locale .class) return LOCALE;
+        if (sourceClass == java.nio.charset.Charset.class) return CHARSET;
+        return this;
+    }
+
+
+    /**
+     * Specialized instance for {@link java.nio.charset.Charset}.
+     * This class invokes {@java.nio.charset.Charset#name()} instead than {@code toString()}.
+     */
+    private static final class Charset extends ObjectToString<java.nio.charset.Charset> {
+        private static final long serialVersionUID = 1313285261794842777L;
+
+        Charset() {
+            super(java.nio.charset.Charset.class, StringConverter.Charset.INSTANCE);
+        }
+
+        @Override
+        public String convert(final java.nio.charset.Charset source) {
+            return (source != null) ? source.name() : null;
+        }
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -72,6 +72,15 @@ abstract class StringConverter<T> extend
     }
 
     /**
+     * While this is not a general rule for surjective functions,
+     * all converters defined in this class are invertibles.
+     */
+    @Override
+    public Set<FunctionProperty> properties() {
+        return EnumSet.of(FunctionProperty.SURJECTIVE, FunctionProperty.INVERTIBLE);
+    }
+
+    /**
      * Converts the given string to the target type of this converter.
      * This method verifies that the given string is non-null and non-empty,
      * then delegates to {@link #doConvert(String)}.
@@ -124,6 +133,11 @@ abstract class StringConverter<T> extend
             return Numbers.narrowestNumber(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.lang.Number, String> inverse() {
+            return ObjectToString.NUMBER;
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -147,6 +161,11 @@ abstract class StringConverter<T> extend
             return java.lang.Double.parseDouble(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.lang.Double, String> inverse() {
+            return new ObjectToString<>(java.lang.Double.class, this);
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -170,6 +189,11 @@ abstract class StringConverter<T> extend
             return java.lang.Float.parseFloat(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.lang.Float, String> inverse() {
+            return new ObjectToString<>(java.lang.Float.class, this);
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -193,6 +217,11 @@ abstract class StringConverter<T> extend
             return java.lang.Long.parseLong(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.lang.Long, String> inverse() {
+            return new ObjectToString<>(java.lang.Long.class, this);
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -216,6 +245,11 @@ abstract class StringConverter<T> extend
             return java.lang.Integer.parseInt(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.lang.Integer, String> inverse() {
+            return new ObjectToString<>(java.lang.Integer.class, this);
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -239,6 +273,11 @@ abstract class StringConverter<T> extend
             return java.lang.Short.parseShort(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.lang.Short, String> inverse() {
+            return new ObjectToString<>(java.lang.Short.class, this);
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -262,6 +301,11 @@ abstract class StringConverter<T> extend
             return java.lang.Byte.parseByte(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.lang.Byte, String> inverse() {
+            return new ObjectToString<>(java.lang.Byte.class, this);
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -285,6 +329,11 @@ abstract class StringConverter<T> extend
             return new java.math.BigDecimal(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.math.BigDecimal, String> inverse() {
+            return new ObjectToString<>(java.math.BigDecimal.class, this);
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -308,6 +357,11 @@ abstract class StringConverter<T> extend
             return new java.math.BigInteger(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.math.BigInteger, String> inverse() {
+            return new ObjectToString<>(java.math.BigInteger.class, this);
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -340,15 +394,19 @@ abstract class StringConverter<T> extend
             return java.lang.Boolean.class;
         }
 
-        @Override java.lang.Boolean doConvert(String source) throws UnconvertibleObjectException {
-            source = source.toLowerCase(java.util.Locale.ROOT);
-            switch (source) {
+        @Override java.lang.Boolean doConvert(final String source) throws UnconvertibleObjectException {
+            switch (source.toLowerCase(java.util.Locale.ROOT)) {
                 case "true":  case "yes": case "on":  case "1": return java.lang.Boolean.TRUE;
                 case "false": case "no":  case "off": case "0": return java.lang.Boolean.FALSE;
             }
             throw new UnconvertibleObjectException(formatErrorMessage(source));
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.lang.Boolean, String> inverse() {
+            return ObjectToString.BOOLEAN;
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -373,6 +431,11 @@ abstract class StringConverter<T> extend
             return Locales.parse(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.util.Locale, String> inverse() {
+            return ObjectToString.LOCALE;
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -396,6 +459,11 @@ abstract class StringConverter<T> extend
             return java.nio.charset.Charset.forName(source);
         }
 
+        /** Returns the inverse, since this converter is "almost" bijective. */
+        @Override public ObjectConverter<java.nio.charset.Charset, String> inverse() {
+            return ObjectToString.CHARSET;
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -413,7 +481,8 @@ abstract class StringConverter<T> extend
 
         /** Returns the function properties, which is bijective. */
         @Override public Set<FunctionProperty> properties() {
-            return EnumSet.of(FunctionProperty.INJECTIVE, FunctionProperty.SURJECTIVE, FunctionProperty.ORDER_PRESERVING);
+            return EnumSet.of(FunctionProperty.INJECTIVE, FunctionProperty.SURJECTIVE,
+                    FunctionProperty.ORDER_PRESERVING, FunctionProperty.INVERTIBLE);
         }
 
         @Override public Class<org.opengis.util.InternationalString> getTargetClass() {
@@ -424,6 +493,10 @@ abstract class StringConverter<T> extend
             return new SimpleInternationalString(source);
         }
 
+        @Override public ObjectConverter<org.opengis.util.InternationalString, String> inverse() {
+            return ObjectToString.I18N;
+        }
+
         /** Returns the singleton instance on deserialization. */
         Object readResolve() throws ObjectStreamException {
             return INSTANCE;
@@ -451,7 +524,7 @@ abstract class StringConverter<T> extend
 
         /** Returns the inverse, since this converter is "almost" bijective. */
         @Override public ObjectConverter<java.io.File, String> inverse() {
-            return FileConverter.String.INSTANCE;
+            return ObjectToString.FILE;
         }
 
         /** Returns the singleton instance on deserialization. */
@@ -502,7 +575,7 @@ abstract class StringConverter<T> extend
 
         /** Returns the inverse, since this converter is "almost" bijective. */
         @Override public ObjectConverter<java.net.URI, String> inverse() {
-            return URIConverter.String.INSTANCE;
+            return ObjectToString.URI;
         }
 
         /** Returns the singleton instance on deserialization. */
@@ -530,7 +603,7 @@ abstract class StringConverter<T> extend
 
         /** Returns the inverse, since this converter is "almost" bijective. */
         @Override public ObjectConverter<java.net.URL, String> inverse() {
-            return URLConverter.String.INSTANCE;
+            return ObjectToString.URL;
         }
 
         /** Returns the singleton instance on deserialization. */

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URIConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URIConverter.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URIConverter.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URIConverter.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -55,38 +55,6 @@ abstract class URIConverter<T> extends I
     }
 
     /**
-     * Converter from {@link URI} to {@link java.lang.String}.
-     * This converter does not encode the string, i.e. the conversion is performed with
-     * the {@link URI#toString()} method rather than {@link URI#toASCIIString()}. We do
-     * that in order to avoid too many transformations if we convert back and forward to
-     * {@code String}.
-     */
-    @Immutable
-    static final class String extends URIConverter<java.lang.String> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = -1745990349642467147L;
-        /** The unique, shared instance. */ static final String INSTANCE = new String();
-        /** For {@link #INSTANCE} only.  */ private String() {}
-
-        @Override public Class<java.lang.String> getTargetClass() {
-            return java.lang.String.class;
-        }
-
-        @Override public java.lang.String convert(final URI source) {
-            return (source != null) ? source.toString() : null;
-        }
-
-        /** Returns the inverse, since this converter is "almost" bijective. */
-        @Override public ObjectConverter<java.lang.String, URI> inverse() {
-            return StringConverter.URI.INSTANCE;
-        }
-
-        /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
-            return INSTANCE;
-        }
-    }
-
-    /**
      * Converter from {@link URI} to {@link java.io.File}.
      */
     @Immutable

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URLConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URLConverter.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URLConverter.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/URLConverter.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -55,36 +55,6 @@ abstract class URLConverter<T> extends I
     }
 
     /**
-     * Converter from {@link URL} to {@link java.lang.String}.
-     * This converter does not encode the string. We do that in order to avoid too many
-     * transformations if we convert back and forward to {@code String}.
-     */
-    @Immutable
-    static final class String extends URLConverter<java.lang.String> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 8091677760312351740L;
-        /** The unique, shared instance. */ static final String INSTANCE = new String();
-        /** For {@link #INSTANCE} only.  */ private String() {}
-
-        @Override public Class<java.lang.String> getTargetClass() {
-            return java.lang.String.class;
-        }
-
-        @Override public java.lang.String convert(final URL source) {
-            return (source != null) ? source.toExternalForm() : null;
-        }
-
-        /** Returns the inverse, since this converter is "almost" bijective. */
-        @Override public ObjectConverter<java.lang.String, URL> inverse() {
-            return StringConverter.URL.INSTANCE;
-        }
-
-        /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
-            return INSTANCE;
-        }
-    }
-
-    /**
      * Converter from {@link URL} to {@link java.io.File}.
      */
     @Immutable

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -47,6 +47,7 @@ final class DefaultFormat extends Format
 
     /**
      * The array for storing singleton instances for types {@code byte} to {@code double}.
+     * The value at index 0 is reserved for the generic {@link Number} type.
      */
     private static final Format[] INSTANCES = new Format[Numbers.DOUBLE - Numbers.BYTE + 2];
 

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=1455255&r1=1455254&r2=1455255&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] Mon Mar 11 17:48:03 2013
@@ -46,8 +46,8 @@ public final class Numbers extends Stati
      * Constant of value {@value} used in {@code switch} statements or as index in arrays.
      */
     public static final byte
+            BIG_DECIMAL=10, BIG_INTEGER=9,
             DOUBLE=8, FLOAT=7, LONG=6, INTEGER=5, SHORT=4, BYTE=3, CHARACTER=2, BOOLEAN=1, OTHER=0;
-    // Note: This class assumes that DOUBLE is the greatest public constant.
 
     /**
      * Mapping between a primitive type and its wrapper, if any.
@@ -62,8 +62,8 @@ public final class Numbers extends Stati
      */
     private static final Map<Class<?>,Numbers> MAPPING = new IdentityHashMap<>(16);
     static {
-        new Numbers(BigDecimal.class, true, false, (byte) (DOUBLE+2)); // Undocumented enum.
-        new Numbers(BigInteger.class, false, true, (byte) (DOUBLE+1)); // Undocumented enum.
+        new Numbers(BigDecimal.class, true, false, BIG_DECIMAL);
+        new Numbers(BigInteger.class, false, true, BIG_INTEGER);
         new Numbers(Double   .TYPE, Double   .class, true,  false, (byte) Double   .SIZE, DOUBLE,    'D', Double   .valueOf(Double.NaN));
         new Numbers(Float    .TYPE, Float    .class, true,  false, (byte) Float    .SIZE, FLOAT,     'F', Float    .valueOf(Float .NaN));
         new Numbers(Long     .TYPE, Long     .class, false, true,  (byte) Long     .SIZE, LONG,      'J', Long     .valueOf(        0L));
@@ -304,7 +304,7 @@ public final class Numbers extends Stati
             throws IllegalArgumentException
     {
         return narrowestClass((n1 != null) ? n1.getClass() : null,
-                           (n2 != null) ? n2.getClass() : null);
+                              (n2 != null) ? n2.getClass() : null);
     }
 
     /**
@@ -708,8 +708,10 @@ public final class Numbers extends Stati
     }
 
     /**
-     * Returns one of {@link #DOUBLE}, {@link #FLOAT}, {@link #LONG}, {@link #INTEGER},
-     * {@link #SHORT}, {@link #BYTE}, {@link #CHARACTER}, {@link #BOOLEAN} or {@link #OTHER}
+     * Returns a numeric constant for the given type.
+     * The constants are {@link #BIG_DECIMAL}, {@link #BIG_INTEGER},
+     * {@link #DOUBLE}, {@link #FLOAT}, {@link #LONG}, {@link #INTEGER},
+     * {@link #SHORT}, {@link #BYTE}, {@link #CHARACTER}, {@link #BOOLEAN}, or {@link #OTHER}
      * constants for the given type. This is a commodity for usage in {@code switch} statements.
      *
      * @param type A type (usually either a primitive type or its wrapper).
@@ -717,13 +719,7 @@ public final class Numbers extends Stati
      */
     public static byte getEnumConstant(final Class<?> type) {
         final Numbers mapping = MAPPING.get(type);
-        if (mapping != null) {
-            // Filter out the non-public enum for BigDecimal and BigInteger.
-            if (mapping.size >= 0) {
-                return mapping.ordinal;
-            }
-        }
-        return OTHER;
+        return (mapping != null) ? mapping.ordinal : OTHER;
     }
 
     /**

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FallbackConverterTest.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -38,11 +38,9 @@ public final strictfp class FallbackConv
     /**
      * Tests a chain of fallback converters. The initial fallback will understand {@link Short}
      * and {@link Long} types. Later we will add other types like {@link Boolean} and {@link Float}.
-     *
-     * @throws UnconvertibleObjectException Should never happen.
      */
     @Test
-    public void testChain() throws UnconvertibleObjectException {
+    public void testChain() {
         @SuppressWarnings({"unchecked","rawtypes"}) // Generic array creation.
         final ObjectConverter<String,?>[] converters = new ObjectConverter[] {
             StringConverter.Short  .INSTANCE,

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FileConverterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FileConverterTest.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FileConverterTest.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/FileConverterTest.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -21,6 +21,7 @@ import java.net.URI;
 import java.net.URL;
 import java.net.URISyntaxException;
 import java.net.MalformedURLException;
+import org.apache.sis.math.FunctionProperty;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
@@ -51,53 +52,54 @@ public final strictfp class FileConverte
     }
 
     /**
+     * Asserts that conversion of the given {@code source} value produces
+     * the given {@code target} value, and tests the inverse conversion.
+     */
+    private static <T> void runInvertibleConversion(final ObjectConverter<File,T> c,
+            final File 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 string values.
-     *
-     * @throws UnconvertibleObjectException Should never happen.
      */
     @Test
-    public void testString() throws UnconvertibleObjectException {
-        final File   source = new File("home/user/index.txt");
-        final String target = "home/user/index.txt".replace("/", File.separator);
-        final ObjectConverter<File,String> c = FileConverter.String.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+    public void testString() {
+        final ObjectConverter<File,String> c = ObjectToString.FILE;
+        runInvertibleConversion(c, new File("home/user/index.txt"), "home/user/index.txt".replace("/", File.separator));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 
     /**
      * Tests conversions to URI values.
      *
-     * @throws UnconvertibleObjectException Should never happen.
      * @throws URISyntaxException Should never happen.
      */
     @Test
     @PlatformDependentTest
-    public void testURI() throws UnconvertibleObjectException, URISyntaxException {
+    public void testURI() throws URISyntaxException {
         assumeUnixRoot();
-        final File source = new File("/home/user/index.txt");
-        final URI  target = new URI("file:/home/user/index.txt");
         final ObjectConverter<File,URI> c = FileConverter.URI.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+        runInvertibleConversion(c, new File("/home/user/index.txt"), new URI("file:/home/user/index.txt"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 
     /**
      * Tests conversions to URL values.
      *
-     * @throws UnconvertibleObjectException Should never happen.
      * @throws MalformedURLException Should never happen.
      */
     @Test
     @PlatformDependentTest
-    public void testURL() throws UnconvertibleObjectException, MalformedURLException {
+    public void testURL() throws MalformedURLException {
         assumeUnixRoot();
-        final File source = new File("/home/user/index.txt");
-        final URL  target = new URL("file:/home/user/index.txt");
         final ObjectConverter<File,URL> c = FileConverter.URL.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+        runInvertibleConversion(c, new File("/home/user/index.txt"), new URL("file:/home/user/index.txt"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 }

Added: 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=1455255&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java (added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -0,0 +1,260 @@
+/*
+ * 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.Locale;
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URL;
+import java.net.URISyntaxException;
+import java.net.MalformedURLException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import org.opengis.util.InternationalString;
+import org.apache.sis.math.FunctionProperty;
+import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.util.UnconvertibleObjectException;
+import org.apache.sis.util.iso.SimpleInternationalString;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assert.*;
+
+
+/**
+ * Tests the various {@link StringConverter} implementations.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3 (derived from geotk-2.4)
+ * @version 0.3
+ * @module
+ */
+public final strictfp class StringConverterTest {
+    /**
+     * Asserts that conversion of the given {@code source} value produces
+     * the given {@code target} value, and tests the inverse conversion.
+     */
+    private static <T> void runInvertibleConversion(final ObjectConverter<String,T> c,
+            final String 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));
+    }
+
+    /**
+     * Tries to convert an unconvertible value.
+     */
+    private static void tryUnconvertibleValue(final ObjectConverter<String,?> c) {
+        try {
+            c.convert("Saturday");
+            fail("Should not accept a text.");
+        } catch (UnconvertibleObjectException e) {
+            // This is the expected exception.
+            assertTrue(e.getMessage().contains("Saturday"));
+        }
+    }
+
+    /**
+     * Tests conversions to {@link Number}.
+     */
+    @Test
+    public void testNumber() {
+        final ObjectConverter<String,Number> c = StringConverter.Number.INSTANCE;
+        runInvertibleConversion(c,    "-4", Byte   .valueOf((byte)   -4));
+        runInvertibleConversion(c,   "128", Short  .valueOf((short) 128));
+        runInvertibleConversion(c, "40000", Integer.valueOf(      40000));
+        runInvertibleConversion(c,   "4.5", Float  .valueOf(       4.5f));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link Double}.
+     */
+    @Test
+    public void testDouble() {
+        final ObjectConverter<String,Double> c = StringConverter.Double.INSTANCE;
+        runInvertibleConversion(c, "4.5", Double.valueOf(4.5));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link Float}.
+     */
+    @Test
+    public void testFloat() {
+        final ObjectConverter<String,Float> c = StringConverter.Float.INSTANCE;
+        runInvertibleConversion(c, "4.5", Float.valueOf(4.5f));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link Long}.
+     */
+    @Test
+    public void testLong() {
+        final ObjectConverter<String,Long> c = StringConverter.Long.INSTANCE;
+        runInvertibleConversion(c, "45000", Long.valueOf(45000));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link Integer}.
+     */
+    @Test
+    public void testInteger() {
+        final ObjectConverter<String,Integer> c = StringConverter.Integer.INSTANCE;
+        runInvertibleConversion(c, "45000", Integer.valueOf(45000));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link Short}.
+     */
+    @Test
+    public void testShort() {
+        final ObjectConverter<String,Short> c = StringConverter.Short.INSTANCE;
+        runInvertibleConversion(c, "4500", Short.valueOf((short) 4500));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link Byte}.
+     */
+    @Test
+    public void testByte() {
+        final ObjectConverter<String,Byte> c = StringConverter.Byte.INSTANCE;
+        runInvertibleConversion(c, "45", Byte.valueOf((byte) 45));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link BigDecimal}.
+     */
+    @Test
+    public void testBigDecimal() {
+        final ObjectConverter<String,BigDecimal> c = StringConverter.BigDecimal.INSTANCE;
+        runInvertibleConversion(c, "45000.5", BigDecimal.valueOf(45000.5));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link BigInteger}.
+     */
+    @Test
+    public void testBigInteger() {
+        final ObjectConverter<String,BigInteger> c = StringConverter.BigInteger.INSTANCE;
+        runInvertibleConversion(c, "45000", BigInteger.valueOf(45000));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to boolean values.
+     */
+    @Test
+    public void testBoolean() {
+        final ObjectConverter<String,Boolean> c = StringConverter.Boolean.INSTANCE;
+        runInvertibleConversion(c, "true",  Boolean.TRUE);
+        runInvertibleConversion(c, "false", Boolean.FALSE);
+        assertEquals(Boolean.TRUE,  c.convert("yes"));
+        assertEquals(Boolean.FALSE, c.convert("no"));
+        assertEquals(Boolean.TRUE,  c.convert("ON"));  // Test upper-case.
+        assertEquals(Boolean.FALSE, c.convert("OFF"));
+        assertEquals(Boolean.TRUE,  c.convert("1"));
+        assertEquals(Boolean.FALSE, c.convert("0"));
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link Locale}.
+     */
+    @Test
+    public void testLocale() {
+        final ObjectConverter<String,Locale> c = StringConverter.Locale.INSTANCE;
+        runInvertibleConversion(c, "fr_CA", Locale.CANADA_FRENCH);
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link Charset}.
+     */
+    @Test
+    public void testCharset() {
+        final ObjectConverter<String,Charset> c = StringConverter.Charset.INSTANCE;
+        runInvertibleConversion(c, "UTF-8", StandardCharsets.UTF_8);
+        tryUnconvertibleValue(c);
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link InternationalString}.
+     */
+    @Test
+    public void testInternationalString() {
+        final ObjectConverter<String,InternationalString> c = StringConverter.InternationalString.INSTANCE;
+        runInvertibleConversion(c, "Some sentence", new SimpleInternationalString("Some sentence"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link File}.
+     */
+    @Test
+    public void testFile() {
+        final ObjectConverter<String,File> c = StringConverter.File.INSTANCE;
+        runInvertibleConversion(c, "home/user/index.txt", new File("home/user/index.txt"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link URI}.
+     *
+     * @throws URISyntaxException Should never happen.
+     */
+    @Test
+    public void testURI() throws URISyntaxException {
+        final ObjectConverter<String,URI> c = StringConverter.URI.INSTANCE;
+        runInvertibleConversion(c, "file:/home/user/index.txt", new URI("file:/home/user/index.txt"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+    }
+
+    /**
+     * Tests conversions to {@link URI}.
+     *
+     * @throws MalformedURLException Should never happen.
+     */
+    @Test
+    public void testURL() throws MalformedURLException  {
+        final ObjectConverter<String,URL> c = StringConverter.URL.INSTANCE;
+        runInvertibleConversion(c, "file:/home/user/index.txt", new URL("file:/home/user/index.txt"));
+        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/StringConverterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/StringConverterTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URIConverterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URIConverterTest.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URIConverterTest.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URIConverterTest.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -21,6 +21,7 @@ import java.net.URI;
 import java.net.URL;
 import java.net.URISyntaxException;
 import java.net.MalformedURLException;
+import org.apache.sis.math.FunctionProperty;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
 import org.apache.sis.test.PlatformDependentTest;
@@ -40,53 +41,55 @@ import static org.apache.sis.test.Assert
  */
 public final strictfp class URIConverterTest extends TestCase {
     /**
+     * Asserts that conversion of the given {@code source} value produces
+     * the given {@code target} value, and tests the inverse conversion.
+     */
+    private static <T> void runInvertibleConversion(final ObjectConverter<URI,T> c,
+            final URI 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 string values.
      *
-     * @throws UnconvertibleObjectException Should never happen.
      * @throws URISyntaxException Should never happen.
      */
     @Test
-    public void testString() throws UnconvertibleObjectException, URISyntaxException {
-        final URI    source = new URI("file:/home/user/index.txt");
-        final String target = "file:/home/user/index.txt";
-        final ObjectConverter<URI,String> c = URIConverter.String.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+    public void testString() throws URISyntaxException {
+        final ObjectConverter<URI,String> c = ObjectToString.URI;
+        runInvertibleConversion(c, new URI("file:/home/user/index.txt"), "file:/home/user/index.txt");
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 
     /**
      * Tests conversions to URL values.
      *
-     * @throws UnconvertibleObjectException Should never happen.
      * @throws MalformedURLException Should never happen.
      * @throws URISyntaxException Should never happen.
      */
     @Test
-    public void testURL() throws UnconvertibleObjectException, MalformedURLException, URISyntaxException {
-        final URI source = new URI("file:/home/user/index.txt");
-        final URL target = new URL("file:/home/user/index.txt");
+    public void testURL() throws MalformedURLException, URISyntaxException {
         final ObjectConverter<URI,URL> c = URIConverter.URL.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+        runInvertibleConversion(c, new URI("file:/home/user/index.txt"), new URL("file:/home/user/index.txt"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 
     /**
      * Tests conversions to File values.
      *
-     * @throws UnconvertibleObjectException Should never happen.
      * @throws URISyntaxException Should never happen.
      */
     @Test
     @PlatformDependentTest
-    public void testFile() throws UnconvertibleObjectException, URISyntaxException {
+    public void testFile() throws URISyntaxException {
         FileConverterTest.assumeUnixRoot();
-        final URI  source = new URI("file:/home/user/index.txt");
-        final File target = new File("/home/user/index.txt");
         final ObjectConverter<URI,File> c = URIConverter.File.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+        runInvertibleConversion(c, new URI("file:/home/user/index.txt"), new File("/home/user/index.txt"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 }

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URLConverterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URLConverterTest.java?rev=1455255&r1=1455254&r2=1455255&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URLConverterTest.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/URLConverterTest.java [UTF-8] Mon Mar 11 17:48:03 2013
@@ -21,6 +21,7 @@ import java.net.URI;
 import java.net.URL;
 import java.net.URISyntaxException;
 import java.net.MalformedURLException;
+import org.apache.sis.math.FunctionProperty;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
 import org.apache.sis.test.PlatformDependentTest;
@@ -40,53 +41,55 @@ import static org.apache.sis.test.Assert
  */
 public final strictfp class URLConverterTest extends TestCase {
     /**
+     * Asserts that conversion of the given {@code source} value produces
+     * the given {@code target} value, and tests the inverse conversion.
+     */
+    private static <T> void runInvertibleConversion(final ObjectConverter<URL,T> c,
+            final URL 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 string values.
      *
-     * @throws UnconvertibleObjectException Should never happen.
      * @throws MalformedURLException Should never happen.
      */
     @Test
-    public void testString() throws UnconvertibleObjectException, MalformedURLException {
-        final URL    source = new URL("file:/home/user/index.txt");
-        final String target = "file:/home/user/index.txt";
-        final ObjectConverter<URL,String> c = URLConverter.String.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+    public void testString() throws MalformedURLException {
+        final ObjectConverter<URL,String> c = ObjectToString.URL;
+        runInvertibleConversion(c, new URL("file:/home/user/index.txt"), "file:/home/user/index.txt");
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 
     /**
      * Tests conversions to URI values.
      *
-     * @throws UnconvertibleObjectException Should never happen.
      * @throws MalformedURLException Should never happen.
      * @throws URISyntaxException Should never happen.
      */
     @Test
-    public void testURI() throws UnconvertibleObjectException, MalformedURLException, URISyntaxException {
-        final URL source = new URL("file:/home/user/index.txt");
-        final URI target = new URI("file:/home/user/index.txt");
+    public void testURI() throws MalformedURLException, URISyntaxException {
         final ObjectConverter<URL,URI> c = URLConverter.URI.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+        runInvertibleConversion(c, new URL("file:/home/user/index.txt"), new URI("file:/home/user/index.txt"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 
     /**
      * Tests conversions to File values.
      *
-     * @throws UnconvertibleObjectException Should never happen.
      * @throws MalformedURLException Should never happen.
      */
     @Test
     @PlatformDependentTest
-    public void testFile() throws UnconvertibleObjectException, MalformedURLException {
+    public void testFile() throws MalformedURLException {
         FileConverterTest.assumeUnixRoot();
-        final URL  source = new URL("file:/home/user/index.txt");
-        final File target = new File("/home/user/index.txt");
         final ObjectConverter<URL,File> c = URLConverter.File.INSTANCE;
-        assertEquals("Forward conversion", target, c.convert(source));
-        assertEquals("Inverse conversion", source, c.inverse().convert(target));
-        assertSame(c, assertSerializedEquals(c));
+        runInvertibleConversion(c, new URL("file:/home/user/index.txt"), new File("/home/user/index.txt"));
+        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
     }
 }

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=1455255&r1=1455254&r2=1455255&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] Mon Mar 11 17:48:03 2013
@@ -94,6 +94,7 @@ import org.junit.runners.Suite;
     org.apache.sis.internal.converter.URIConverterTest.class,
     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.FallbackConverterTest.class,
 
     // XML most basic types.



Mime
View raw message