sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1625169 [2/2] - in /sis/branches/JDK6: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/ core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ core/sis-metadata/src/main/java/org/apache/sis/...
Date Mon, 15 Sep 2014 21:45:27 GMT
Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -54,10 +54,10 @@ public final strictfp class DefaultParam
         final Class<Integer> type = Integer.class;
         final Map<String,Object> properties = new HashMap<String,Object>(4);
         M1_M1_O1_O2 = new DefaultParameterDescriptorGroup(singletonMap(NAME_KEY, "Test group"), 0, 1,
-            new DefaultParameterDescriptor<Integer>(name(properties, "Mandatory 1", "Ambiguity"), type, null, null, DEFAULT_VALUE, true),
-            new DefaultParameterDescriptor<Integer>(name(properties, "Mandatory 2", "Alias 2"),   type, null, null, DEFAULT_VALUE, true),
-            new DefaultParameterDescriptor<Integer>(name(properties,  "Optional 3", "Alias 3"),   type, null, null, DEFAULT_VALUE, false),
-            new MultiOccurrenceDescriptor <Integer>(name(properties,  "Optional 4", "Ambiguity"), type, null, null, DEFAULT_VALUE, false)
+            new DefaultParameterDescriptor<Integer>(name(properties, "Mandatory 1", "Ambiguity"), 1, 1, type, null, null, DEFAULT_VALUE),
+            new DefaultParameterDescriptor<Integer>(name(properties, "Mandatory 2", "Alias 2"),   1, 1, type, null, null, DEFAULT_VALUE),
+            new DefaultParameterDescriptor<Integer>(name(properties, "Optional 3", "Alias 3"),    0, 1, type, null, null, DEFAULT_VALUE),
+            new DefaultParameterDescriptor<Integer>(name(properties, "Optional 4", "Ambiguity"),  0, 2, type, null, null, DEFAULT_VALUE)
         );
     }
 
@@ -78,8 +78,8 @@ public final strictfp class DefaultParam
         final Class<Integer> type = Integer.class;
         final Map<String,Object> properties = new HashMap<String,Object>(4);
         final DefaultParameterDescriptor<Integer> p1, p2;
-        p1 = new DefaultParameterDescriptor<Integer>(name(properties, "Name", null), type, null, null, null, true);
-        p2 = new DefaultParameterDescriptor<Integer>(name(properties, "  NAME ", null), type, null, null, null, true);
+        p1 = new DefaultParameterDescriptor<Integer>(name(properties,    "Name", null), 1, 1, type, null, null, null);
+        p2 = new DefaultParameterDescriptor<Integer>(name(properties, "  NAME ", null), 1, 1, type, null, null, null);
         try {
             new DefaultParameterDescriptorGroup(singletonMap(NAME_KEY, "Test group"), 0, 1, p1, p2);
             fail("Constructor should have detected the duplicated names.");
@@ -102,7 +102,7 @@ public final strictfp class DefaultParam
             } catch (AssertionError e) {
                 error = e;
             }
