sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1457553 [1/2] - in /sis/branches/JDK7: ide-project/NetBeans/ sis-utility/src/main/java/org/apache/sis/internal/converter/ sis-utility/src/main/java/org/apache/sis/util/ sis-utility/src/main/resources/META-INF/ sis-utility/src/main/resource...
Date Sun, 17 Mar 2013 20:29:10 GMT
Author: desruisseaux
Date: Sun Mar 17 20:29:09 2013
New Revision: 1457553

URL: http://svn.apache.org/r1457553
Log:
Replaced the hard-coded 'getInstance(...)' methods by a registration mechanism based on META-INF/services/.
This will be needed anyway for allowing other modules like sis-metadata to define their own converters.

Added:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java
      - copied, changed from r1457163, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/HeuristicRegistry.java
    sis/branches/JDK7/sis-utility/src/main/resources/META-INF/
    sis/branches/JDK7/sis-utility/src/main/resources/META-INF/services/
    sis/branches/JDK7/sis-utility/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter   (with props)
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/SystemRegistryTest.java
      - copied, changed from r1457163, sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/HeuristicRegistryTest.java
Removed:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/HeuristicRegistry.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/HeuristicRegistryTest.java
Modified:
    sis/branches/JDK7/ide-project/NetBeans/build.xml
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.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/PathConverter.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/SystemConverter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/package-info.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Classes.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/ConverterRegistryTest.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/NumberConverterTest.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.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/ide-project/NetBeans/build.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/build.xml?rev=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/build.xml (original)
+++ sis/branches/JDK7/ide-project/NetBeans/build.xml Sun Mar 17 20:29:09 2013
@@ -19,9 +19,10 @@
     </copy>
 
     <!-- Following are classical properties resources files. -->
-    <copy todir="${build.classes.dir}/org/apache/sis/internal/util">
-      <fileset dir="${project.root}/sis-utility/src/main/resources/org/apache/sis/internal/util">
-        <include name="*.properties"/>
+    <copy todir="${build.classes.dir}">
+      <fileset dir="${project.root}/sis-utility/src/main/resources">
+        <include name="META-INF/services/*"/>
+        <include name="**/*.properties"/>
       </fileset>
     </copy>
   </target>

