sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1457152 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/internal/converter/ main/java/org/apache/sis/util/ test/java/org/apache/sis/internal/converter/
Date Fri, 15 Mar 2013 22:32:44 GMT
Author: desruisseaux
Date: Fri Mar 15 22:32:44 2013
New Revision: 1457152

URL: http://svn.apache.org/r1457152
Log:
Connected DateConverter, and added more tests.

Removed:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/LongConverter.java
Modified:
    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/HeuristicRegistry.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.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/ObjectToString.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/util/Numbers.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/HeuristicRegistryTest.java

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=1457152&r1=1457151&r2=1457152&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] Fri Mar 15 22:32:44 2013
@@ -101,6 +101,7 @@ public class ConverterRegistry {
     @SuppressWarnings("unchecked")
     private <S,T> void put(ClassPair<S,T> key, final ObjectConverter<? super
S, ? extends T> converter) {
         assert key.getClass() == ClassPair.class; // See SystemConverter.equals(Object)
+        assert key.cast(converter) != null : converter;
         assert Thread.holdsLock(converters);
         if (converter instanceof SystemConverter<?,?> &&
             converter.getSourceClass() == key.sourceClass &&
@@ -441,7 +442,7 @@ public class ConverterRegistry {
     @SuppressWarnings({"unchecked", "rawtypes"})
     protected <S,T> ObjectConverter<S,T> createConverter(final Class<S>
sourceClass, final Class<T> targetClass) {
         if (targetClass.isAssignableFrom(sourceClass)) {
-            return new IdentityConverter(sourceClass, targetClass);
+            return new IdentityConverter(sourceClass, targetClass, null);
         }
         return null;
     }

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=1457152&r1=1457151&r2=1457152&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] Fri Mar 15 22:32:44 2013
@@ -19,8 +19,6 @@ package org.apache.sis.internal.converte
 import java.util.Date;
 import java.util.Set;
 import java.util.EnumSet;
-import java.io.Serializable;
-import java.io.ObjectStreamException;
 import net.jcip.annotations.Immutable;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.math.FunctionProperty;
@@ -33,22 +31,69 @@ import org.apache.sis.math.FunctionPrope
  * There is currently no converter between {@link String} and {@link java.util.Date} because
the
  * date format is not yet defined (we are considering the ISO format for a future SIS version).
  *
+ * {@section Special cases}
+ * The converter from dates to timestamps is not injective, because the same date could be
mapped
+ * to many timestamps since timestamps have an additional nanoseconds field.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)
  * @version 0.3
  * @module
  */
 @Immutable
-abstract class DateConverter<T> extends SurjectiveConverter<Date,T> implements
Serializable {
+abstract class DateConverter<T> extends SystemConverter<Date,T> {
     /**
      * For cross-version compatibility.
      */
     private static final long serialVersionUID = -7770401534710581917L;
 
     /**
-     * For inner classes only.
+     * The inverse converter specified at construction time.
+     */
+    private final SystemConverter<T, Date> inverse;
+
+    /**
+     * Creates a converter with an inverse which is the identity converter.
+     */
+    @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() {
+    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;
     }
 
     /**
@@ -56,95 +101,101 @@ abstract class DateConverter<T> extends 
      */
     @Override
     public Set<FunctionProperty> properties() {
-        return EnumSet.of(FunctionProperty.SURJECTIVE, FunctionProperty.ORDER_PRESERVING);
+        return EnumSet.of(FunctionProperty.SURJECTIVE, FunctionProperty.ORDER_PRESERVING,
+                FunctionProperty.INVERTIBLE);
     }
 
     /**
-     * Returns the source class, which is always {@link Date}.
+     * Returns the inverse given at construction time.
      */
     @Override
-    public final Class<Date> getSourceClass() {
-        return Date.class;
+    public final ObjectConverter<T, Date> inverse() {
+        return inverse;
     }
 
     /**
-     * Converter from dates to long integers.
+     * Converter from {@code Long} to {@code Date}.
+     * This is the inverse of {@link org.apache.sis.internal.converter.DateConverter.Long}.
      */
-    @Immutable
-    static final class Long extends DateConverter<java.lang.Long> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 3163928356094316134L;
-        /** The unique, shared instance. */ static final Long INSTANCE = new Long();
-        /** For {@link #INSTANCE} only.  */ private Long() {}
+    private static final class Inverse extends SystemConverter<java.lang.Long, java.util.Date>
{
+        private static final long serialVersionUID = 3999693055029959455L;
+
+        private Inverse() {
+            super(java.lang.Long.class, java.util.Date.class);
+        }
+
+        @Override public ObjectConverter<java.util.Date, java.lang.Long> inverse()
{
+            return DateConverter.Long.INSTANCE;
+        }
 
-        /** Returns the function properties, which is bijective. */
         @Override public Set<FunctionProperty> properties() {
-            return EnumSet.of(FunctionProperty.INJECTIVE, FunctionProperty.SURJECTIVE,
-                    FunctionProperty.ORDER_PRESERVING, FunctionProperty.INVERTIBLE);
+            return DateConverter.Long.INSTANCE.properties();
         }
 
-        @Override public Class<java.lang.Long> getTargetClass() {
-            return java.lang.Long.class;
+        @Override public java.util.Date convert(final java.lang.Long target) {
+            return (target != null) ? new java.util.Date(target) : null;
         }
+    }
 
-        @Override public java.lang.Long convert(final Date source) {
-            return (source != null) ? source.getTime() : null;
+    /**
+     * 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> {
+        private static final long serialVersionUID = 3163928356094316134L;
+        static final Long INSTANCE = new Long();
+
+        private Long() {
+            super(java.lang.Long.class, new Inverse());
         }
 
-        @Override public ObjectConverter<java.lang.Long, Date> inverse() {
-            return LongConverter.Date.INSTANCE;
+        @Override public Set<FunctionProperty> properties() {
+            return EnumSet.of(FunctionProperty.INJECTIVE, FunctionProperty.SURJECTIVE,
+                    FunctionProperty.ORDER_PRESERVING, FunctionProperty.INVERTIBLE);
         }
 
-        /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
-            return INSTANCE;
+        @Override public java.lang.Long convert(final Date source) {
+            return (source != null) ? source.getTime() : null;
         }
     }
 
     /**
-     * Converter from dates to SQL dates.
+     * From {@code Date} to SQL {@code Date}.
+     * The inverse of this converter is the identity conversion.
      */
-    @Immutable
-    static final class SQL extends DateConverter<java.sql.Date> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = -3644605344718636345L;
-        /** The unique, shared instance. */ static final SQL INSTANCE = new SQL();
-        /** For {@link #INSTANCE} only.  */ private SQL() {}
+    private static final class SQL extends DateConverter<java.sql.Date> {
+        private static final long serialVersionUID = -3644605344718636345L;
+        static final SQL INSTANCE = new SQL();
 
-        @Override public Class<java.sql.Date> getTargetClass() {
-            return java.sql.Date.class;
+        private SQL() {
+            super(java.sql.Date.class);
         }
 
         @Override public java.sql.Date convert(final Date source) {
-            return (source != null) ? new java.sql.Date(source.getTime()) : null;
-        }
-
-        /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
-            return INSTANCE;
+            if (source == null || source instanceof java.sql.Date) {
+                return (java.sql.Date) source;
+            }
+            return new java.sql.Date(source.getTime());
         }
     }
 
     /**
-     * Converter from dates to timestamps. This converter is not injective, because
-     * the same date could be mapped to many timestamps since timestamps have an
-     * additional nanoseconds field.
+     * From {@code Date} to SQL {@code Timestamp}.
+     * The inverse of this converter is the identity conversion.
      */
-    @Immutable
-    static final class Timestamp extends DateConverter<java.sql.Timestamp> {
-        /** Cross-version compatibility. */ static final long serialVersionUID = 3798633184562706892L;
-        /** The unique, shared instance. */ static final Timestamp INSTANCE = new Timestamp();
-        /** For {@link #INSTANCE} only.  */ private Timestamp() {}
+    private static final class Timestamp extends DateConverter<java.sql.Timestamp>
{
+        private static final long serialVersionUID = 3798633184562706892L;
+        static final Timestamp INSTANCE = new Timestamp();
 
-        @Override public Class<java.sql.Timestamp> getTargetClass() {
-            return java.sql.Timestamp.class;
+        private Timestamp() {
+            super(java.sql.Timestamp.class);
         }
 
         @Override public java.sql.Timestamp convert(final Date source) {
-            return (source != null) ? new java.sql.Timestamp(source.getTime()) : null;
-        }
-
-        /** Returns the singleton instance on deserialization. */
-        Object readResolve() throws ObjectStreamException {
-            return INSTANCE;
+            if (source == null || source instanceof java.sql.Timestamp) {
+                return (java.sql.Timestamp) source;
+            }
+            return new java.sql.Timestamp(source.getTime());
         }
     }
 }

Modified: 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/HeuristicRegistry.java?rev=1457152&r1=1457151&r2=1457152&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/HeuristicRegistry.java
[UTF-8] Fri Mar 15 22:32:44 2013
@@ -16,11 +16,11 @@
  */
 package org.apache.sis.internal.converter;
 
+import java.util.Date;
 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.internal.util.SystemListener;
 
 
 /**
@@ -46,22 +46,9 @@ public final class HeuristicRegistry ext
      *
      * {@section Adding system-wide converters}
      * Applications can add system-wide custom providers either by explicit call to the
-     * {@link #register(ObjectConverter)} method on the system converter, or by listing
-     * the fully qualified classnames of their {@link ObjectConverter} instances in the
-     * following file (see {@link ServiceLoader} for more info about services loading):
-     *
-     * {@preformat text
-     *     META-INF/services/org.apache.sis.util.converter.ObjectConverter
-     * }
+     * {@link #register(ObjectConverter)} method on the system converter.
      */
     public static final ConverterRegistry SYSTEM = new HeuristicRegistry();
-    static {
-        SystemListener.add(new SystemListener() {
-            @Override protected void classpathChanged() {
-                SYSTEM.clear();
-            }
-        });
-    }
 
     /**
      * Creates an initially empty set of object converters. The heuristic
@@ -72,7 +59,10 @@ public final class HeuristicRegistry ext
 
     /**
      * Create dynamically the converters for a few special cases.
+     * This method is invoked only the first time that a new pair of source and target classes
is
+     * requested. Then, the value returned by this method will be cached for future invocations.
      *
+     * <p>Some (not all) special cases are:</p>
      * <ul>
      *   <li>If the source class is {@link CharSequence}, tries to delegate to an other
      *       converter accepting {@link String} sources.</li>
@@ -87,25 +77,61 @@ public final class HeuristicRegistry ext
     @SuppressWarnings({"unchecked","rawtypes"})
     protected <S,T> ObjectConverter<S,T> createConverter(final Class<S>
sourceClass, final Class<T> targetClass) {
         /*
-         * Before to try any heuristic rule, check for the identity converter.
+         * Most methods in this package are provided in such a way that we need to look at
the
+         * source class first, then at the target class. However before to perform those
usual
+         * checks, we need to check for the inverse conversions below. The reason is that
some
+         * of them are identity conversion (e.g. going from java.sql.Date to java.util.Date),
+         * but we don't want to leave the creation of those identity tranforms to the parent
+         * class because it doesn't know what are the inverse of those inverse conversions
+         * (i.e. the direct conversions). For example if the conversion from java.sql.Date
+         * 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)) {
+                return findExact(targetClass, sourceClass).inverse();
+            }
+        }
+        /*
+         * After we checked for the above special-cases, check for the identity converter.
+         * We need this check before to continue because some of the code below may create
+         * a "real" converter for what was actually an identity operation.
          */
         final ObjectConverter<S,T> identity = super.createConverter(sourceClass, targetClass);
         if (identity != null) {
             return identity;
         }
         /*
-         * From CharSequence to anything.
+         * From CharSequence to anything. Note that this check shall be done only after we
have
+         * determined that the conversion is not the identity conversion (i.e. the target
is not
+         * CharSequence or Object), otherwise this converter would apply useless toString().
          */
         if (sourceClass == CharSequence.class) {
             return (ObjectConverter<S,T>) new CharSequenceConverter<>(
                     targetClass, find(String.class, targetClass));
         }
         /*
-         * From String to various kind of CodeList.
+         * From String to various kind of objects.
          */
-        if (sourceClass == String.class && CodeList.class.isAssignableFrom(targetClass))
{
-            return (ObjectConverter<S,T>) new StringConverter.CodeList<>(
-                    targetClass.asSubclass(CodeList.class));
+        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));
+            }
         }
         /*
          * From Number to other kinds of Number.
@@ -121,6 +147,21 @@ public final class HeuristicRegistry ext
                         sourceClass.asSubclass(Number.class));
             }
         }
+        /*
+         * 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;
+            }
+        }
+        /*
+         * From various objects to String.
+         */
+        if (targetClass == String.class) {
+            return (ObjectConverter<S,T>) new ObjectToString<>(sourceClass, null);
+        }
         return null;
     }
 

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.java?rev=1457152&r1=1457151&r2=1457152&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.java
[UTF-8] Fri Mar 15 22:32:44 2013
@@ -19,6 +19,7 @@ package org.apache.sis.internal.converte
 import java.util.Set;
 import java.util.EnumSet;
 import net.jcip.annotations.Immutable;
+import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.math.FunctionProperty;
 
 
@@ -43,13 +44,26 @@ public final class IdentityConverter<S e
     private static final long serialVersionUID = -7203549932226245206L;
 
     /**
+     * The inverse converter specified at construction time, or {@code null} if none.
+     */
+    private final ObjectConverter<T, S> inverse;
+
+    /**
      * Creates a new identity converter.
      *
      * @param sourceClass The {@linkplain #getSourceClass() source class}.
      * @param targetClass The {@linkplain #getTargetClass() target class}.
+     * @param inverse     The inverse converter, or {@code null} if none.
      */
-    public IdentityConverter(final Class<S> sourceClass, final Class<T> targetClass)
{
+    @SuppressWarnings("unchecked")
+    public IdentityConverter(final Class<S> sourceClass, final Class<T> targetClass,
+            ObjectConverter<T, S> inverse)
+    {
         super(sourceClass, targetClass);
+        if (inverse == null && sourceClass == targetClass) {
+            inverse = (ObjectConverter<T,S>) this;
+        }
+        this.inverse = inverse;
     }
 
     /**
@@ -63,14 +77,21 @@ public final class IdentityConverter<S e
     @Override
     public Set<FunctionProperty> properties() {
         final EnumSet<FunctionProperty> properties = EnumSet.allOf(FunctionProperty.class);
-        if (sourceClass != targetClass) {
-            // Conservative choice (actually we don't really know).
+        if (inverse == null) {
             properties.remove(FunctionProperty.INVERTIBLE);
         }
         return properties;
     }
 
     /**
+     * Returns the inverse converter, if any.
+     */
+    @Override
+    public ObjectConverter<T,S> inverse() throws UnsupportedOperationException {
+        return (inverse != null) ? inverse : super.inverse();
+    }
+
+    /**
      * Returns the given object unchanged.
      *
      * @param source The value to convert.

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=1457152&r1=1457151&r2=1457152&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] Fri Mar 15 22:32:44 2013
@@ -27,7 +27,7 @@ import org.apache.sis.util.resources.Err
 
 
 /**
- * Handles conversions from {@link java.lang.Number} to other numbers.
+ * Handles conversions from {@link java.lang.Number} to other kind of numbers.
  * This class supports only the type supported by {@link Numbers}.
  *
  * {@section Performance note}
@@ -73,6 +73,9 @@ 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.
+     * We do not provide pre-defined constant for the various converter because there
+     * is too many possibly combinations.
      */
     @Override
     public ObjectConverter<T,S> inverse() throws UnsupportedOperationException {
@@ -140,7 +143,7 @@ final class NumberConverter<S extends Nu
          */
         @Override
         public Set<FunctionProperty> properties() {
-            if (Comparable.class.isAssignableFrom(sourceClass)) {
+            if (targetClass.isAssignableFrom(sourceClass)) {
                 return EnumSet.of(FunctionProperty.INJECTIVE, FunctionProperty.SURJECTIVE,
                             FunctionProperty.ORDER_PRESERVING);
             }

Modified: 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=1457152&r1=1457151&r2=1457152&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java
[UTF-8] Fri Mar 15 22:32:44 2013
@@ -84,14 +84,14 @@ class ObjectToString<S> extends SystemCo
      */
     @Override
     public final ObjectConverter<String, S> inverse() {
-        return inverse;
+        return (inverse != null) ? inverse : super.inverse();
     }
 
     /**
      * Returns the singleton instance on deserialization, if any.
      */
     @Override
-    public ObjectConverter<S, String> unique() {
+    public final ObjectConverter<S, String> unique() {
         if (inverse != null) {
             return inverse.unique().inverse(); // Will typically delegate to StringConverter.
         }

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=1457152&r1=1457151&r2=1457152&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] Fri Mar 15 22:32:44 2013
@@ -132,10 +132,10 @@ abstract class StringConverter<T> extend
      * Returns the singleton instance on deserialization, if any.
      */
     @Override
-    public ObjectConverter<String, T> unique() {
+    public final ObjectConverter<String, T> unique() {
         assert sourceClass == String.class : sourceClass;
         final StringConverter<T> instance = getInstance(targetClass);
-        return (instance != null) ? instance : this;
+        return (instance != null) ? instance : super.unique();
     }
 
     /**

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=1457152&r1=1457151&r2=1457152&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] Fri
Mar 15 22:32:44 2013
@@ -525,7 +525,9 @@ public final class Numbers extends Stati
             case DOUBLE:  return (N) Double .valueOf(number.doubleValue());
             case BIG_INTEGER: {
                 final BigInteger c;
-                if (number instanceof BigDecimal) {
+                if (number instanceof BigInteger) {
+                    c = (BigInteger) number;
+                } else if (number instanceof BigDecimal) {
                     c = ((BigDecimal) number).toBigInteger();
                 } else {
                     c = BigInteger.valueOf(number.longValue());
@@ -534,8 +536,10 @@ public final class Numbers extends Stati
             }
             case BIG_DECIMAL: {
                 final BigDecimal c;
-                if (number instanceof BigInteger) {
-                    c =new BigDecimal((BigInteger) number);
+                if (number instanceof BigDecimal) {
+                    c = (BigDecimal) number;
+                } else if (number instanceof BigInteger) {
+                    c = new BigDecimal((BigInteger) number);
                 } else if (isInteger(number.getClass())) {
                     c = BigDecimal.valueOf(number.longValue());
                 } else {

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=1457152&r1=1457151&r2=1457152&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] Fri Mar 15 22:32:44 2013
@@ -78,7 +78,7 @@ public final class ObjectConverters exte
      */
     public static <T> ObjectConverter<T,T> identity(final Class<T> type)
{
         ArgumentChecks.ensureNonNull("type", type);
-        return new IdentityConverter<>(type, type).unique();
+        return new IdentityConverter<>(type, type, null).unique();
     }
 
     /**

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/HeuristicRegistryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/HeuristicRegistryTest.java?rev=1457152&r1=1457151&r2=1457152&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/HeuristicRegistryTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/internal/converter/HeuristicRegistryTest.java
[UTF-8] Fri Mar 15 22:32:44 2013
@@ -16,17 +16,22 @@
  */
 package org.apache.sis.internal.converter;
 
+import java.io.File;
+import java.util.Date;
+import org.opengis.metadata.spatial.PixelOrientation;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static org.opengis.test.Assert.*;
+import static org.apache.sis.test.Assert.*;
 import static org.apache.sis.internal.converter.HeuristicRegistry.SYSTEM;
 
 
 /**
  * Tests the {@link HeuristicRegistry#SYSTEM} constant.
+ * This class shall not perform any conversion tests; it shall only checks the registrations.
+ * Conversion tests are the purpose of other test classes in this package.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
@@ -36,15 +41,78 @@ import static org.apache.sis.internal.co
 @DependsOn(ConverterRegistryTest.class)
 public final strictfp class HeuristicRegistryTest extends TestCase {
     /**
+     * Tests the creation of {@link StringConverter}.
+     */
+    @Test
+    public void testStringFile() {
+        final ObjectConverter<String,File> c1 = SYSTEM.findExact(String.class, File.class);
+        final ObjectConverter<File,String> c2 = SYSTEM.findExact(File.class, String.class);
+        assertInstanceOf("File ← String", StringConverter.class, c1);
+        assertInstanceOf("String ← File", ObjectToString.class,  c2);
+        assertSame("inverse()", c2, c1.inverse());
+        assertSame("inverse()", c1, c2.inverse());
+        assertSame(c1, assertSerializedEquals(c1));
+        assertSame(c2, assertSerializedEquals(c2));
+    }
+
+    /**
+     * Tests the creation of code list converter.
+     */
+    @Test
+    public void testStringCodeList() {
+        final ObjectConverter<String, PixelOrientation> c1 = SYSTEM.findExact(String.class,
PixelOrientation.class);
+        final ObjectConverter<PixelOrientation, String> c2 = SYSTEM.findExact(PixelOrientation.class,
String.class);
+        assertInstanceOf("PixelOrientation ← String", StringConverter.class, c1);
+        assertInstanceOf("String ← PixelOrientation", ObjectToString.class,  c2);
+        assertSame("inverse()", c2, c1.inverse());
+        assertSame("inverse()", c1, c2.inverse());
+        assertSame(c1, assertSerializedEquals(c1));
+        assertSame(c2, assertSerializedEquals(c2));
+    }
+
+    /**
      * Tests the creation of {@link NumberConverter}.
      */
     @Test
-    public void testSystem() {
+    public void testFloatDouble() {
         final ObjectConverter<Float,Double> c1 = SYSTEM.findExact(Float.class, Double.class);
         final ObjectConverter<Double,Float> c2 = SYSTEM.findExact(Double.class, Float.class);
         assertInstanceOf("Double ← Float", NumberConverter.class, c1);
         assertInstanceOf("Float ← Double", NumberConverter.class, c2);
         assertSame("inverse()", c2, c1.inverse());
         assertSame("inverse()", c1, c2.inverse());
+        assertSame(c1, assertSerializedEquals(c1));
+        assertSame(c2, assertSerializedEquals(c2));
+    }
+
+    /**
+     * Tests the creation of {@link DateConverter}.
+     */
+    @Test
+    public void testDateLong() {
+        final ObjectConverter<Date,Long> c1 = SYSTEM.findExact(Date.class, Long.class);
+        final ObjectConverter<Long,Date> c2 = SYSTEM.findExact(Long.class, Date.class);
+        assertInstanceOf("Long ← Date", DateConverter.class,   c1);
+        assertInstanceOf("Date ← Long", SystemConverter.class, c2);
+        assertSame("inverse()", c2, c1.inverse());
+        assertSame("inverse()", c1, c2.inverse());
+        assertSame(c1, assertSerializedEquals(c1));
+        assertSame(c2, assertSerializedEquals(c2));
+    }
+
+    /**
+     * Tests the creation of {@link DateConverter} from {@code java.util.Date}
+     * to {@code java.sql.Date}. The inverse converter is an identity converter.
+     */
+    @Test
+    public void testDateSQL() {
+        final ObjectConverter<Date, java.sql.Date> c1 = SYSTEM.findExact(Date.class,
java.sql.Date.class);
+        final ObjectConverter<java.sql.Date, Date> c2 = SYSTEM.findExact(java.sql.Date.class,
Date.class);
+        assertInstanceOf("sql.Date ← Date", DateConverter.class,     c1);
+        assertInstanceOf("Date ← sql.Date", IdentityConverter.class, c2);
+        assertSame("inverse()", c2, c1.inverse());
+        assertSame("inverse()", c1, c2.inverse());
+        assertSame(c1, assertSerializedEquals(c1));
+        assertSame(c2, assertSerializedEquals(c2));
     }
 }



Mime
View raw message