-            if (descriptor instanceof MultiOccurrenceDescriptor) {
+            if (descriptor.getMaximumOccurs() > 1) {
                 assertNotNull("Validation methods should have detected that the descriptor is invalid.", error);
             } else if (error != null) {
                 throw error;

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorTest.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorTest.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -65,7 +65,7 @@ public final strictfp class DefaultParam
      * @return The parameter descriptor.
      */
     static <T> DefaultParameterDescriptor<T> createSimpleOptional(final String name, final Class<T> type) {
-        return new DefaultParameterDescriptor<T>(properties(name), type, null, null, null, false);
+        return new DefaultParameterDescriptor<T>(properties(name), 0, 1, type, null, null, null);
     }
 
     /**
@@ -80,8 +80,8 @@ public final strictfp class DefaultParam
     static DefaultParameterDescriptor<Integer> create(final String name,
             final int minimumValue, final int maximumValue, final int defaultValue)
     {
-        return new DefaultParameterDescriptor<Integer>(properties(name), Integer.class,
-                NumberRange.create(minimumValue, true, maximumValue, true), null, Integer.valueOf(defaultValue), true);
+        return new DefaultParameterDescriptor<Integer>(properties(name), 1, 1, Integer.class,
+                NumberRange.create(minimumValue, true, maximumValue, true), null, Integer.valueOf(defaultValue));
     }
 
     /**
@@ -97,9 +97,9 @@ public final strictfp class DefaultParam
     static DefaultParameterDescriptor<Double> create(final String name,
             final double minimumValue, final double maximumValue, final double defaultValue, final Unit<?> unit)
     {
-        return new DefaultParameterDescriptor<Double>(properties(name), Double.class,
+        return new DefaultParameterDescriptor<Double>(properties(name), 1, 1, Double.class,
                 MeasurementRange.create(minimumValue, true, maximumValue, true, unit), null,
-                Double.isNaN(defaultValue) ? null : Double.valueOf(defaultValue), true);
+                Double.isNaN(defaultValue) ? null : Double.valueOf(defaultValue));
     }
 
     /**
@@ -115,7 +115,7 @@ public final strictfp class DefaultParam
     static <T> DefaultParameterDescriptor<T> create(final String name, final Class<T> type,
             final T[] validValues, final T defaultValue)
     {
-        return new DefaultParameterDescriptor<T>(properties(name), type, null, validValues, defaultValue, true);
+        return new DefaultParameterDescriptor<T>(properties(name), 1, 1, type, null, validValues, defaultValue);
     }
 
     /**
@@ -131,7 +131,7 @@ public final strictfp class DefaultParam
             final double minimumValue, final double maximumValue, final Unit<?> unit)
     {
         final MeasurementRange<Double> valueDomain = MeasurementRange.create(minimumValue, true, maximumValue, true, unit);
-        return new DefaultParameterDescriptor<double[]>(properties(name), double[].class, valueDomain, null, null, true);
+        return new DefaultParameterDescriptor<double[]>(properties(name), 1, 1, double[].class, valueDomain, null, null);
     }
 
     /**
@@ -210,7 +210,7 @@ public final strictfp class DefaultParam
     public void testStringType() {
         final Range<String> valueDomain = new Range<String>(String.class, "AAA", true, "BBB", true);
         final DefaultParameterDescriptor<String> descriptor = new DefaultParameterDescriptor<String>(
-                properties("String param"), String.class, valueDomain, null, "ABC", false);
+                properties("String param"), 0, 1, String.class, valueDomain, null, "ABC");
         assertEquals("name", "String param",     descriptor.getName().getCode());
         assertEquals("valueClass", String.class, descriptor.getValueClass());
         assertNull  ("validValues",              descriptor.getValidValues());
@@ -277,8 +277,8 @@ public final strictfp class DefaultParam
          * Invalid operation: wrong type of range value.
          */
         try {
-            new DefaultParameterDescriptor<double[]>(properties("Array param"), double[].class,
-                    NumberRange.create(4, true, 9, true), null, null, false);
+            new DefaultParameterDescriptor<double[]>(properties("Array param"), 0, 1,
+                    double[].class, NumberRange.create(4, true, 9, true), null, null);
         } catch (IllegalArgumentException e) {
             assertEquals("Argument ‘valueDomain’ can not be an instance of ‘Range<Integer>’.", e.getMessage());
         }

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueGroupTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueGroupTest.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueGroupTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueGroupTest.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -103,7 +103,7 @@ public final strictfp class DefaultParam
             } catch (AssertionError e) {
                 error = e;
             }
-            if (param.getDescriptor() instanceof MultiOccurrenceDescriptor) {
+            if (param.getDescriptor().getMaximumOccurs() > 1) {
                 assertNotNull("Validation methods should have detected that the descriptor is invalid.", error);
             } else if (error != null) {
                 throw error;
@@ -238,7 +238,7 @@ public final strictfp class DefaultParam
         final DefaultParameterValueGroup    group = createGroup(10);
         final List<GeneralParameterValue>  values = group.values();
         final ParameterValue<Integer> nonExistent = new DefaultParameterDescriptor<Integer>(
-                singletonMap(NAME_KEY, "Optional 5"), Integer.class, null, null, null, false).createValue();
+                singletonMap(NAME_KEY, "Optional 5"), 0, 1, Integer.class, null, null, null).createValue();
         try {
             values.add(nonExistent);
             fail("“Optional 5” is not a parameter for this group.");

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -30,7 +30,8 @@ import org.apache.sis.internal.util.Cita
 import org.apache.sis.util.iso.DefaultNameSpace;
 import org.apache.sis.util.LenientComparable;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.Utilities;
+
+import static org.apache.sis.util.collection.Containers.isNullOrEmpty;
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk7.Objects;
@@ -44,6 +45,8 @@ import org.apache.sis.internal.jdk7.Obje
  * @since   0.5 (derived from geotk-3.00)
  * @version 0.3
  * @module
+ *
+ * @see org.apache.sis.referencing.AbstractIdentifiedObject
  */
 public class SimpleIdentifiedObject implements IdentifiedObject, LenientComparable, Serializable {
     /**
@@ -95,10 +98,13 @@ public class SimpleIdentifiedObject impl
      * Method required by the {@link IdentifiedObject} interface.
      * Current implementation returns an empty set.
      *
+     * <p>If a future version allows this method to returns a non-empty set,
+     * revisit {@link #equals(Object, ComparisonMode)}.</p>
+     *
      * @return The identifiers, or an empty set if none.
      */
     @Override
-    public Set<ReferenceIdentifier> getIdentifiers() {
+    public final Set<ReferenceIdentifier> getIdentifiers() {
         return Collections.emptySet();
     }
 
@@ -106,10 +112,13 @@ public class SimpleIdentifiedObject impl
      * Method required by the {@link IdentifiedObject} interface.
      * Current implementation returns an empty set.
      *
+     * <p>If a future version allows this method to returns a non-empty set,
+     * revisit {@link #equals(Object, ComparisonMode)}.</p>
+     *
      * @return The aliases, or an empty set if none.
      */
     @Override
-    public Collection<GenericName> getAlias() {
+    public final Collection<GenericName> getAlias() {
         return Collections.emptySet();
     }
 
@@ -117,9 +126,12 @@ public class SimpleIdentifiedObject impl
      * Method required by most {@link IdentifiedObject} sub-interfaces.
      * Current implementation returns {@code null}.
      *
+     * <p>If a future version allows this method to returns a non-null value,
+     * revisit {@link #equals(Object, ComparisonMode)} in subclasses.</p>
+     *
      * @return The domain of validity, or {@code null} if none.
      */
-    public Extent getDomainOfValidity() {
+    public final Extent getDomainOfValidity() {
         return null;
     }
 
@@ -127,9 +139,12 @@ public class SimpleIdentifiedObject impl
      * Method required by most {@link IdentifiedObject} sub-interfaces.
      * Current implementation returns {@code null}.
      *
+     * <p>If a future version allows this method to returns a non-null value,
+     * revisit {@link #equals(Object, ComparisonMode)} in subclasses.</p>
+     *
      * @return The scope, or {@code null} if none.
      */
-    public InternationalString getScope() {
+    public final InternationalString getScope() {
         return null;
     }
 
@@ -137,10 +152,13 @@ public class SimpleIdentifiedObject impl
      * Method required by the {@link IdentifiedObject} interface.
      * Current implementation returns {@code null}.
      *
+     * <p>If a future version allows this method to returns a non-null value,
+     * revisit {@link #equals(Object, ComparisonMode)}.</p>
+     *
      * @return The remarks, or {@code null} if none.
      */
     @Override
-    public InternationalString getRemarks() {
+    public final InternationalString getRemarks() {
         return null;
     }
 
@@ -150,7 +168,7 @@ public class SimpleIdentifiedObject impl
     @Override
     public final int hashCode() {
         int code = (int) serialVersionUID;
-        final ReferenceIdentifier name = this.name;
+        final ReferenceIdentifier name = getName();
         if (name != null) {
             code ^= name.hashCode();
         }
@@ -170,6 +188,9 @@ public class SimpleIdentifiedObject impl
 
     /**
      * Compares this object with the given one for equality.
+     * This method compares the {@linkplain #name} only in "strict" or "by contract" modes.
+     * If name is a critical component of this object, then it shall be compared by the subclass.
+     * This behavior is consistent with {@link org.apache.sis.referencing.AbstractIdentifiedObject}.
      *
      * @param  object The object to compare with this reference system.
      * @param  mode The strictness level of the comparison.
@@ -180,15 +201,16 @@ public class SimpleIdentifiedObject impl
         if (object == this) {
             return true;
         }
-        if (mode == ComparisonMode.STRICT) {
-            if (object != null && object.getClass() == getClass()) {
-                final SimpleIdentifiedObject that = (SimpleIdentifiedObject) object;
-                return Objects.equals(name, that.name);
-            }
-        } else {
-            if (object instanceof IdentifiedObject) {
+        if (object instanceof IdentifiedObject) {
+            if (mode != ComparisonMode.STRICT || object.getClass() == getClass()) {
                 final IdentifiedObject that = (IdentifiedObject) object;
-                return Utilities.deepEquals(name, that.getName(), mode);
+                if (mode.ordinal() >= ComparisonMode.IGNORE_METADATA.ordinal()) {
+                    return true;
+                }
+                return Objects.equals(getName(), that.getName()) &&
+                        isNullOrEmpty(that.getIdentifiers()) &&
+                        isNullOrEmpty(that.getAlias()) &&
+                        that.getRemarks() == null;
             }
         }
         return false;
@@ -222,7 +244,7 @@ public class SimpleIdentifiedObject impl
             codespace = null;
             authority = null;
         }
-        final StringBuilder buffer = new StringBuilder("OBJECT[\"");
+        final StringBuilder buffer = new StringBuilder("IdentifiedObject[\"");
         if (codespace != null) {
             buffer.append(codespace).append(DefaultNameSpace.DEFAULT_SEPARATOR);
         }

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -213,7 +213,7 @@ public final class Classes extends Stati
                  */
                 if (type instanceof ParameterizedType) {
                     // Example: replace ParameterDescriptor<?> by ParameterDescriptor
-                    // before we test for instance of Class.
+                    // before we test if (type instanceof Class<?>).
                     type = ((ParameterizedType) type).getRawType();
                 }
                 int dimension = 0;

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/UnsupportedImplementationException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/UnsupportedImplementationException.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/UnsupportedImplementationException.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/UnsupportedImplementationException.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -20,10 +20,10 @@ import org.apache.sis.util.resources.Err
 
 
 /**
- * Thrown when an operation can't use arbitrary implementation of an interface, and
- * a given instance doesn't meet the requirement. For example this exception may be
- * thrown when an operation requires an Apache SIS implementation of a
- * <A HREF="http://www.geoapi.org">GeoAPI</A> interface.
+ * Thrown when an operation can not use arbitrary implementation of an interface,
+ * and a given instance does not meet the requirement. For example this exception
+ * may be thrown when an operation requires an Apache SIS implementation of a
+ * <a href="http://www.geoapi.org">GeoAPI</a> interface.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3 (derived from geotk-2.0)

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Utilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Utilities.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Utilities.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Utilities.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
+import org.apache.sis.util.collection.CheckedContainer;
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk7.Objects;
@@ -229,7 +230,7 @@ public final class Utilities extends Sta
         final Iterator<?> it2 = object2.iterator();
         while (it1.hasNext()) {
             if (!it2.hasNext()) {
-                assert isNotDebug(mode) : "Sizes not equal";
+                assert isNotDebug(mode) : mismatchedElement("Iterable", object1, object2, "size");
                 return false;
             }
             Object element1 = it1.next();
@@ -238,7 +239,7 @@ public final class Utilities extends Sta
                 continue;
             }
             if (!(object1 instanceof Set<?> && object2 instanceof Set<?>)) {
-                assert isNotDebug(mode) : "Lists not equal";
+                assert isNotDebug(mode) : mismatchedElement("Iterable", object1, object2, "element");
                 return false;
             }
             /*
@@ -258,7 +259,7 @@ public final class Utilities extends Sta
             while (true) {
                 final Iterator<?> it = copy.iterator();
                 do if (!it.hasNext()) {
-                    assert isNotDebug(mode) : "Sets not equal";
+                    assert isNotDebug(mode) : mismatchedElement("Set", object1, object2, "element");
                     return false; // An element has not been found.
                 } while (!deepEquals(it.next(), element2, mode));
                 it.remove();
@@ -293,6 +294,20 @@ public final class Utilities extends Sta
     }
 
     /**
+     * Returns an assertion error message for mismatched collections.
+     */
+    private static String mismatchedElement(final String header, final Iterable<?> object1, final Iterable<?> object2, final String tail) {
+        Class<?> type = null;
+        if (object1 instanceof CheckedContainer<?>) {
+            type = ((CheckedContainer<?>) object1).getElementType();
+        }
+        if (type == null && object2 instanceof CheckedContainer<?>) {
+            type = ((CheckedContainer<?>) object2).getElementType();
+        }
+        return header + '<' + (type != null ? type.getSimpleName() : "?") + ">: " + tail + " not equals.";
+    }
+
+    /**
      * Returns a hash code for the specified object, which may be an array.
      * This method returns one of the following values:
      *

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -44,9 +44,10 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * <p>{@code DefaultLocalName} can be instantiated by any of the following methods:</p>
  * <ul>
- *   <li>{@link DefaultNameFactory#createLocalName(NameSpace, CharSequence)}</li>
- *   <li>{@link DefaultNameFactory#createGenericName(NameSpace, CharSequence[])} with an array of length 1</li>
- *   <li>{@link DefaultNameFactory#parseGenericName(NameSpace, CharSequence)} without separator</li>
+ *   <li>{@link DefaultNameFactory#createLocalName(NameSpace, CharSequence)}.</li>
+ *   <li>{@link DefaultNameFactory#createGenericName(NameSpace, CharSequence[])} with an array of length 1.</li>
+ *   <li>{@link DefaultNameFactory#parseGenericName(NameSpace, CharSequence)} with no occurrence of the separator in the path.</li>
+ *   <li>Similar static convenience methods in {@link Names}.</li>
  * </ul>
  *
  * {@section Immutability and thread safety}

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -35,6 +35,7 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * <ul>
  *   <li>{@link DefaultNameFactory#createMemberName(NameSpace, CharSequence, TypeName)}</li>
+ *   <li>Similar static convenience method in {@link Names}.</li>
  * </ul>
  *
  * {@section Immutability and thread safety}

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -31,7 +31,6 @@ import org.opengis.util.GenericName;
 import org.opengis.util.NameFactory;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.NullArgumentException;
 import org.apache.sis.util.collection.WeakHashSet;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -61,6 +60,7 @@ import static org.apache.sis.util.iso.De
  * <ul>
  *   <li>{@link #parseGenericName(NameSpace, CharSequence)}</li>
  *   <li>{@link #toGenericNames(Object)}</li>
+ *   <li>{@link #toTypeName(Class)}</li>
  * </ul>
  *
  * {@section Thread safety}
@@ -82,11 +82,26 @@ import static org.apache.sis.util.iso.De
  */
 public class DefaultNameFactory extends AbstractFactory implements NameFactory {
     /**
+     * The key for name separator.
+     */
+    static final String SEPARATOR_KEY = "separator";
+
+    /**
+     * The key or the separator after the first name.
+     */
+    static final String HEAD_SEPARATOR_KEY = "separator.head";
+
+    /**
      * Weak references to the name created by this factory.
      */
     private final WeakHashSet<GenericName> pool;
 
     /**
+     * Helper class for mapping {@link Class} to {@link TypeName}, created when first needed.
+     */
+    private transient volatile TypeNames typeNames;
+
+    /**
      * Creates a new factory.
      */
     public DefaultNameFactory() {
@@ -167,18 +182,18 @@ public class DefaultNameFactory extends 
     @Override
     public NameSpace createNameSpace(final GenericName name, final Map<String,?> properties) {
         ensureNonNull("name", name);
-        String separator = getString(properties, "separator");
+        String separator = getString(properties, SEPARATOR_KEY);
         if (separator == null) {
             separator = DefaultNameSpace.DEFAULT_SEPARATOR_STRING;
         }
-        String headSeparator = getString(properties, "separator.head");
+        String headSeparator = getString(properties, HEAD_SEPARATOR_KEY);
         if (headSeparator == null) {
             headSeparator = separator;
         }
         final boolean isEmpty = separator.isEmpty();
         if (isEmpty || headSeparator.isEmpty()) {
             throw new IllegalArgumentException(Errors.format(
-                    Errors.Keys.EmptyProperty_1, isEmpty ? "separator" : "separator.head"));
+                    Errors.Keys.EmptyProperty_1, isEmpty ? SEPARATOR_KEY : HEAD_SEPARATOR_KEY));
         }
         return DefaultNameSpace.forName(name.toFullyQualifiedName(), headSeparator, separator);
     }
@@ -191,7 +206,9 @@ public class DefaultNameFactory extends 
      *         name to be created, or {@code null} for a global namespace.
      * @param  name The type name as a string or an international string.
      * @return The type name for the given character sequence.
-     * @throws NullArgumentException If the {@code name} argument is null.
+     *
+     * @see #toTypeName(Class)
+     * @see Names#createTypeName(CharSequence, String, CharSequence)
      */
     @Override
     public TypeName createTypeName(final NameSpace scope, final CharSequence name) {
@@ -200,15 +217,13 @@ public class DefaultNameFactory extends 
 
     /**
      * Creates a member name from the given character sequence and attribute type.
-     * The default implementation returns a new or an existing {@link DefaultMemberName}
-     * instance.
+     * The default implementation returns a new or an existing {@link DefaultMemberName} instance.
      *
      * @param  scope The {@linkplain AbstractName#scope() scope} of the member
      *         name to be created, or {@code null} for a global namespace.
      * @param  name The member name as a string or an international string.
      * @param  attributeType The type of the data associated with the record member.
      * @return The member name for the given character sequence.
-     * @throws NullArgumentException If the {@code name} or {@code attributeType} argument is null.
      */
     @Override
     public MemberName createMemberName(final NameSpace scope, final CharSequence name, final TypeName attributeType) {
@@ -223,7 +238,6 @@ public class DefaultNameFactory extends 
      *         name to be created, or {@code null} for a global namespace.
      * @param  name The local name as a string or an international string.
      * @return The local name for the given character sequence.
-     * @throws NullArgumentException If the {@code name} argument is null.
      *
      * @see Names#createLocalName(CharSequence, String, CharSequence)
      */
@@ -251,7 +265,8 @@ public class DefaultNameFactory extends 
      * @param  parsedNames The local names as an array of {@link String} or {@link InternationalString} instances.
      *         This array shall contain at least one element.
      * @return The generic name for the given parsed names.
-     * @throws NullArgumentException If the given array is empty.
+     *
+     * @see #parseGenericName(NameSpace, CharSequence)
      */
     @Override
     public GenericName createGenericName(final NameSpace scope, final CharSequence... parsedNames) {
@@ -273,6 +288,8 @@ public class DefaultNameFactory extends 
      * @param  name The qualified name, as a sequence of names separated by a scope-dependent
      *         separator.
      * @return A name parsed from the given string.
+     *
+     * @see Names#parseGenericName(CharSequence, String, CharSequence)
      */
     @Override
     public GenericName parseGenericName(final NameSpace scope, final CharSequence name) {
@@ -371,8 +388,8 @@ public class DefaultNameFactory extends 
 
     /**
      * Creates a generic name from the given value. The value may be an instance of
-     * {@link GenericName}, {@link Identifier} or {@link CharSequence}. If the given
-     * object is not recognized, then this method returns {@code null}.
+     * {@link GenericName}, {@link Identifier}, {@link CharSequence} or {@link Class}.
+     * If the given object is not recognized, then this method returns {@code null}.
      *
      * @param  value The object to convert.
      * @return The converted object, or {@code null} if {@code value} is not convertible.
@@ -387,6 +404,56 @@ public class DefaultNameFactory extends 
         if (value instanceof CharSequence) {
             return parseGenericName(null, (CharSequence) value);
         }
+        if (value instanceof Class<?>) {
+            return toTypeName((Class<?>) value);
+        }
         return null;
     }
+
+    /**
+     * Suggests a type name for the given class. Apache SIS provides a mapping between {@code Class}
+     * and {@code TypeName} objects as documented in the {@link DefaultTypeName} javadoc.
+     *
+     * <p>In order to protect against potential changes in the {@code Class} ↔ {@code TypeName} mapping, users are
+     * encouraged to retrieve the {@code valueClass} by invoking the {@link Names#toClass(TypeName)} method instead
+     * than parsing the name.</p>
+     *
+     * @param  valueClass The Java class for which to get a type name, or {@code null}.
+     * @return A suggested type name, or {@code null} if the given class was null.
+     *
+     * @see DefaultTypeName#toClass()
+     * @see Names#toClass(TypeName)
+     *
+     * @since 0.5
+     */
+    public TypeName toTypeName(final Class<?> valueClass) {
+        if (!TypeNames.isValid(valueClass)) {
+            return null;
+        }
+        /*
+         * Note: we do not cache the TypeName for the valueClass argument because:
+         *
+         *  - It is not needed (at least in the default implementation) for getting unique instance.
+         *  - It is not the best place for performance improvement, since TypeName are usually only
+         *    a step in the creation of bigger object (typically AttributeType). Users are better to
+         *    cache the bigger object instead.
+         */
+        TypeNames t = typeNames;
+        if (t == null) {
+            /*
+             * Create TypeNames outide the synchronized block because the TypeNames constructor will call back
+             * methods from this class. Since those methods are overrideable, this could invoke user's code.
+             * Note also that methods in this class use the 'pool', which is itself synchronized, so we are
+             * better to avoid double synchronization for reducing the risk of dead-lock.
+             */
+            final TypeNames c = new TypeNames(this);
+            synchronized (this) { // Double-check strategy is ok if 'typeNames' is volatile.
+                t = typeNames;
+                if (t == null) {
+                    typeNames = t = c;
+                }
+            }
+        }
+        return t.toTypeName(this, valueClass);
+    }
 }

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -17,10 +17,10 @@
 package org.apache.sis.util.iso;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Collections;
-import java.util.Date;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
 import org.opengis.util.Type;
 import org.opengis.util.TypeName;
 import org.opengis.util.LocalName;
@@ -30,7 +30,6 @@ import org.opengis.util.NameSpace;
 import org.opengis.util.RecordSchema;
 import org.opengis.util.RecordType;
 import org.apache.sis.util.Debug;
-import org.apache.sis.util.Numbers;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.ObjectConverters;
@@ -54,7 +53,7 @@ import org.apache.sis.internal.converter
  * by overriding the following methods:
  *
  * <ul>
- *   <li>{@link #toTypeName(Class)}</li>
+ *   <li>{@link DefaultNameFactory#toTypeName(Class)} if the factory given to the constructor.</li>
  * </ul>
  *
  * {@section Thread safety}
@@ -86,6 +85,12 @@ public class DefaultRecordSchema impleme
     protected final NameFactory nameFactory;
 
     /**
+     * The helper class to use for mapping Java classes to {@code TypeName} instances, or {@code null} if not needed.
+     * This helper class is needed only if {@link #nameFactory} is not an instance of {@link DefaultNameFactory}.
+     */
+    private final TypeNames typeFactory;
+
+    /**
      * The namespace of {@link RecordType} to be created by this class.
      * This is also (indirectly) the {@linkplain #getSchemaName() schema name}.
      */
@@ -98,9 +103,8 @@ public class DefaultRecordSchema impleme
 
     /**
      * The pool of attribute types created so far.
-     * Shall be used only in synchronized blocks.
      */
-    private final Map<Class<?>,Type> attributeTypes;
+    private final ConcurrentMap<Class<?>,Type> attributeTypes;
 
     /**
      * The converter to use for converting Java {@link Class} to ISO 19103 {@link Type}.
@@ -126,9 +130,10 @@ public class DefaultRecordSchema impleme
             nameFactory = DefaultFactories.NAMES;
         }
         this.nameFactory    = nameFactory;
+        this.typeFactory    = (nameFactory instanceof DefaultNameFactory) ? null : new TypeNames(nameFactory);
         this.namespace      = nameFactory.createNameSpace(nameFactory.createLocalName(parent, schemaName), null);
         this.description    = new WeakValueHashMap<TypeName,RecordType>(TypeName.class);
-        this.attributeTypes = new HashMap<Class<?>,Type>();
+        this.attributeTypes = new ConcurrentHashMap<Class<?>,Type>();
     }
 
     /**
@@ -189,80 +194,39 @@ public class DefaultRecordSchema impleme
     }
 
     /**
-     * Suggests an attribute type for the given value class. For a short list of known classes,
-     * this method returns the ISO 19103 type as used in XML documents. Examples:
-     *
-     * <table class="sis">
-     *   <caption>Attribute types for Java classes (non exhaustive list)</caption>
-     *   <tr><th>Java class</th>        <th>Attribute type</th></tr>
-     *   <tr><td>{@link String}</td>    <td>{@code gco:CharacterString}</td></tr>
-     *   <tr><td>{@link Date}</td>      <td>{@code gco:DateTime}</td></tr>
-     *   <tr><td>{@link Double}</td>    <td>{@code gco:Real}</td></tr>
-     *   <tr><td>{@link Integer}</td>   <td>{@code gco:Integer}</td></tr>
-     *   <tr><td>{@link Boolean}</td>   <td>{@code gco:Boolean}</td></tr>
-     * </table>
+     * Suggests an attribute type for the given value class. The {@code TypeName} will use the UML identifier
+     * of OGC/ISO specification when possible, e.g. {@code "GCO:CharacterString"} for {@code java.lang.String}.
+     * See <cite>Mapping Java classes to type names</cite> in {@link DefaultTypeName} javadoc for more information.
      *
      * @param  valueClass The value class to represent as an attribute type.
      * @return Attribute type for the given value class.
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
-    private Type toAttributeType(final Class<?> valueClass) {
-        Type type;
-        synchronized (attributeTypes) {
-            type = attributeTypes.get(valueClass);
+    final Type toAttributeType(final Class<?> valueClass) {
+        if (!TypeNames.isValid(valueClass)) {
+            return null;
         }
+        Type type = attributeTypes.get(valueClass);
         if (type == null) {
-            type = new SimpleAttributeType(toTypeName(valueClass), valueClass);
-            synchronized (attributeTypes) {
-                final Type old = attributeTypes.put(valueClass, type);
-                if (old != null) { // May happen if the type has been computed concurrently.
-                    attributeTypes.put(valueClass, old);
-                    return old;
-                }
+            if (valueClass == Void.TYPE) {
+                throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "valueClass", "void"));
+            }
+            final TypeName name;
+            if (nameFactory instanceof DefaultNameFactory) {
+                name = ((DefaultNameFactory) nameFactory).toTypeName(valueClass);
+            } else {
+                name = typeFactory.toTypeName(nameFactory, valueClass);
+            }
+            type = new SimpleAttributeType(name, valueClass);
+            final Type old = attributeTypes.putIfAbsent(valueClass, type);
+            if (old != null) { // May happen if the type has been computed concurrently.
+                return old;
             }
         }
         return type;
     }
 
     /**
-     * Suggests a type name for the given value class. For a short list of known classes,
-     * this method returns the ISO 19103 type name as used in XML documents. Examples:
-     *
-     * <table class="sis">
-     *   <caption>Type names for Java classes (non exhaustive list)</caption>
-     *   <tr><th>Java class</th>        <th>Type name</th></tr>
-     *   <tr><td>{@link String}</td>    <td>"{@code gco:CharacterString}"</td></tr>
-     *   <tr><td>{@link Date}</td>      <td>"{@code gco:DateTime}"</td></tr>
-     *   <tr><td>{@link Double}</td>    <td>"{@code gco:Real}"</td></tr>
-     *   <tr><td>{@link Integer}</td>   <td>"{@code gco:Integer}"</td></tr>
-     *   <tr><td>{@link Boolean}</td>   <td>"{@code gco:Boolean}"</td></tr>
-     * </table>
-     *
-     * Subclasses can override this method for defining more type names.
-     *
-     * @param  valueClass The value class for which to get a type name.
-     * @return Type name for the given value class.
-     */
-    protected TypeName toTypeName(final Class<?> valueClass) {
-        String ns = "gco";
-        final String name;
-        if (CharSequence.class.isAssignableFrom(valueClass)) {
-            name = "CharacterString";
-        } else if (Number.class.isAssignableFrom(valueClass)) {
-            name = Numbers.isInteger(valueClass) ? "Integer" : "Real";
-        } else if (Date.class.isAssignableFrom(valueClass)) {
-            name = "DateTime";
-        } else if (valueClass == Boolean.class) {
-            name = "Boolean";
-        } else {
-            ns   = "java";
-            name = valueClass.getCanonicalName();
-        }
-        return nameFactory.createTypeName(nameFactory.createNameSpace(
-                nameFactory.createLocalName(null, ns), null), name);
-    }
-
-    /**
      * Returns the dictionary of all (<var>name</var>, <var>record type</var>) pairs in this schema.
      *
      * @return All (<var>name</var>, <var>record type</var>) pairs in this schema.

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -37,8 +37,9 @@ import org.apache.sis.internal.util.Unmo
  *
  * <p>{@code DefaultScopedName} can be instantiated by any of the following methods:</p>
  * <ul>
- *   <li>{@link DefaultNameFactory#createGenericName(NameSpace, CharSequence[])} with an array of length 2 or more</li>
- *   <li>{@link DefaultNameFactory#parseGenericName(NameSpace, CharSequence)} with at least one separator</li>
+ *   <li>{@link DefaultNameFactory#createGenericName(NameSpace, CharSequence[])} with an array of length 2 or more.</li>
+ *   <li>{@link DefaultNameFactory#parseGenericName(NameSpace, CharSequence)} with at least one occurrence of the separator in the path.</li>
+ *   <li>Similar static convenience methods in {@link Names}.</li>
  * </ul>
  *
  * {@section Immutability and thread safety}

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -20,6 +20,7 @@ import javax.xml.bind.annotation.XmlType
 import javax.xml.bind.annotation.XmlRootElement;
 import org.opengis.util.TypeName;
 import org.opengis.util.NameSpace;
+import org.apache.sis.util.UnknownNameException;
 
 
 /**
@@ -28,8 +29,38 @@ import org.opengis.util.NameSpace;
  *
  * <ul>
  *   <li>{@link DefaultNameFactory#createTypeName(NameSpace, CharSequence)}</li>
+ *   <li>{@link DefaultNameFactory#toTypeName(Class)}</li>
  * </ul>
  *
+ * {@section Mapping Java classes to type names}
+ * It is sometime useful to establish a mapping between {@link Class} and {@code TypeName}.
+ * When an UML identifier from an OGC standard exists for a given {@code Class}, Apache SIS
+ * uses that identifier prefixed by the {@code "OGC"} namespace.
+ * Note that this is <strong>not</strong> a standard practice.
+ * A more standard practice would be to use the <cite>definition identifiers in OGC namespace</cite>
+ * (last column in the table below), but the set of data type identifiers defined by OGC is currently
+ * small and is sometime not an exact match.
+ *
+ * <table class="sis">
+ *   <caption>Mapping from Java classes to type names (non-exhaustive list)</caption>
+ *   <tr><th>Java class</th>                                   <th>Type name (unofficial)</th>      <th>Definition identifier in OGC namespace</th></tr>
+ *   <tr><td>{@link org.opengis.util.InternationalString}</td> <td>{@code OGC:FreeText}</td>        <td></td></tr>
+ *   <tr><td>{@link java.lang.String}</td>                     <td>{@code OGC:CharacterString}</td> <td>urn:ogc:def:dataType:OGC::string</td></tr>
+ *   <tr><td>{@link java.net.URI}</td>                         <td>{@code OGC:URI}</td>             <td>urn:ogc:def:dataType:OGC::anyURI</td></tr>
+ *   <tr><td>{@link java.lang.Boolean}</td>                    <td>{@code OGC:Boolean}</td>         <td>urn:ogc:def:dataType:OGC::boolean</td></tr>
+ *   <tr><td>{@link java.lang.Integer}</td>                    <td>{@code OGC:Integer}</td>         <td>urn:ogc:def:dataType:OGC::nonNegativeInteger</td></tr>
+ *   <tr><td>{@link java.lang.Double}</td>                     <td>{@code OGC:Real}</td>            <td></td></tr>
+ *   <tr><td>{@link java.util.Date}</td>                       <td>{@code OGC:DateTime}</td>        <td></td></tr>
+ *   <tr><td>{@link java.util.Locale}</td>                     <td>{@code OGC:PT_Locale}</td>       <td></td></tr>
+ *   <tr><td>{@link org.opengis.metadata.Metadata}</td>        <td>{@code OGC:MD_Metadata}</td>     <td></td></tr>
+ *   <tr><td>Unknown Java class</td>                           <td>{@code class:}&lt;the class name&gt;</td><td></td></tr>
+ * </table>
+ *
+ * The mapping defined by Apache SIS may change in any future version depending on standardization progress.
+ * To protect against such changes, users are encouraged to rely on methods or constructors like
+ * {@link DefaultNameFactory#toTypeName(Class)} or {@link #toClass()} instead than parsing the name.
+ *
+ *
  * {@section Immutability and thread safety}
  * This class is immutable and thus inherently thread-safe if the {@link NameSpace} and {@link CharSequence}
  * arguments given to the constructor are also immutable. Subclasses shall make sure that any overridden methods
@@ -37,6 +68,7 @@ import org.opengis.util.NameSpace;
  *
  * @author  Guilhem Legal (Geomatys)
  * @author  Cédric Briançon (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
  * @version 0.5
  * @module
@@ -53,6 +85,20 @@ public class DefaultTypeName extends Def
     private static final long serialVersionUID = 7182126541436753582L;
 
     /**
+     * The value class to be returned by {@link #toClass()}, or {@code null} if not yet computed.
+     * {@link Void#TYPE} is used as a sentinel value meaning explicit {@code null}.
+     *
+     * <p>This value is only computed. We do not allow the user to explicitely specify it, because we
+     * need that {@code DefaultTypeName}s having identical name also have the same {@code valueClass}.
+     * This is necessary {@link DefaultNameFactory#pool} cache integrity. Users who want to explicitely
+     * specify their own value class can override {@link #toClass()} instead.</p>
+     *
+     * @see #setValueClass(NameSpace, String, Class)
+     * @see #toClass()
+     */
+    private transient Class<?> valueClass;
+
+    /**
      * Empty constructor to be used by JAXB only. Despite its "final" declaration,
      * the {@link #name} field will be set by JAXB during unmarshalling.
      */
@@ -60,12 +106,13 @@ public class DefaultTypeName extends Def
     }
 
     /**
-     * Constructs a type name from the given character sequence. The argument are given unchanged
-     * to the {@linkplain DefaultLocalName#DefaultLocalName(NameSpace,CharSequence) super-class
-     * constructor}.
+     * Constructs a type name from the given character sequence. The argument are given unchanged to the
+     * {@linkplain DefaultLocalName#DefaultLocalName(NameSpace,CharSequence) super-class constructor}.
      *
      * @param scope The scope of this name, or {@code null} for a global scope.
      * @param name  The local name (never {@code null}).
+     *
+     * @see DefaultNameFactory#createTypeName(NameSpace, CharSequence)
      */
     protected DefaultTypeName(final NameSpace scope, final CharSequence name) {
         super(scope, name);
@@ -95,4 +142,85 @@ public class DefaultTypeName extends Def
         }
         return new DefaultTypeName(object.scope(), object.toInternationalString());
     }
+
+    /**
+     * Sets {@link #valueClass} to the given value, only if the scope and the name of this {@code TypeName}
+     * are equal to the given values. The check for scope and name is a protection against renaming that user
+     * could apply if they subclass {@link DefaultNameFactory}. If the user performed such renaming, then the
+     * value class may be wrong, so we will ignore the given value class and let {@link #toClass()} computes
+     * the class itself.
+     */
+    final void setValueClass(final NameSpace scope, final String name, final Class<?> valueClass) {
+        if (scope == super.scope() && name.equals(super.toString())) {
+            this.valueClass = valueClass;
+        }
+    }
+
+    /**
+     * Returns the Java class associated to this type name.
+     * The default implementation parses this name in different ways depending on the {@linkplain #scope() scope}:
+     *
+     * <ul>
+     *   <li>If the scope is {@code "OGC"}, then:
+     *     <ul>
+     *       <li>If the name is {@code "CharacterString"}, {@code "Integer"}, {@code "Real"} or other recognized names
+     *           (see {@linkplain DefaultTypeName class javadoc}), then the corresponding class is returned.</li>
+     *       <li>Otherwise {@link UnknownNameException} is thrown.</li>
+     *     </ul>
+     *   </li>
+     *   <li>Else if the scope is {@code "class"}, then:
+     *     <ul>
+     *       <li>If the name is accepted by {@link Class#forName(String)}, then that class is returned.</li>
+     *       <li>Otherwise {@link UnknownNameException} is thrown.</li>
+     *     </ul>
+     *   </li>
+     *   <li>Else if the scope {@linkplain DefaultNameSpace#isGlobal() is global}, then:
+     *     <ul>
+     *       <li>If the name is one of the names recognized in {@code "OGC"} scope (see above),
+     *           then the corresponding class is returned.</li>
+     *       <li>Otherwise {@code null} is returned. No exception is thrown because names in the global namespace
+     *           could be anything, so we can not be sure that the given name was wrong.</li>
+     *     </ul>
+     *   </li>
+     *   <li>Otherwise {@code null} is returned, since this method can not check the validity of names in other
+     *       namespaces.</li>
+     * </ul>
+     *
+     * @return The Java class associated to this {@code TypeName},
+     *         or {@code null} if there is no mapping from this name to a Java class.
+     * @throws UnknownNameException if a mapping from this name to a Java class was expected to exist
+     *         (typically because of the {@linkplain #scope() scope}) but the operation failed.
+     *
+     * @see Names#toClass(TypeName)
+     * @see DefaultNameFactory#toTypeName(Class)
+     *
+     * @since 0.5
+     */
+    public Class<?> toClass() throws UnknownNameException {
+        /*
+         * No synchronization, because it is not a problem if two threads compute the same value concurrently.
+         * No volatile field neither, because instances of Class are safely published (well, I presume...).
+         */
+        Class<?> c = valueClass;
+        if (c == Void.TYPE) {
+            return null;
+        }
+        if (c == null) {
+            /*
+             * Invoke super.foo() instead than this.foo() because we do not want to invoke any overridden method.
+             * This is for ensuring that two TypeNames constructed with the same name will map to the same class.
+             * See 'valueClass' javadoc for more information.
+             */
+            try {
+                c = TypeNames.toClass(TypeNames.namespace(super.scope()), super.toString());
+            } catch (ClassNotFoundException e) {
+                throw new UnknownNameException(TypeNames.unknown(super.toFullyQualifiedName()), e);
+            }
+            if (c == null) {
+                throw new UnknownNameException(TypeNames.unknown(super.toFullyQualifiedName()));
+            }
+            valueClass = c;
+        }
+        return (c != Void.TYPE) ? c : null;
+    }
 }

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -19,11 +19,13 @@ package org.apache.sis.util.iso;
 import java.util.Collections;
 import org.opengis.util.TypeName;
 import org.opengis.util.LocalName;
+import org.opengis.util.MemberName;
 import org.opengis.util.GenericName;
 import org.opengis.util.NameSpace;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.Static;
 import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.util.UnknownNameException;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
@@ -189,6 +191,98 @@ public final class Names extends Static 
     }
 
     /**
+     * Creates a member name for values of the given class. A {@link TypeName} will be inferred
+     * from the given {@code valueClass} as documented in the {@link DefaultTypeName} javadoc.
+     *
+     * <div class="note"><b>Performance note:</b> this method is okay for <em>casual</em> use. If many names
+     * need to be created, then {@link DefaultNameFactory#createMemberName(NameSpace, CharSequence, TypeName)}
+     * is more efficient since it allows to create the {@code NameSpace} and {@code TypeName} objects only once.</div>
+     *
+     * @param  namespace  The namespace, or {@code null} for the global namespace.
+     * @param  separator  The separator between the namespace and the local part.
+     * @param  localPart  The name which is locale in the given namespace.
+     * @param  valueClass The type of values, used for inferring a {@link TypeName} instance.
+     * @return A member name in the given namespace for values of the given type.
+     */
+    public static MemberName createMemberName(final CharSequence namespace, final String separator,
+            final CharSequence localPart, final Class<?> valueClass)
+    {
+        ensureNonNull("localPart",  localPart);
+        ensureNonNull("separator",  separator);
+        ensureNonNull("valueClass", valueClass);
+        return DefaultFactories.NAMES.createMemberName(
+                createNameSpace(namespace, separator), localPart,
+                DefaultFactories.SIS_NAMES.toTypeName(valueClass));
+    }
+
+    /**
+     * Returns the Java class associated to the given type name.
+     * The method performs the following choices:
+     *
+     * <ul>
+     *   <li>If the given type name is {@code null}, then this method returns {@code null}.</li>
+     *   <li>Else if the given type name is an instance of {@code DefaultTypeName},
+     *       then this method delegates to {@link DefaultTypeName#toClass()}.</li>
+     *   <li>Else if the type name {@linkplain DefaultTypeName#scope() scope} is {@code "OGC"}, then:
+     *     <ul>
+     *       <li>If the name is {@code "CharacterString"}, {@code "Integer"}, {@code "Real"} or other recognized names
+     *           (see {@link DefaultTypeName} javadoc), then the corresponding class is returned.</li>
+     *       <li>Otherwise {@link UnknownNameException} is thrown.</li>
+     *     </ul>
+     *   </li>
+     *   <li>Else if the scope is {@code "class"}, then:
+     *     <ul>
+     *       <li>If the name is accepted by {@link Class#forName(String)}, then that class is returned.</li>
+     *       <li>Otherwise {@link UnknownNameException} is thrown.</li>
+     *     </ul>
+     *   </li>
+     *   <li>Else if the scope {@linkplain DefaultNameSpace#isGlobal() is global}, then:
+     *     <ul>
+     *       <li>If the name is one of the names recognized in {@code "OGC"} scope (see above),
+     *           then the corresponding class is returned.</li>
+     *       <li>Otherwise {@code null} is returned. No exception is thrown because names in the global namespace
+     *           could be anything, so we can not be sure that the given name was wrong.</li>
+     *     </ul>
+     *   </li>
+     *   <li>Otherwise {@code null} is returned, since this method can not check the validity of names in other
+     *       namespaces.</li>
+     * </ul>
+     *
+     * @param  type The type name from which to infer a Java class.
+     * @return The Java class associated to the given {@code TypeName},
+     *         or {@code null} if there is no mapping from the given name to a Java class.
+     * @throws UnknownNameException if a mapping from the given name to a Java class was expected to exist
+     *         (typically because of the {@linkplain DefaultTypeName#scope() scope}) but the operation failed.
+     *
+     * @see DefaultTypeName#toClass()
+     * @see DefaultNameFactory#toTypeName(Class)
+     *
+     * @since 0.5
+     */
+    public static Class<?> toClass(final TypeName type) throws UnknownNameException {
+        if (type == null) {
+            return null;
+        }
+        Class<?> c;
+        if (type instanceof DefaultTypeName) {
+            c = ((DefaultTypeName) type).toClass();
+        } else {
+            try {
+                c = TypeNames.toClass(TypeNames.namespace(type.scope()), type.toString());
+            } catch (ClassNotFoundException e) {
+                throw new UnknownNameException(TypeNames.unknown(type), e);
+            }
+            if (c == null) {
+                throw new UnknownNameException(TypeNames.unknown(type));
+            }
+            if (c == Void.TYPE) {
+                c = null;
+            }
+        }
+        return c;
+    }
+
+    /**
      * Formats the given name in <cite>expanded form</cite> close to the Java Content Repository (JCR) definition.
      * The expanded form is defined as below:
      *
@@ -196,13 +290,15 @@ public final class Names extends Static 
      * NameSpace    ::= name.{@linkplain AbstractName#scope() scope()}.{@linkplain DefaultNameSpace#name() name()}.toString()
      * LocalPart    ::= name.{@linkplain AbstractName#toString() toString()}</pre></blockquote>
      *
-     * @param  name The generic name to format in expanded form.
-     * @return Expanded form of the given generic name.
+     * @param  name The generic name to format in expanded form, or {@code null}.
+     * @return Expanded form of the given generic name, or {@code null} if the given name was null.
      *
      * @see DefaultNameSpace#toString()
      */
     public static String toExpandedString(final GenericName name) {
-        ensureNonNull("name", name);
+        if (name == null) {
+            return null;
+        }
         final String localPart = name.toString();
         final NameSpace scope = name.scope();
         if (scope == null || scope.isGlobal()) {

Copied: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/TypeNames.java (from r1625167, sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/TypeNames.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/TypeNames.java?p2=sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/TypeNames.java&p1=sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/TypeNames.java&r1=1625167&r2=1625169&rev=1625169&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/TypeNames.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/TypeNames.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -50,7 +50,7 @@ final class TypeNames {
      *
      * <p>This map shall not be modified after construction.</p>
      */
-    private static final Map<String,Class<?>> MAPPING = new LinkedHashMap<>(16);
+    private static final Map<String,Class<?>> MAPPING = new LinkedHashMap<String,Class<?>>(16);
     static {
         final Map<String,Class<?>> m = MAPPING;
         m.put("URI",                URI.class);

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -86,6 +86,7 @@ import org.junit.BeforeClass;
     org.apache.sis.util.iso.AbstractNameTest.class,
     org.apache.sis.util.iso.DefaultNameFactoryTest.class,
     org.apache.sis.util.iso.NamesTest.class,
+    org.apache.sis.util.iso.TypeNamesTest.class,
     org.apache.sis.internal.simple.SimpleReferenceIdentifierTest.class,
     org.apache.sis.util.iso.DefaultRecordTypeTest.class,
     org.apache.sis.util.iso.DefaultRecordSchemaTest.class,

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/ClassesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/ClassesTest.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/ClassesTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/ClassesTest.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -57,7 +57,7 @@ import org.opengis.referencing.operation
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.5)
- * @version 0.3
+ * @version 0.5
  * @module
  */
 public final strictfp class ClassesTest extends TestCase {
@@ -106,13 +106,13 @@ public final strictfp class ClassesTest 
         assertArrayEquals("TreeSet class", new Class<?>[] {NavigableSet.class},
                 getLeafInterfaces(TreeSet.class, Collection.class));
 
-        assertArrayEquals("Convolved class", new Class<?>[] {GeographicCRS.class},
+        assertArrayEquals("GeographicCRS", new Class<?>[] {GeographicCRS.class},
                 getLeafInterfaces(T1.class, IdentifiedObject.class));
 
-        assertArrayEquals("Convolved class", new Class<?>[] {GeographicCRS.class, CoordinateOperation.class},
+        assertArrayEquals("Mixed types",   new Class<?>[] {GeographicCRS.class, CoordinateOperation.class},
                 getLeafInterfaces(T2.class, IdentifiedObject.class));
 
-        assertArrayEquals("Convolved class", new Class<?>[] {Transformation.class, GeographicCRS.class},
+        assertArrayEquals("Mixed types",   new Class<?>[] {Transformation.class, GeographicCRS.class},
                 getLeafInterfaces(T3.class, IdentifiedObject.class));
     }
 
@@ -198,28 +198,30 @@ public final strictfp class ClassesTest 
         final Class<Parameterized> c = Parameterized.class;
         assertNull(                 boundOfParameterizedProperty(c.getMethod("getter0", g)));
         assertNull(                 boundOfParameterizedProperty(c.getMethod("setter0", s)));
-        assertEquals(Long   .class, boundOfParameterizedProperty(c.getField ("attrib2"   )));
-        assertEquals(Integer.class, boundOfParameterizedProperty(c.getMethod("getter1", g)));
-        assertEquals(Byte   .class, boundOfParameterizedProperty(c.getMethod("getter2", g)));
-        assertEquals(Object .class, boundOfParameterizedProperty(c.getMethod("getter3", g)));
-        assertEquals(short[].class, boundOfParameterizedProperty(c.getMethod("getter4", g)));
-        assertEquals(String .class, boundOfParameterizedProperty(c.getMethod("setter1", s)));
-        assertEquals(Short  .class, boundOfParameterizedProperty(c.getMethod("setter2", s)));
-        assertEquals(Object .class, boundOfParameterizedProperty(c.getMethod("setter3", s)));
+        assertEquals(Long      .class, boundOfParameterizedProperty(c.getField ("attrib2"   )));
+        assertEquals(Integer   .class, boundOfParameterizedProperty(c.getMethod("getter1", g)));
+        assertEquals(Byte      .class, boundOfParameterizedProperty(c.getMethod("getter2", g)));
+        assertEquals(Object    .class, boundOfParameterizedProperty(c.getMethod("getter3", g)));
+        assertEquals(short[]   .class, boundOfParameterizedProperty(c.getMethod("getter4", g)));
+        assertEquals(Comparable.class, boundOfParameterizedProperty(c.getMethod("getter5", g)));
+        assertEquals(String    .class, boundOfParameterizedProperty(c.getMethod("setter1", s)));
+        assertEquals(Short     .class, boundOfParameterizedProperty(c.getMethod("setter2", s)));
+        assertEquals(Object    .class, boundOfParameterizedProperty(c.getMethod("setter3", s)));
     }
 
     /**
      * Dummy class for {@link #testBoundOfParameterizedProperty()} usage only.
      */
+    @SuppressWarnings("rawtypes")
     private static final class Parameterized {
         public Set<? extends Long> attrib2 = null;
-        @SuppressWarnings("rawtypes")
         public Set                 getter0() {return null;} // Intentionnaly unparameterized.
         public Set<       Integer> getter1() {return null;}
         public Set<? extends Byte> getter2() {return null;}
         public Set<? super  Float> getter3() {return null;}
         public Set<       short[]> getter4() {return null;}
-        @SuppressWarnings("rawtypes")
+        public Set<Comparable<?>>  getter5() {return null;}
+
         public void setter0(Set                  dummy) {}  // Intentionnaly unparameterized.
         public void setter1(Set<         String> dummy) {}
         public void setter2(Set<? extends Short> dummy) {}

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordSchemaTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordSchemaTest.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordSchemaTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordSchemaTest.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -69,25 +69,25 @@ public final strictfp class DefaultRecor
             switch (count) {
                 case 0: {
                     expectedName  = "city";
-                    expectedType  = "gco:CharacterString";
+                    expectedType  = "OGC:CharacterString";
                     expectedClass = String.class;
                     break;
                 }
                 case 1: {
                     expectedName  = "latitude";
-                    expectedType  = "gco:Real";
+                    expectedType  = "OGC:Real";
                     expectedClass = Double.class;
                     break;
                 }
                 case 2: {
                     expectedName  = "longitude";
-                    expectedType  = "gco:Real";
+                    expectedType  = "OGC:Real";
                     expectedClass = Double.class;
                     break;
                 }
                 case 3: {
                     expectedName  = "population";
-                    expectedType  = "gco:Integer";
+                    expectedType  = "OGC:Integer";
                     expectedClass = Integer.class;
                     break;
                 }

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -40,7 +40,7 @@ import static org.apache.sis.test.TestUt
  * @version 0.5
  * @module
  */
-@DependsOn(AbstractNameTest.class)
+@DependsOn(TypeNamesTest.class)
 public final strictfp class DefaultRecordTypeTest extends TestCase {
     /** Value of {@link DefaultRecordType#getContainer()}.   */ private DefaultRecordSchema container;
     /** Value of {@link DefaultRecordType#getTypeName()}.    */ private DefaultTypeName     recordTypeName;

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -16,7 +16,16 @@
  */
 package org.apache.sis.util.iso;
 
+import java.util.List;
+import java.util.Random;
+import org.opengis.util.GenericName;
+import org.opengis.util.TypeName;
 import org.opengis.util.LocalName;
+import org.opengis.util.InternationalString;
+import org.opengis.util.NameSpace;
+import org.opengis.util.ScopedName;
+import org.apache.sis.util.UnknownNameException;
+import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -45,4 +54,81 @@ public final strictfp class NamesTest ex
         assertEquals("http://www.opengis.net/gml/srs/epsg.xml#4326",  name.toFullyQualifiedName().toString());
         assertEquals("{http://www.opengis.net/gml/srs/epsg.xml}4326", Names.toExpandedString(name));
     }
+
+    /**
+     * Tests {@link Names#toClass(TypeName)} with a name in the {@code "class"} scope.
+     * If the name is not recognized, then {@code toClass(TypeName)} is expected to throw an exception.
+     */
+    @Test
+    public void testClassFromClassname() {
+        final TypeName type = DefaultFactories.SIS_NAMES.toTypeName(Random.class);
+        assertEquals("class:java.util.Random", type.toFullyQualifiedName().toString());
+        assertValueClassEquals(Random.class, type);
+        assertValueClassEquals(DefaultNameFactoryTest.class,
+                new DefaultTypeName(type.scope(), DefaultNameFactoryTest.class.getName()));
+        assertValueClassEquals(UnknownNameException.class,
+                new DefaultTypeName(type.scope(), "org.apache.sis.Dummy"));
+    }
+
+    /**
+     * Tests {@link Names#toClass(TypeName)} with a name in the {@code "OGC"} scope.
+     * If the name is not recognized, then {@code toClass(TypeName)} is expected to throw an exception.
+     */
+    @Test
+    public void testClassFromOGC() {
+        final TypeName type = DefaultFactories.SIS_NAMES.toTypeName(String.class);
+        assertEquals("OGC:CharacterString", type.toFullyQualifiedName().toString());
+        assertValueClassEquals(String.class,               type);
+        assertValueClassEquals(Double.class,               new DefaultTypeName(type.scope(), "Real"));
+        assertValueClassEquals(InternationalString.class,  new DefaultTypeName(type.scope(), "FreeText"));
+        assertValueClassEquals(UnknownNameException.class, new DefaultTypeName(type.scope(), "Dummy"));
+    }
+
+    /**
+     * Tests {@link Names#toClass(TypeName)} with in a scope different than {@code "OGC"}.
+     * If the name is not recognized, then {@code toClass(TypeName)} is expected to return
+     * {@code null} rather than throwing an exception because the namespace is used for too
+     * many things - we can not said that the name is wrong.
+     */
+    @Test
+    public void testClassFromOtherNamespaces() {
+        assertValueClassEquals(null,         Names.createTypeName("MyOrg", ":", "CharacterString"));
+        assertValueClassEquals(String.class, Names.createTypeName(null,    ":", "CharacterString"));
+        assertValueClassEquals(null,         Names.createTypeName(null,    ":", "Dummy"));
+    }
+
+    /**
+     * Invokes {@link Names#toClass(TypeName)}, but catch {@link UnknownNameException}.
+     * If the later exception is caught, then this method returns {@code UnknownNameException.class}.
+     */
+    private static Class<?> toClass(final TypeName type) {
+        try {
+            return Names.toClass(type);
+        } catch (UnknownNameException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains(type.toFullyQualifiedName().toString()));
+            return UnknownNameException.class;
+        }
+    }
+
+    /**
+     * Asserts that calls to {@link Names#toClass(TypeName)} returns the expected value class.
+     */
+    private static void assertValueClassEquals(final Class<?> expected, final TypeName type) {
+        assertEquals(expected, toClass(type));
+
+        // Tests detection with an implementation which is not the SIS one.
+        assertEquals(expected, toClass(new TypeName() {
+            @Override public int                       depth()                  {return type.depth();}
+            @Override public List<? extends LocalName> getParsedNames()         {return type.getParsedNames();}
+            @Override public LocalName                 head()                   {return type.head();}
+            @Override public LocalName                 tip()                    {return type.tip();}
+            @Override public NameSpace                 scope()                  {return type.scope();}
+            @Override public GenericName               toFullyQualifiedName()   {return type.toFullyQualifiedName();}
+            @Override public ScopedName                push(GenericName scope)  {return type.push(scope);}
+            @Override public String                    toString()               {return type.toString();}
+            @Override public InternationalString       toInternationalString()  {return type.toInternationalString();}
+            @Override public int                       compareTo(GenericName o) {return type.compareTo(o);}
+        }));
+    }
 }

Modified: sis/branches/JDK6/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/DirectReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/DirectReferenceSystem.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/DirectReferenceSystem.java [UTF-8] (original)
+++ sis/branches/JDK6/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/DirectReferenceSystem.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -21,6 +21,7 @@ import javax.xml.bind.annotation.XmlRoot
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.referencing.ReferenceIdentifier;
 import org.apache.sis.internal.jaxb.metadata.replace.ReferenceSystemMetadata;
+import org.apache.sis.util.ComparisonMode;
 
 
 /**
@@ -73,4 +74,16 @@ public class DirectReferenceSystem exten
     public DirectReferenceSystem(final ReferenceIdentifier identifier) {
         super(identifier);
     }
+
+    /**
+     * Compares this object with the given one for equality.
+     *
+     * @param  object The object to compare with this reference system.
+     * @param  mode The strictness level of the comparison.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final Object object, final ComparisonMode mode) {
+        return super.equals(object, mode) && (object instanceof DirectReferenceSystem);
+    }
 }

Modified: sis/branches/JDK6/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/IndirectReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/IndirectReferenceSystem.java?rev=1625169&r1=1625168&r2=1625169&view=diff
==============================================================================
--- sis/branches/JDK6/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/IndirectReferenceSystem.java [UTF-8] (original)
+++ sis/branches/JDK6/profiles/sis-french-profile/src/main/java/org/apache/sis/internal/profile/fra/IndirectReferenceSystem.java [UTF-8] Mon Sep 15 21:45:25 2014
@@ -21,6 +21,7 @@ import javax.xml.bind.annotation.XmlRoot
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.referencing.ReferenceIdentifier;
 import org.apache.sis.internal.jaxb.metadata.replace.ReferenceSystemMetadata;
+import org.apache.sis.util.ComparisonMode;
 
 
 /**
@@ -73,4 +74,16 @@ public class IndirectReferenceSystem ext
     public IndirectReferenceSystem(final ReferenceIdentifier identifier) {
         super(identifier);
     }
+
+    /**
+     * Compares this object with the given one for equality.
+     *
+     * @param  object The object to compare with this reference system.
+     * @param  mode The strictness level of the comparison.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final Object object, final ComparisonMode mode) {
+        return super.equals(object, mode) && (object instanceof IndirectReferenceSystem);
+    }
 }



Mime
View raw message