Modified: 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=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -37,7 +37,7 @@ import org.apache.sis.util.resources.Err
  *
  * <p>New instances of {@code ConverterRegistry} are initially empty. Custom converters must be
  * explicitly {@linkplain #register(ObjectConverter) registered}. However a system-wide registry
- * initialized with default converters is provided by the {@link HeuristicRegistry#SYSTEM} constant.</p>
+ * initialized with default converters is provided by the {@link SystemRegistry#INSTANCE} constant.</p>
  *
  * {@section Note about conversions from interfaces}
  * {@code ConverterRegistry} is primarily designed for handling converters from classes to
@@ -72,6 +72,13 @@ public class ConverterRegistry {
     private final Map<ClassPair<?,?>, ObjectConverter<?,?>> converters;
 
     /**
+     * {@code true} if this {@code ConverterRegistry} has been initialized.
+     *
+     * @see #initialize()
+     */
+    private boolean isInitialized;
+
+    /**
      * Creates an initially empty set of object converters.
      */
     public ConverterRegistry() {
@@ -79,11 +86,34 @@ public class ConverterRegistry {
     }
 
     /**
-     * Removes all converters from this registry.
+     * Invoked when this {@code ConverterRegistry} needs to be initialized. This method
+     * is automatically invoked the first time that {@link #register(ObjectConverter)}
+     * or {@link #find(Class, Class)} is invoked.
+     *
+     * <p>The default implementation does nothing. Subclasses can override this method
+     * in order to register a default set of converters. For example a subclass could
+     * fetch the {@code ObjectConverter} instances from the {@code META-INF/services}
+     * directories as below:</p>
+     *
+     * {@preformat java
+     *     ClassLoader loader = getClass().getClassLoader();
+     *     for (ObjectConverter<?,?> converter : ServiceLoader.load(ObjectConverter.class, loader)) {
+     *         register(converter);
+     *     }
+     * }
+     */
+    protected void initialize() {
+    }
+
+    /**
+     * Removes all converters from this registry and set this {@code ServiceRegistry}
+     * state to <cite>uninitialized</cite>. The {@link #initialize()} method will be
+     * invoked again when first needed.
      */
     public void clear() {
         synchronized (converters) {
             converters.clear();
+            isInitialized = false;
         }
     }
 
@@ -232,12 +262,20 @@ public class ConverterRegistry {
         ArgumentChecks.ensureNonNull("sourceClass", sourceClass);
         ArgumentChecks.ensureNonNull("targetClass", targetClass);
         synchronized (converters) {
+            /*
+             * If this registry has not yet been initialized, initializes it before we search
+             * for the place where to put the given converter in the hierarchy of converters.
+             */
+            if (!isInitialized) {
+                isInitialized = true; // Before 'initialize()' for preventing infinite recursivity.
+                initialize();
+            }
             for (Class<? super T> i=targetClass; i!=null && i!=stopAt; i=i.getSuperclass()) {
                 register(new ClassPair<>(sourceClass, i), converter);
             }
             /*
-             * At this point, the given class and parent classes
-             * have been registered. Now registers interfaces.
+             * At this point, the given class and parent classes have been registered.
+             * Now registers interfaces, except for the special cases coded below.
              */
             for (final Class<? super T> i : Classes.getAllInterfaces(targetClass)) {
                 if (i.isAssignableFrom(sourceClass)) {
@@ -267,6 +305,15 @@ public class ConverterRegistry {
                      */
                     continue;
                 }
+                if (sourceClass == String.class && Iterable.class.isAssignableFrom(targetClass)) {
+                    /*
+                     * Exclude the case of String to Iterables (including collections), because
+                     * there is too many ways to perform such conversion. For example we do not
+                     * want find(String, Iterable) to select a conversion to java.nio.file.Path
+                     * (which implements Iterable).
+                     */
+                    continue;
+                }
                 if (!i.isAssignableFrom(sourceClass)) {
                     register(new ClassPair<>(sourceClass, i), converter);
                 }
@@ -396,6 +443,19 @@ public class ConverterRegistry {
                 return converter;
             }
             /*
+             * If the user is invoking this method for the firt time, regiter the converers
+             * declared in all "META-INF/services/org.apache.sis.util.ObjectConverter" files
+             * found on the classpath and try again.
+             */
+            if (!isInitialized) {
+                isInitialized = true; // Before 'initialize()' for preventing infinite recursivity.
+                initialize();
+                converter = get(key);
+                if (converter != null) {
+                    return converter;
+                }
+            }
+            /*
              * At this point, no converter were found explicitly for the given key. Searches a
              * converter accepting some super-class of S, and if we find any cache the result.
              * This is the complement of the search performed in the register(ObjectConverter)

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.java?rev=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -48,52 +48,16 @@ abstract class DateConverter<T> extends 
     private static final long serialVersionUID = -7770401534710581917L;
 
     /**
-     * The inverse converter specified at construction time.
+     * The inverse converter. Must be initialized by subclass constructors.
      */
-    private final SystemConverter<T, Date> inverse;
+    SystemConverter<T, Date> inverse;
 
     /**
-     * Creates a converter with an inverse which is the identity converter.
+     * Creates a converter for the given target type.
+     * Subclasses must initialize {@link #inverse}.
      */
-    @SuppressWarnings("unchecked")
     DateConverter(final Class<T> targetClass) {
         super(Date.class, targetClass);
-        assert Date.class.isAssignableFrom(targetClass);
-        inverse = new IdentityConverter(targetClass, Date.class, this);
-    }
-
-    /**
-     * Creates a converter with the given inverse converter.
-     */
-    DateConverter(final Class<T> targetClass, final SystemConverter<T, Date> inverse) {
-        super(Date.class, targetClass);
-        this.inverse = inverse;
-    }
-
-    /**
-     * Returns a predefined instance for the given target class, or {@code null} if none.
-     * This method does not create any new instance.
-     *
-     * @param  <T> The target class.
-     * @param  targetClass The target class.
-     * @return An instance for the given target class, or {@code null} if none.
-     */
-    @SuppressWarnings({"unchecked","rawtypes"})
-    static <T> DateConverter<T> getInstance(final Class<T> targetClass) {
-        if (targetClass == java.lang.Long    .class) return (DateConverter<T>) Long     .INSTANCE;
-        if (targetClass == java.sql.Date     .class) return (DateConverter<T>) SQL      .INSTANCE;
-        if (targetClass == java.sql.Timestamp.class) return (DateConverter<T>) Timestamp.INSTANCE;
-        return null;
-    }
-
-    /**
-     * Returns the singleton instance on deserialization, if any.
-     */
-    @Override
-    public final ObjectConverter<Date, T> unique() {
-        assert sourceClass == Date.class : sourceClass;
-        final DateConverter<T> instance = getInstance(targetClass);
-        return (instance != null) ? instance : this;
     }
 
     /**
@@ -106,7 +70,7 @@ abstract class DateConverter<T> extends 
     }
 
     /**
-     * Returns the inverse given at construction time.
+     * Returns the inverse converter.
      */
     @Override
     public final ObjectConverter<T, Date> inverse() {
@@ -115,21 +79,31 @@ abstract class DateConverter<T> extends 
 
     /**
      * Converter from {@code Long} to {@code Date}.
-     * This is the inverse of {@link org.apache.sis.internal.converter.DateConverter.Long}.
+     * This converter is <strong>not</strong> registered by {@link ConverterRegistry#initialize()}.
+     * Instead, {@link SystemRegistry} will fetch it when first needed by looking at the inverse
+     * of {@link DateConverter.Long}. The same is true for all inverse converters defined in the
+     * {@code DateConverter} enclosing class.
      */
     private static final class Inverse extends SystemConverter<java.lang.Long, java.util.Date> {
         private static final long serialVersionUID = 3999693055029959455L;
 
-        private Inverse() {
+        private final SystemConverter<java.util.Date, java.lang.Long> inverse;
+
+        Inverse(final SystemConverter<java.util.Date, java.lang.Long> inverse) {
             super(java.lang.Long.class, java.util.Date.class);
+            this.inverse = inverse;
         }
 
         @Override public ObjectConverter<java.util.Date, java.lang.Long> inverse() {
-            return DateConverter.Long.INSTANCE;
+            return inverse;
+        }
+
+        @Override public ObjectConverter<java.lang.Long, Date> unique() {
+            return inverse.inverse();
         }
 
         @Override public Set<FunctionProperty> properties() {
-            return DateConverter.Long.INSTANCE.properties();
+            return inverse.properties();
         }
 
         @Override public java.util.Date convert(final java.lang.Long target) {
@@ -139,14 +113,13 @@ abstract class DateConverter<T> extends 
 
     /**
      * Converter from {@code Date} to {@code Long}.
-     * This is the inverse of {@link org.apache.sis.internal.converter.DateConverter.Inverse}.
      */
-    private static final class Long extends DateConverter<java.lang.Long> {
+    public static final class Long extends DateConverter<java.lang.Long> {
         private static final long serialVersionUID = 3163928356094316134L;
-        static final Long INSTANCE = new Long();
 
-        private Long() {
-            super(java.lang.Long.class, new Inverse());
+        public Long() { // Instantiated by ServiceLoader.
+            super(java.lang.Long.class);
+            inverse = new Inverse(this);
         }
 
         @Override public Set<FunctionProperty> properties() {
@@ -163,12 +136,12 @@ abstract class DateConverter<T> extends 
      * From {@code Date} to SQL {@code Date}.
      * The inverse of this converter is the identity conversion.
      */
-    private static final class SQL extends DateConverter<java.sql.Date> {
+    public static final class SQL extends DateConverter<java.sql.Date> {
         private static final long serialVersionUID = -3644605344718636345L;
-        static final SQL INSTANCE = new SQL();
 
-        private SQL() {
+        public SQL() { // Instantiated by ServiceLoader.
             super(java.sql.Date.class);
+            inverse = new IdentityConverter<>(targetClass, Date.class, this);
         }
 
         @Override public java.sql.Date convert(final Date source) {
@@ -183,12 +156,12 @@ abstract class DateConverter<T> extends 
      * From {@code Date} to SQL {@code Timestamp}.
      * The inverse of this converter is the identity conversion.
      */
-    private static final class Timestamp extends DateConverter<java.sql.Timestamp> {
+    public static final class Timestamp extends DateConverter<java.sql.Timestamp> {
         private static final long serialVersionUID = 3798633184562706892L;
-        static final Timestamp INSTANCE = new Timestamp();
 
-        private Timestamp() {
+        public Timestamp() { // Instantiated by ServiceLoader.
             super(java.sql.Timestamp.class);
+            inverse = new IdentityConverter<>(targetClass, Date.class, this);
         }
 
         @Override public java.sql.Timestamp convert(final Date source) {

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=1457553&r1=1457552&r2=1457553&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] Sun Mar 17 20:29:09 2013
@@ -73,7 +73,7 @@ final class NumberConverter<S extends Nu
 
     /**
      * Returns the inverse converter, creating it when first needed.
-     * This method delegates to {@link HeuristicRegistry#SYSTEM} and caches the result.
+     * This method delegates to {@link SystemRegistry#INSTANCE} and caches the result.
      * We do not provide pre-defined constant for the various converter because there
      * is too many possibly combinations.
      */
@@ -83,7 +83,7 @@ final class NumberConverter<S extends Nu
         // The ConverterRegistry clas provides the required synchronization.
         ObjectConverter<T,S> candidate = inverse;
         if (candidate == null) try {
-            inverse = candidate = HeuristicRegistry.SYSTEM.findExact(targetClass, sourceClass);
+            inverse = candidate = SystemRegistry.INSTANCE.findExact(targetClass, sourceClass);
         } catch (UnconvertibleObjectException e) {
             throw new UnsupportedOperationException(Errors.format(Errors.Keys.NonInvertibleConversion), e);
         }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/PathConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/PathConverter.java?rev=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/PathConverter.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/PathConverter.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -52,38 +52,6 @@ abstract class PathConverter<S,T> extend
     }
 
     /**
-     * Returns a predefined instance for the given target class, or {@code null} if none.
-     * This method does not create any new instance.
-     *
-     * @param  <T> The target class.
-     * @param  targetClass The target class.
-     * @return An instance for the given target class, or {@code null} if none.
-     */
-    @SuppressWarnings({"unchecked","rawtypes"})
-    static <S,T> PathConverter<S,T> getInstance(final Class<S> sourceClass, final Class<T> targetClass) {
-        if (sourceClass == File.class) {
-            if (targetClass == URI.class) return (PathConverter<S,T>) FileURI.INSTANCE;
-            if (targetClass == URL.class) return (PathConverter<S,T>) FileURL.INSTANCE;
-        } else if (sourceClass == URL.class) {
-            if (targetClass == File.class) return (PathConverter<S,T>) URLFile.INSTANCE;
-            if (targetClass == URI .class) return (PathConverter<S,T>) URL_URI.INSTANCE;
-        } else if (sourceClass == URI.class) {
-            if (targetClass == File.class) return (PathConverter<S,T>) URIFile.INSTANCE;
-            if (targetClass == URL .class) return (PathConverter<S,T>) URI_URL.INSTANCE;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the singleton instance on deserialization, if any.
-     */
-    @Override
-    public final ObjectConverter<S, T> unique() {
-        final PathConverter<S,T> instance = getInstance(sourceClass, targetClass);
-        return (instance != null) ? instance : super.unique();
-    }
-
-    /**
      * Returns the properties of this converter.
      */
     @Override
@@ -126,11 +94,12 @@ abstract class PathConverter<S,T> extend
      * Converter from {@link File} to {@link URI}.
      * This converter changes relative paths to absolute paths.
      */
-    private static final class FileURI extends PathConverter<File,URI> {
+    public static final class FileURI extends PathConverter<File,URI> {
         private static final long serialVersionUID = 1032598133849975567L;
         static final FileURI INSTANCE = new FileURI();
-        private FileURI() {super(File.class, URI.class);}
+        public FileURI() {super(File.class, URI.class);} // Instantiated by ServiceLoader.
 
+        @Override public ObjectConverter<File,URI> unique()  {return INSTANCE;}
         @Override public ObjectConverter<URI,File> inverse() {return URIFile.INSTANCE;}
         @Override public URI doConvert(final File source) {
             return source.toURI();
@@ -140,11 +109,12 @@ abstract class PathConverter<S,T> extend
     /**
      * Converter from {@link File} to {@link URL}.
      */
-    private static final class FileURL extends PathConverter<File,URL> {
+    public static final class FileURL extends PathConverter<File,URL> {
         private static final long serialVersionUID = 621496099287330756L;
         static final FileURL INSTANCE = new FileURL();
-        private FileURL() {super(File.class, URL.class);}
+        public FileURL() {super(File.class, URL.class);} // Instantiated by ServiceLoader.
 
+        @Override public ObjectConverter<File,URL> unique()  {return INSTANCE;}
         @Override public ObjectConverter<URL,File> inverse() {return URLFile.INSTANCE;}
         @Override public URL doConvert(final File source) throws MalformedURLException {
             return source.toURI().toURL();
@@ -154,11 +124,12 @@ abstract class PathConverter<S,T> extend
     /**
      * Converter from {@link URL} to {@link File}.
      */
-    private static final class URLFile extends PathConverter<URL,File> {
+    public static final class URLFile extends PathConverter<URL,File> {
         private static final long serialVersionUID = 1228852836485762335L;
         static final URLFile INSTANCE = new URLFile();
-        private URLFile() {super(URL.class, File.class);}
+        public URLFile() {super(URL.class, File.class);} // Instantiated by ServiceLoader.
 
+        @Override public ObjectConverter<URL,File> unique()  {return INSTANCE;}
         @Override public ObjectConverter<File,URL> inverse() {return FileURL.INSTANCE;}
         @Override public File doConvert(final URL source) throws URISyntaxException {
             return new File(source.toURI());
@@ -168,11 +139,12 @@ abstract class PathConverter<S,T> extend
     /**
      * Converter from {@link URL} to {@link File}.
      */
-    private static final class URIFile extends PathConverter<URI,File> {
+    public static final class URIFile extends PathConverter<URI,File> {
         private static final long serialVersionUID = 5289256237146366469L;
         static final URIFile INSTANCE = new URIFile();
-        private URIFile() {super(URI.class, File.class);}
+        public URIFile() {super(URI.class, File.class);} // Instantiated by ServiceLoader.
 
+        @Override public ObjectConverter<URI,File> unique()  {return INSTANCE;}
         @Override public ObjectConverter<File,URI> inverse() {return FileURI.INSTANCE;}
         @Override public File doConvert(final URI source) throws IllegalArgumentException {
             return new File(source);
@@ -182,13 +154,13 @@ abstract class PathConverter<S,T> extend
     /**
      * Converter from {@link URL} to {@link URI}.
      */
-    @Immutable
-    static final class URL_URI extends PathConverter<URL,URI> {
+    public static final class URL_URI extends PathConverter<URL,URI> {
         private static final long serialVersionUID = -1653233667050600894L;
         static final URL_URI INSTANCE = new URL_URI();
-        private URL_URI() {super(URL.class, URI.class);}
+        public URL_URI() {super(URL.class, URI.class);} // Instantiated by ServiceLoader.
 
-        @Override public ObjectConverter<URI, URL> inverse() {return URI_URL.INSTANCE;}
+        @Override public ObjectConverter<URL,URI> unique()  {return INSTANCE;}
+        @Override public ObjectConverter<URI,URL> inverse() {return URI_URL.INSTANCE;}
         @Override public URI doConvert(final URL source) throws URISyntaxException {
             return source.toURI();
         }
@@ -197,12 +169,13 @@ abstract class PathConverter<S,T> extend
     /**
      * Converter from {@link URI} to {@link URL}.
      */
-    static final class URI_URL extends PathConverter<URI,URL> {
+    public static final class URI_URL extends PathConverter<URI,URL> {
         private static final long serialVersionUID = -7866572007304228474L;
         static final URI_URL INSTANCE = new URI_URL();
-        private URI_URL() {super(URI.class, URL.class);}
+        public URI_URL() {super(URI.class, URL.class);} // Instantiated by ServiceLoader.
 
-        @Override public ObjectConverter<URL, URI> inverse() {return URL_URI.INSTANCE;}
+        @Override public ObjectConverter<URI,URL> unique()  {return INSTANCE;}
+        @Override public ObjectConverter<URL,URI> inverse() {return URL_URI.INSTANCE;}
         @Override public URL doConvert(final URI source) throws MalformedURLException {
             return source.toURL();
         }

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=1457553&r1=1457552&r2=1457553&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] Sun Mar 17 20:29:09 2013
@@ -96,49 +96,6 @@ abstract class StringConverter<T> extend
     }
 
     /**
-     * Returns a predefined instance for the given target class, or {@code null} if none.
-     * This method does not create any new instance.
-     *
-     * @param  <T> The target class.
-     * @param  targetClass The target class.
-     * @return An instance for the given target class, or {@code null} if none.
-     */
-    @SuppressWarnings({"unchecked","rawtypes"})
-    static <T> StringConverter<T> getInstance(final Class<T> targetClass) {
-        switch (Numbers.getEnumConstant(targetClass)) {
-            case Numbers.BOOLEAN:     return (StringConverter<T>) Boolean   .INSTANCE;
-            case Numbers.BYTE:        return (StringConverter<T>) Byte      .INSTANCE;
-            case Numbers.SHORT:       return (StringConverter<T>) Short     .INSTANCE;
-            case Numbers.INTEGER:     return (StringConverter<T>) Integer   .INSTANCE;
-            case Numbers.LONG:        return (StringConverter<T>) Long      .INSTANCE;
-            case Numbers.FLOAT:       return (StringConverter<T>) Float     .INSTANCE;
-            case Numbers.DOUBLE:      return (StringConverter<T>) Double    .INSTANCE;
-            case Numbers.BIG_INTEGER: return (StringConverter<T>) BigInteger.INSTANCE;
-            case Numbers.BIG_DECIMAL: return (StringConverter<T>) BigDecimal.INSTANCE;
-        }
-        if (targetClass == java.lang.Number        .class) return (StringConverter<T>) Number. INSTANCE;
-        if (targetClass == java.util.Locale        .class) return (StringConverter<T>) Locale. INSTANCE;
-        if (targetClass == java.nio.charset.Charset.class) return (StringConverter<T>) Charset.INSTANCE;
-        if (targetClass == java.io.File            .class) return (StringConverter<T>) File   .INSTANCE;
-        if (targetClass == java.nio.file.Path      .class) return (StringConverter<T>) Path   .INSTANCE;
-        if (targetClass == java.net.URI            .class) return (StringConverter<T>) URI    .INSTANCE;
-        if (targetClass == java.net.URL            .class) return (StringConverter<T>) URL    .INSTANCE;
-        if (targetClass == org.opengis.util.InternationalString.class)
-            return (StringConverter<T>) InternationalString.INSTANCE;
-        return null;
-    }
-
-    /**
-     * Returns the singleton instance on deserialization, if any.
-     */
-    @Override
-    public final ObjectConverter<String, T> unique() {
-        assert sourceClass == String.class : sourceClass;
-        final StringConverter<T> instance = getInstance(targetClass);
-        return (instance != null) ? instance : super.unique();
-    }
-
-    /**
      * While this is not a general rule for surjective functions,
      * all converters defined in this class are invertibles.
      */
@@ -193,100 +150,90 @@ abstract class StringConverter<T> extend
      * Converter from {@link String} to various kinds of {@link java.lang.Number}.
      */
     @Immutable
-    private static final class Number extends StringConverter<java.lang.Number> {
+    public static final class Number extends StringConverter<java.lang.Number> {
         private static final long serialVersionUID = 1557277544742023571L;
-        static final Number INSTANCE = new Number();
-        private Number() {super(java.lang.Number.class);}
+        public Number() {super(java.lang.Number.class);} // Instantiated by ServiceLoader.
 
         @Override java.lang.Number doConvert(String source) throws NumberFormatException {
             return Numbers.narrowestNumber(source);
         }
     }
 
-    private static final class Double extends StringConverter<java.lang.Double> {
+    public static final class Double extends StringConverter<java.lang.Double> {
         private static final long serialVersionUID = -9094071164371643060L;
-        static final Double INSTANCE = new Double();
-        private Double() {super(java.lang.Double.class);}
+        public Double() {super(java.lang.Double.class);} // Instantiated by ServiceLoader.
 
         @Override java.lang.Double doConvert(String source) throws NumberFormatException {
             return java.lang.Double.parseDouble(source);
         }
     }
 
-    private static final class Float extends StringConverter<java.lang.Float> {
+    public static final class Float extends StringConverter<java.lang.Float> {
         private static final long serialVersionUID = -2815192289550338333L;
-        static final Float INSTANCE = new Float();
-        private Float() {super(java.lang.Float.class);}
+        public Float() {super(java.lang.Float.class);} // Instantiated by ServiceLoader.
 
         @Override java.lang.Float doConvert(String source) throws NumberFormatException {
             return java.lang.Float.parseFloat(source);
         }
     }
 
-    private static final class Long extends StringConverter<java.lang.Long> {
+    public static final class Long extends StringConverter<java.lang.Long> {
         private static final long serialVersionUID = -2171263041723939779L;
-        static final Long INSTANCE = new Long();
-        private Long() {super(java.lang.Long.class);}
+        public Long() {super(java.lang.Long.class);} // Instantiated by ServiceLoader.
 
         @Override java.lang.Long doConvert(String source) throws NumberFormatException {
             return java.lang.Long.parseLong(source);
         }
     }
 
-    private static final class Integer extends StringConverter<java.lang.Integer> {
+    public static final class Integer extends StringConverter<java.lang.Integer> {
         private static final long serialVersionUID = 763211364703205967L;
-        static final Integer INSTANCE = new Integer();
-        private Integer() {super(java.lang.Integer.class);}
+        public Integer() {super(java.lang.Integer.class);} // Instantiated by ServiceLoader.
 
         @Override java.lang.Integer doConvert(String source) throws NumberFormatException {
             return java.lang.Integer.parseInt(source);
         }
     }
 
-    private static final class Short extends StringConverter<java.lang.Short> {
+    public static final class Short extends StringConverter<java.lang.Short> {
         private static final long serialVersionUID = -1770870328699572960L;
-        static final Short INSTANCE = new Short();
-        private Short() {super(java.lang.Short.class);}
+        public Short() {super(java.lang.Short.class);} // Instantiated by ServiceLoader.
 
         @Override java.lang.Short doConvert(String source) throws NumberFormatException {
             return java.lang.Short.parseShort(source);
         }
     }
 
-    private static final class Byte extends StringConverter<java.lang.Byte> {
+    public static final class Byte extends StringConverter<java.lang.Byte> {
         private static final long serialVersionUID = 2084870859391804185L;
-        static final Byte INSTANCE = new Byte();
-        private Byte() {super(java.lang.Byte.class);}
+        public Byte() {super(java.lang.Byte.class);} // Instantiated by ServiceLoader.
 
         @Override java.lang.Byte doConvert(String source) throws NumberFormatException {
             return java.lang.Byte.parseByte(source);
         }
     }
 
-    private static final class BigDecimal extends StringConverter<java.math.BigDecimal> {
+    public static final class BigDecimal extends StringConverter<java.math.BigDecimal> {
         private static final long serialVersionUID = -8597497425876120213L;
-        static final BigDecimal INSTANCE = new BigDecimal();
-        private BigDecimal() {super(java.math.BigDecimal.class);}
+        public BigDecimal() {super(java.math.BigDecimal.class);} // Instantiated by ServiceLoader.
 
         @Override java.math.BigDecimal doConvert(String source) throws NumberFormatException {
             return new java.math.BigDecimal(source);
         }
     }
 
-    private static final class BigInteger extends StringConverter<java.math.BigInteger> {
+    public static final class BigInteger extends StringConverter<java.math.BigInteger> {
         private static final long serialVersionUID = 8658903031519526466L;
-        static final BigInteger INSTANCE = new BigInteger();
-        private BigInteger() {super(java.math.BigInteger.class);}
+        public BigInteger() {super(java.math.BigInteger.class);} // Instantiated by ServiceLoader.
 
         @Override java.math.BigInteger doConvert(String source) throws NumberFormatException {
             return new java.math.BigInteger(source);
         }
     }
 
-    private static final class Boolean extends StringConverter<java.lang.Boolean> {
+    public static final class Boolean extends StringConverter<java.lang.Boolean> {
         private static final long serialVersionUID = -27525398425996373L;
-        static final Boolean INSTANCE = new Boolean();
-        private Boolean() {super(java.lang.Boolean.class);}
+        public Boolean() {super(java.lang.Boolean.class);} // Instantiated by ServiceLoader.
 
         /** See {@link StringConverter} for the conversion table. */
         @Override java.lang.Boolean doConvert(final String source) throws UnconvertibleObjectException {
@@ -298,70 +245,63 @@ abstract class StringConverter<T> extend
         }
     }
 
-    private static final class Locale extends StringConverter<java.util.Locale> {
+    public static final class Locale extends StringConverter<java.util.Locale> {
         private static final long serialVersionUID = -2888932450292616036L;
-        static final Locale INSTANCE = new Locale();
-        private Locale() {super(java.util.Locale.class);}
+        public Locale() {super(java.util.Locale.class);} // Instantiated by ServiceLoader.
 
         @Override java.util.Locale doConvert(String source) throws IllegalArgumentException {
             return Locales.parse(source);
         }
     }
 
-    private static final class Charset extends StringConverter<java.nio.charset.Charset> {
+    public static final class Charset extends StringConverter<java.nio.charset.Charset> {
         private static final long serialVersionUID = 4539755855992944656L;
-        static final Charset INSTANCE = new Charset();
-        private Charset() {super(java.nio.charset.Charset.class);}
+        public Charset() {super(java.nio.charset.Charset.class);} // Instantiated by ServiceLoader.
 
         @Override java.nio.charset.Charset doConvert(String source) throws UnsupportedCharsetException {
             return java.nio.charset.Charset.forName(source);
         }
     }
 
-    private static final class File extends StringConverter<java.io.File> {
+    public static final class File extends StringConverter<java.io.File> {
         private static final long serialVersionUID = 6445208470928432376L;
-        static final File INSTANCE = new File();
-        private File() {super(java.io.File.class);}
+        public File() {super(java.io.File.class);} // Instantiated by ServiceLoader.
 
         @Override java.io.File doConvert(String source) {
             return new java.io.File(source);
         }
     }
 
-    private static final class Path extends StringConverter<java.nio.file.Path> {
+    public static final class Path extends StringConverter<java.nio.file.Path> {
         private static final long serialVersionUID = -5227120925547132828L;
-        static final Path INSTANCE = new Path();
-        private Path() {super(java.nio.file.Path.class);}
+        public Path() {super(java.nio.file.Path.class);} // Instantiated by ServiceLoader.
 
         @Override java.nio.file.Path doConvert(String source) throws InvalidPathException {
             return java.nio.file.Paths.get(source);
         }
     }
 
-    private static final class URI extends StringConverter<java.net.URI> {
+    public static final class URI extends StringConverter<java.net.URI> {
         private static final long serialVersionUID = -2804405634789179706L;
-        static final URI INSTANCE = new URI();
-        private URI() {super(java.net.URI.class);}
+        public URI() {super(java.net.URI.class);} // Instantiated by ServiceLoader.
 
         @Override java.net.URI doConvert(String source) throws URISyntaxException {
             return new java.net.URI(source);
         }
     }
 
-    private static final class URL extends StringConverter<java.net.URL> {
+    public static final class URL extends StringConverter<java.net.URL> {
         private static final long serialVersionUID = 2303928306635765592L;
-        static final URL INSTANCE = new URL();
-        private URL() {super(java.net.URL.class);}
+        public URL() {super(java.net.URL.class);} // Instantiated by ServiceLoader.
 
         @Override java.net.URL doConvert(String source) throws MalformedURLException {
             return new java.net.URL(source);
         }
     }
 
-    private static final class InternationalString extends StringConverter<org.opengis.util.InternationalString> {
+    public static final class InternationalString extends StringConverter<org.opengis.util.InternationalString> {
         private static final long serialVersionUID = 730809620191573819L;
-        static final InternationalString INSTANCE = new InternationalString();
-        private InternationalString() {super(org.opengis.util.InternationalString.class);}
+        public InternationalString() {super(org.opengis.util.InternationalString.class);} // Instantiated by ServiceLoader.
 
         @Override org.opengis.util.InternationalString doConvert(String source) {
             return new SimpleInternationalString(source);
@@ -380,7 +320,7 @@ abstract class StringConverter<T> extend
      * to the constructor.
      *
      * <p>Instances of this class are created by
-     * {@link HeuristicRegistry#createConverter(Class, Class)}.</p>
+     * {@link SystemRegistry#createConverter(Class, Class)}.</p>
      */
     @Immutable
     static final class CodeList<T extends org.opengis.util.CodeList<T>> extends StringConverter<T> {

Modified: 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=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -115,7 +115,7 @@ abstract class SystemConverter<S,T> exte
      * Otherwise this converter is returned <strong>without</strong> being cached.
      */
     public ObjectConverter<S,T> unique() {
-        final ObjectConverter<S,T> existing = HeuristicRegistry.SYSTEM.findEquals(this);
+        final ObjectConverter<S,T> existing = SystemRegistry.INSTANCE.findEquals(this);
         return (existing != null) ? existing : this;
     }
 

Copied: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java (from r1457163, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/HeuristicRegistry.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java?p2=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/HeuristicRegistry.java&r1=1457163&r2=1457553&rev=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/HeuristicRegistry.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -17,17 +17,33 @@
 package org.apache.sis.internal.converter;
 
 import java.util.Date;
+import java.util.ServiceLoader;
 import org.opengis.util.CodeList;
 import net.jcip.annotations.ThreadSafe;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.util.UnconvertibleObjectException;
+import org.apache.sis.internal.util.SystemListener;
 
 
 /**
- * A {@link ConverterRegistry} which applies heuristic rules in addition of the explicitly
- * registered converters. Those heuristic rules are provided in a separated class in order
- * to keep the {@link ConverterRegistry} class "pure", and concentrate all arbitrary
- * decisions in this single class.
+ * The Apache SIS system-wide {@link ConverterRegistry}.
+ * This class serves two purposes:
+ *
+ * <ul>
+ *   <li><p>Fetch the list of converters from the content of all
+ *       {@code META-INF/services/org.apache.sis.util.converter.ObjectConverter} files found on the classpath.
+ *       The intend is to allow other modules to register their own converters.</p></li>
+ *
+ *   <li><p>Apply heuristic rules in addition to the explicitly registered converters.
+ *       Those heuristic rules are provided in a separated class in order to keep the
+ *       {@link ConverterRegistry} class a little bit more "pure", and concentrate
+ *       most arbitrary decisions in this single class.</p></li>
+ * </ul>
+ *
+ * When using {@code SystemRegistry}, new converters may "automagically" appear as a consequence
+ * of the above-cited heuristic rules. This differs from the {@link ConverterRegistry} behavior,
+ * where only registered converters are used.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.02)
@@ -35,7 +51,7 @@ import org.apache.sis.util.ObjectConvert
  * @module
  */
 @ThreadSafe
-public final class HeuristicRegistry extends ConverterRegistry {
+public final class SystemRegistry extends 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
@@ -44,17 +60,67 @@ public final class HeuristicRegistry ext
      * <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.
+     * <p>See the package javadoc for information about how applications can add
+     * custom system-wide converters.</p>
      */
-    public static final ConverterRegistry SYSTEM = new HeuristicRegistry();
+    public static final ConverterRegistry INSTANCE = new SystemRegistry();
+    static {
+        /*
+         * Force reloading of META-INF/services files if the classpath changed,
+         * since the set of reachable META-INF/services files may have changed.
+         * If any converters were registered by explicit calls to the 'register' method,
+         * then those converters are lost. This is of concern only for applications using
+         * a modularization framework like OSGi. See package javadoc for more information.
+         */
+        SystemListener.add(new SystemListener() {
+            @Override protected void classpathChanged() {
+                INSTANCE.clear();
+            }
+        });
+    }
 
     /**
      * Creates an initially empty set of object converters. The heuristic
      * rules apply right away, even if no converter have been registered yet.
      */
-    private HeuristicRegistry() {
+    private SystemRegistry() {
+    }
+
+    /**
+     * Invoked when this {@code ConverterRegistry} needs to be initialized. This method
+     * is automatically invoked the first time that {@link #register(ObjectConverter)}
+     * or {@link #find(Class, Class)} is invoked.
+     *
+     * <p>The default implementation is equivalent to the following code
+     * (see the package javadoc for more information):</p>
+     *
+     * {@preformat java
+     *     ClassLoader loader = getClass().getClassLoader();
+     *     for (ObjectConverter<?,?> converter : ServiceLoader.load(ObjectConverter.class, loader)) {
+     *         register(converter);
+     *     }
+     * }
+     */
+    @Override
+    protected void initialize() {
+        for (ObjectConverter<?,?> converter : ServiceLoader.load(ObjectConverter.class, getClass().getClassLoader())) {
+            if (converter instanceof SystemConverter<?,?>) {
+                converter = ((SystemConverter<?,?>) converter).unique();
+            }
+            register(converter);
+        }
+    }
+
+    /**
+     * Returns {@code true} if we should look for the inverse converter of the given target class.
+     * For example if no converter is explicitely registered from {@code Float} to {@code String},
+     * we can look for the converter from {@code String} to {@code Float}, then fetch its inverse.
+     *
+     * <p>We allow this operation only for a few types which are needed for the way SIS converters
+     * are defined in this internal package.</p>
+     */
+    private static boolean tryInverse(final Class<?> targetClass) {
+        return (targetClass == String.class) || (targetClass == Date.class);
     }
 
     /**
@@ -87,19 +153,11 @@ public final class HeuristicRegistry ext
          * to java.util.Date was created by the super class, that conversion would not contain
          * an inverse conversion from java.util.Date to java.sql.Date.
          */
-        if (targetClass == Date.class) {
-            final ObjectConverter<Date, S> candidate = DateConverter.getInstance(sourceClass);
-            if (candidate != null) {
-                return (ObjectConverter<S,T>) candidate.inverse();
-            }
-        }
-        if (targetClass == String.class) {
-            final ObjectConverter<String, S> candidate = StringConverter.getInstance(sourceClass);
-            if (candidate != null) {
-                return (ObjectConverter<S,T>) candidate.inverse();
-            }
-            if (CodeList.class.isAssignableFrom(sourceClass)) {
+        if (tryInverse(targetClass) && !tryInverse(sourceClass)) { // The ! is for preventing infinite recursivity.
+            try {
                 return findExact(targetClass, sourceClass).inverse();
+            } catch (UnconvertibleObjectException e) {
+                // Ignore. The code below may succeed.
             }
         }
         /*
@@ -121,13 +179,9 @@ public final class HeuristicRegistry ext
                     targetClass, find(String.class, targetClass));
         }
         /*
-         * From String to various kind of objects.
+         * From String to CodeList.
          */
         if (sourceClass == String.class) {
-            final ObjectConverter<String, T> candidate = StringConverter.getInstance(targetClass);
-            if (candidate != null) {
-                return (ObjectConverter<S,T>) candidate;
-            }
             if (CodeList.class.isAssignableFrom(targetClass)) {
                 return (ObjectConverter<S,T>) new StringConverter.CodeList<>(
                         targetClass.asSubclass(CodeList.class));
@@ -148,22 +202,6 @@ public final class HeuristicRegistry ext
             }
         }
         /*
-         * From Date to various kind of objects.
-         */
-        if (sourceClass == Date.class) {
-            final ObjectConverter<Date, T> candidate = DateConverter.getInstance(targetClass);
-            if (candidate != null) {
-                return (ObjectConverter<S,T>) candidate;
-            }
-        }
-        /*
-         * Various kind of paths (Path, File, URL, URI).
-         */
-        final ObjectConverter<S,T> p = PathConverter.getInstance(sourceClass, targetClass);
-        if (p != null) {
-            return p;
-        }
-        /*
          * From various objects to String.
          */
         if (targetClass == String.class) {

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/package-info.java?rev=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/package-info.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/package-info.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -16,9 +16,30 @@
  */
 
 /**
- * {@link org.apache.sis.util.ObjectConverter} implementations.
- * A system-wide set of conversions is pre-defined and available by the
- * {@link org.apache.sis.internal.converter.ConverterRegistry#system()} method.
+ * Default set of {@link org.apache.sis.util.ObjectConverter} implementations.
+ * Converter for a given pair of <cite>source</cite> and <cite>target</cite> classes
+ * can be obtained with {@link org.apache.sis.internal.converter.ConverterRegistry}.
+ * A system-wide instance of {@code ConverterRegistry} with a default set of conversions
+ * is available as {@link org.apache.sis.internal.converter.SystemRegistry#INSTANCE}.
+ *
+ * {@section Adding system-wide converters}
+ * Applications can add system-wide custom converters either by explicit calls to the
+ * {@code SystemRegistry.INSTANCE.register(ObjectConverter)} method, or by listing the
+ * fully qualified classnames of their {@link ObjectConverter} instances in a file having
+ * exactly the following name:
+ *
+ * {@preformat text
+ *     META-INF/services/org.apache.sis.util.converter.ObjectConverter
+ * }
+ *
+ * Applications deployed in a modularization framework like OSGi shall use only the
+ * {@code META-INF} approach, because system converters are discarded every time the
+ * classpath changes. Having the converters declared in {@code META-INF} ensure that
+ * they will be reloaded when needed.
+ *
+ * <p>Alternatively, applications can also use their own {@code ConverterRegistry} instance.
+ * Non-system instances do not scan for {@code META-INF} and do not discard their content on
+ * classpath changes.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.5)

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Classes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Classes.java?rev=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Classes.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Classes.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -582,11 +582,11 @@ cmp:    for (final Class<?> c : c1) {
         if (classe == null) {
             return "<*>";
         }
-        Class<?> enclosing = classe.getEnclosingClass();
         while (classe.isAnonymousClass()) {
             classe = classe.getSuperclass();
         }
         String name = classe.getSimpleName();
+        final Class<?> enclosing = classe.getEnclosingClass();
         if (enclosing != null) {
             name = getShortName(enclosing) + '.' + name;
         }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java?rev=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -20,7 +20,7 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.sis.util.collection.CollectionsExt;
 import org.apache.sis.internal.converter.IdentityConverter;
-import org.apache.sis.internal.converter.HeuristicRegistry;
+import org.apache.sis.internal.converter.SystemRegistry;
 
 
 /**
@@ -94,7 +94,7 @@ public final class ObjectConverters exte
     public static <S,T> ObjectConverter<? super S, ? extends T> find(final Class<S> source, final Class<T> target)
             throws UnconvertibleObjectException
     {
-        return HeuristicRegistry.SYSTEM.find(source, target);
+        return SystemRegistry.INSTANCE.find(source, target);
     }
 
     /**

Added: sis/branches/JDK7/sis-utility/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter?rev=1457553&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter (added)
+++ sis/branches/JDK7/sis-utility/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter [UTF-8] Sun Mar 17 20:29:09 2013
@@ -0,0 +1,27 @@
+# Loaded by org.apache.sis.internal.converter.ConverterRegistry.
+org.apache.sis.internal.converter.StringConverter$Number
+org.apache.sis.internal.converter.StringConverter$Byte
+org.apache.sis.internal.converter.StringConverter$Short
+org.apache.sis.internal.converter.StringConverter$Integer
+org.apache.sis.internal.converter.StringConverter$Long
+org.apache.sis.internal.converter.StringConverter$Float
+org.apache.sis.internal.converter.StringConverter$Double
+org.apache.sis.internal.converter.StringConverter$BigInteger
+org.apache.sis.internal.converter.StringConverter$BigDecimal
+org.apache.sis.internal.converter.StringConverter$Boolean
+org.apache.sis.internal.converter.StringConverter$Locale
+org.apache.sis.internal.converter.StringConverter$Charset
+org.apache.sis.internal.converter.StringConverter$InternationalString
+org.apache.sis.internal.converter.StringConverter$File
+org.apache.sis.internal.converter.StringConverter$Path
+org.apache.sis.internal.converter.StringConverter$URI
+org.apache.sis.internal.converter.StringConverter$URL
+org.apache.sis.internal.converter.PathConverter$FileURI
+org.apache.sis.internal.converter.PathConverter$FileURL
+org.apache.sis.internal.converter.PathConverter$URLFile
+org.apache.sis.internal.converter.PathConverter$URIFile
+org.apache.sis.internal.converter.PathConverter$URL_URI
+org.apache.sis.internal.converter.PathConverter$URI_URL
+org.apache.sis.internal.converter.DateConverter$Long
+org.apache.sis.internal.converter.DateConverter$SQL
+org.apache.sis.internal.converter.DateConverter$Timestamp

Propchange: sis/branches/JDK7/sis-utility/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/main/resources/META-INF/services/org.apache.sis.util.ObjectConverter
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/ConverterRegistryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/ConverterRegistryTest.java?rev=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/ConverterRegistryTest.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/ConverterRegistryTest.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -160,7 +160,7 @@ public final strictfp class ConverterReg
     @Test
     public void testStringToMiscellaneous() {
         assertAllConvertersAreRegistered();
-        register(StringConverter.getInstance(Short.class));
+        register(new StringConverter.Short());
         assertSameConverterForTarget(Short       .class);
         assertSameConverterForTarget(Number      .class);
         assertIdentityForTarget     (Object      .class);
@@ -181,7 +181,7 @@ public final strictfp class ConverterReg
          */
         assertAllConvertersAreRegistered();
         assertNoConverterForTarget(Long.class);
-        register(StringConverter.getInstance(Long.class));
+        register(new StringConverter.Long());
         assertSameConverterForTarget(Long        .class);
         assertIdentityForTarget     (Object      .class);
         assertNoConverterForTarget  (Cloneable   .class);
@@ -207,7 +207,7 @@ public final strictfp class ConverterReg
          */
         assertAllConvertersAreRegistered();
         assertNoConverterForTarget(Boolean.class);
-        register(StringConverter.getInstance(Boolean.class));
+        register(new StringConverter.Boolean());
         assertSameConverterForTarget(Boolean     .class);
         assertIdentityForTarget     (Object      .class);
         assertNoConverterForTarget  (Cloneable   .class);
@@ -229,7 +229,7 @@ public final strictfp class ConverterReg
          * Expected side-effect: replacement of the FallbackConverter
          */
         assertAllConvertersAreRegistered();
-        register(StringConverter.getInstance(Number.class));
+        register(new StringConverter.Number());
         assertSameConverterForTarget(Number      .class);
         assertIdentityForTarget     (Object      .class);
         assertNoConverterForTarget  (Cloneable   .class);
@@ -250,7 +250,7 @@ public final strictfp class ConverterReg
          */
         assertAllConvertersAreRegistered();
         assertNoConverterForTarget(Float.class);
-        register(StringConverter.getInstance(Float.class));
+        register(new StringConverter.Float());
         assertSameConverterForTarget(Float       .class);
         assertIdentityForTarget     (Object      .class);
         assertNoConverterForTarget  (Cloneable   .class);
@@ -285,7 +285,7 @@ public final strictfp class ConverterReg
     @DependsOnMethod("testStringToMiscellaneous")
     public void testNumberToMiscellaneous() {
         assertAllConvertersAreRegistered();
-        register(StringConverter.getInstance(Number.class).inverse());
+        register(new StringConverter.Number().inverse());
         assertSameConverterForTarget(String      .class);
         assertIdentityForTarget     (Object      .class);
         assertNoConverterForTarget  (Cloneable   .class);
@@ -304,7 +304,7 @@ public final strictfp class ConverterReg
          * Expected side-effect: none
          */
         assertAllConvertersAreRegistered();
-        register(StringConverter.getInstance(Number.class));
+        register(new StringConverter.Number());
         assertSameConverterForTarget(Number.class);
         assertMultilinesEquals("After StringConverter.Number",
             "ConverterRegistry\n" +

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=1457553&r1=1457552&r2=1457553&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] Sun Mar 17 20:29:09 2013
@@ -60,7 +60,7 @@ public final strictfp class FallbackConv
         final EnumSet<FunctionProperty> SURJECTIVE = EnumSet.of(FunctionProperty.SURJECTIVE);
         final EnumSet<FunctionProperty> INVERTIBLE = EnumSet.of(FunctionProperty.SURJECTIVE, FunctionProperty.INVERTIBLE);
 
-        ObjectConverter<String,?> c = StringConverter.getInstance(Short.class);
+        ObjectConverter<String,?> c = new StringConverter.Short();
         assertEquals(String.class, c.getSourceClass());
         assertEquals(Short.class,  c.getTargetClass());
         assertEquals(INVERTIBLE,   c.properties());
@@ -68,7 +68,7 @@ public final strictfp class FallbackConv
         assertMultilinesEquals(
                 "Short ← String", c.toString());
 
-        c = FallbackConverter.merge(c, StringConverter.getInstance(Long.class));
+        c = FallbackConverter.merge(c, new StringConverter.Long());
         assertEquals(String.class, c.getSourceClass());
         assertEquals(Number.class, c.getTargetClass());
         assertEquals(SURJECTIVE,   c.properties());
@@ -78,7 +78,7 @@ public final strictfp class FallbackConv
                 "  ├─Short ← String\n" +
                 "  └─Long  ← String\n", c.toString());
 
-        c = FallbackConverter.merge(c, StringConverter.getInstance(Float.class));
+        c = FallbackConverter.merge(c, new StringConverter.Float());
         assertEquals(String.class, c.getSourceClass());
         assertEquals(Number.class, c.getTargetClass());
         assertEquals(SURJECTIVE,   c.properties());
@@ -89,7 +89,7 @@ public final strictfp class FallbackConv
                 "  ├─Long  ← String\n" +
                 "  └─Float ← String\n", c.toString());
 
-        c = FallbackConverter.merge(c, StringConverter.getInstance(Integer.class));
+        c = FallbackConverter.merge(c, new StringConverter.Integer());
         assertEquals(String.class, c.getSourceClass());
         assertEquals(Number.class, c.getTargetClass());
         assertEquals(SURJECTIVE,   c.properties());
@@ -101,7 +101,7 @@ public final strictfp class FallbackConv
                 "  ├─Float   ← String\n" +
                 "  └─Integer ← String\n", c.toString());
 
-        c = FallbackConverter.merge(c, StringConverter.getInstance(Boolean.class));
+        c = FallbackConverter.merge(c, new StringConverter.Boolean());
         assertEquals(String.class, c.getSourceClass());
         assertEquals(Object.class, c.getTargetClass());
         assertEquals(SURJECTIVE,   c.properties());
@@ -115,7 +115,7 @@ public final strictfp class FallbackConv
                 "  │   └─Integer ← String\n" +
                 "  └─Boolean     ← String\n", c.toString());
 
-        c = FallbackConverter.merge(c, StringConverter.getInstance(Double.class));
+        c = FallbackConverter.merge(c, new StringConverter.Double());
         assertEquals(String.class, c.getSourceClass());
         assertEquals(Object.class, c.getTargetClass());
         assertEquals(SURJECTIVE,   c.properties());

Modified: 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=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/NumberConverterTest.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -36,7 +36,7 @@ import static org.apache.sis.test.Assert
  * @version 0.3
  * @module
  */
-@DependsOn(HeuristicRegistryTest.class)
+@DependsOn(SystemRegistryTest.class)
 public final strictfp class NumberConverterTest extends TestCase {
     /**
      * Creates a {@link NumberConverter} for the given source and target classes.
@@ -47,7 +47,7 @@ public final strictfp class NumberConver
     private static <S extends Number, T> ObjectConverter<S,T> create(
             final Class<S> sourceClass, final Class<T> targetClass)
     {
-        final ObjectConverter<S,T> converter = HeuristicRegistry.SYSTEM.findExact(sourceClass, targetClass);
+        final ObjectConverter<S,T> converter = SystemRegistry.INSTANCE.findExact(sourceClass, targetClass);
         assertInstanceOf("ConverterRegistry.find(" + sourceClass.getSimpleName() + ", " + targetClass.getSimpleName() + ')',
                 (targetClass == Comparable.class) ? NumberConverter.Comparable.class : NumberConverter.class, converter);
         return converter;

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java?rev=1457553&r1=1457552&r2=1457553&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java [UTF-8] Sun Mar 17 20:29:09 2013
@@ -26,6 +26,7 @@ import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
 import org.apache.sis.test.PlatformDependentTest;
+import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -41,6 +42,7 @@ import static org.apache.sis.test.Assert
  * @version 0.3
  * @module
  */
+@DependsOn(StringConverterTest.class)
 public final strictfp class PathConverterTest extends TestCase {
     /**
      * Assumes that the platform file system has a Unix-style root.
@@ -70,9 +72,9 @@ public final strictfp class PathConverte
      */
     @Test
     public void testFile_String() {
-        final ObjectConverter<File,String> c = StringConverter.getInstance(File.class).inverse();
+        final ObjectConverter<File,String> c = new StringConverter.File().inverse();
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -84,9 +86,9 @@ public final strictfp class PathConverte
     @PlatformDependentTest
     public void testFile_URI() throws URISyntaxException {
         assumeUnixRoot();
-        final ObjectConverter<File,URI> c = PathConverter.getInstance(File.class, URI.class);
+        final ObjectConverter<File,URI> c = PathConverter.FileURI.INSTANCE;
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -98,9 +100,9 @@ public final strictfp class PathConverte
     @PlatformDependentTest
     public void testFile_URL() throws MalformedURLException {
         assumeUnixRoot();
-        final ObjectConverter<File,URL> c = PathConverter.getInstance(File.class, URL.class);
+        final ObjectConverter<File,URL> c = PathConverter.FileURL.INSTANCE;
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -110,9 +112,9 @@ public final strictfp class PathConverte
      */
     @Test
     public void testURI_String() throws URISyntaxException {
-        final ObjectConverter<URI,String> c = StringConverter.getInstance(URI.class).inverse();
+        final ObjectConverter<URI,String> c = new StringConverter.URI().inverse();
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -123,9 +125,9 @@ public final strictfp class PathConverte
      */
     @Test
     public void testURI_URL() throws MalformedURLException, URISyntaxException {
-        final ObjectConverter<URI,URL> c = PathConverter.getInstance(URI.class, URL.class);
+        final ObjectConverter<URI,URL> c = PathConverter.URI_URL.INSTANCE;
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -137,9 +139,9 @@ public final strictfp class PathConverte
     @PlatformDependentTest
     public void testURI_File() throws URISyntaxException {
         PathConverterTest.assumeUnixRoot();
-        final ObjectConverter<URI,File> c = PathConverter.getInstance(URI.class, File.class);
+        final ObjectConverter<URI,File> c = PathConverter.URIFile.INSTANCE;
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -149,9 +151,9 @@ public final strictfp class PathConverte
      */
     @Test
     public void testURL_String() throws MalformedURLException {
-        final ObjectConverter<URL,String> c = StringConverter.getInstance(URL.class).inverse();
+        final ObjectConverter<URL,String> c = new StringConverter.URL().inverse();
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -162,9 +164,9 @@ public final strictfp class PathConverte
      */
     @Test
     public void testURL_URI() throws MalformedURLException, URISyntaxException {
-        final ObjectConverter<URL,URI> c = PathConverter.getInstance(URL.class, URI.class);
+        final ObjectConverter<URL,URI> c = PathConverter.URL_URI.INSTANCE;
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -176,8 +178,8 @@ public final strictfp class PathConverte
     @PlatformDependentTest
     public void testURL_File() throws MalformedURLException {
         PathConverterTest.assumeUnixRoot();
-        final ObjectConverter<URL,File> c = PathConverter.getInstance(URL.class, File.class);
+        final ObjectConverter<URL,File> c = PathConverter.URLFile.INSTANCE;
         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));
+        assertSerializedEquals(c);
     }
 }

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=1457553&r1=1457552&r2=1457553&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] Sun Mar 17 20:29:09 2013
@@ -52,17 +52,6 @@ import java.nio.file.Paths;
  */
 public final strictfp class StringConverterTest extends TestCase {
     /**
-     * Returns an instance for the given target type.
-     */
-    private static <T> StringConverter<T> getInstance(final Class<T> targetClass) {
-        final StringConverter<T> c = StringConverter.getInstance(targetClass);
-        assertNotNull("No instance found for the given target type.", c);
-        assertEquals("Unexpected source class.", String.class, c.getSourceClass());
-        assertEquals("Unexpected source class.", targetClass,  c.getTargetClass());
-        return c;
-    }
-
-    /**
      * Asserts that conversion of the given {@code source} value produces
      * the given {@code target} value, and tests the inverse conversion.
      */
@@ -94,13 +83,13 @@ public final strictfp class StringConver
      */
     @Test
     public void testNumber() {
-        final ObjectConverter<String,Number> c = getInstance(Number.class);
+        final ObjectConverter<String,Number> c = new StringConverter.Number();
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -108,10 +97,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testDouble() {
-        final ObjectConverter<String,Double> c = getInstance(Double.class);
+        final ObjectConverter<String,Double> c = new StringConverter.Double();
         runInvertibleConversion(c, "4.5", Double.valueOf(4.5));
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -119,10 +108,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testFloat() {
-        final ObjectConverter<String,Float> c = getInstance(Float.class);
+        final ObjectConverter<String,Float> c = new StringConverter.Float();
         runInvertibleConversion(c, "4.5", Float.valueOf(4.5f));
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -130,10 +119,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testLong() {
-        final ObjectConverter<String,Long> c = getInstance(Long.class);
+        final ObjectConverter<String,Long> c = new StringConverter.Long();
         runInvertibleConversion(c, "45000", Long.valueOf(45000));
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -141,10 +130,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testInteger() {
-        final ObjectConverter<String,Integer> c = getInstance(Integer.class);
+        final ObjectConverter<String,Integer> c = new StringConverter.Integer();
         runInvertibleConversion(c, "45000", Integer.valueOf(45000));
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -152,10 +141,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testShort() {
-        final ObjectConverter<String,Short> c = getInstance(Short.class);
+        final ObjectConverter<String,Short> c = new StringConverter.Short();
         runInvertibleConversion(c, "4500", Short.valueOf((short) 4500));
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -163,10 +152,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testByte() {
-        final ObjectConverter<String,Byte> c = getInstance(Byte.class);
+        final ObjectConverter<String,Byte> c = new StringConverter.Byte();
         runInvertibleConversion(c, "45", Byte.valueOf((byte) 45));
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -174,10 +163,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testBigDecimal() {
-        final ObjectConverter<String,BigDecimal> c = getInstance(BigDecimal.class);
+        final ObjectConverter<String,BigDecimal> c = new StringConverter.BigDecimal();
         runInvertibleConversion(c, "45000.5", BigDecimal.valueOf(45000.5));
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -185,10 +174,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testBigInteger() {
-        final ObjectConverter<String,BigInteger> c = getInstance(BigInteger.class);
+        final ObjectConverter<String,BigInteger> c = new StringConverter.BigInteger();
         runInvertibleConversion(c, "45000", BigInteger.valueOf(45000));
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -196,7 +185,7 @@ public final strictfp class StringConver
      */
     @Test
     public void testBoolean() {
-        final ObjectConverter<String,Boolean> c = getInstance(Boolean.class);
+        final ObjectConverter<String,Boolean> c = new StringConverter.Boolean();
         runInvertibleConversion(c, "true",  Boolean.TRUE);
         runInvertibleConversion(c, "false", Boolean.FALSE);
         assertEquals(Boolean.TRUE,  c.convert("yes"));
@@ -206,7 +195,7 @@ public final strictfp class StringConver
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -214,10 +203,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testLocale() {
-        final ObjectConverter<String,Locale> c = getInstance(Locale.class);
+        final ObjectConverter<String,Locale> c = new StringConverter.Locale();
         runInvertibleConversion(c, "fr_CA", Locale.CANADA_FRENCH);
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -225,10 +214,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testCharset() {
-        final ObjectConverter<String,Charset> c = getInstance(Charset.class);
+        final ObjectConverter<String,Charset> c = new StringConverter.Charset();
         runInvertibleConversion(c, "UTF-8", StandardCharsets.UTF_8);
         tryUnconvertibleValue(c);
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -236,9 +225,9 @@ public final strictfp class StringConver
      */
     @Test
     public void testInternationalString() {
-        final ObjectConverter<String,InternationalString> c = getInstance(InternationalString.class);
+        final ObjectConverter<String,InternationalString> c = new StringConverter.InternationalString();
         runInvertibleConversion(c, "Some sentence", new SimpleInternationalString("Some sentence"));
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -246,10 +235,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testFile() {
-        final ObjectConverter<String,File> c = getInstance(File.class);
+        final ObjectConverter<String,File> c = new StringConverter.File();
         final String path = "home/user/index.txt".replace('/', File.separatorChar);
         runInvertibleConversion(c, path, new File(path));
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -257,10 +246,10 @@ public final strictfp class StringConver
      */
     @Test
     public void testPath() {
-        final ObjectConverter<String,Path> c = getInstance(Path.class);
+        final ObjectConverter<String,Path> c = new StringConverter.Path();
         final String path = "home/user/index.txt".replace('/', File.separatorChar);
         runInvertibleConversion(c, path, Paths.get(path));
-        assertSame("Deserialization shall resolves to the singleton instance.", c, assertSerializedEquals(c));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -270,9 +259,9 @@ public final strictfp class StringConver
      */
     @Test
     public void testURI() throws URISyntaxException {
-        final ObjectConverter<String,URI> c = getInstance(URI.class);
+        final ObjectConverter<String,URI> c = new StringConverter.URI();
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -282,9 +271,9 @@ public final strictfp class StringConver
      */
     @Test
     public void testURL() throws MalformedURLException  {
-        final ObjectConverter<String,URL> c = getInstance(URL.class);
+        final ObjectConverter<String,URL> c = new StringConverter.URL();
         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));
+        assertSerializedEquals(c);
     }
 
     /**
@@ -295,5 +284,6 @@ public final strictfp class StringConver
         final ObjectConverter<String, PixelOrientation> c = new StringConverter.CodeList<>(PixelOrientation.class);
         runInvertibleConversion(c, "LOWER_RIGHT", PixelOrientation.LOWER_RIGHT);
         tryUnconvertibleValue(c);
+        assertSerializedEquals(c);
     }
 }



Mime
View raw message