You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2012/12/17 10:08:24 UTC

svn commit: r1422804 [1/2] - in /sis/branches/JDK6: ./ ide-project/NetBeans/nbproject/ sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/ sis-referencing/ sis-referencing/src/main/java/org/apache/sis/geometry/ sis-referencing/src/main/java/o...

Author: desruisseaux
Date: Mon Dec 17 09:08:19 2012
New Revision: 1422804

URL: http://svn.apache.org/viewvc?rev=1422804&view=rev
Log:
Merge from JDK7 branch: port of Envelope implementions.

Added:
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/
      - copied from r1422800, sis/branches/JDK7/sis-referencing/src/main/java/org/apache/sis/geometry/
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/internal/
      - copied from r1422800, sis/branches/JDK7/sis-referencing/src/main/java/org/apache/sis/internal/
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/referencing/
      - copied from r1422800, sis/branches/JDK7/sis-referencing/src/main/java/org/apache/sis/referencing/
    sis/branches/JDK6/sis-referencing/src/test/java/org/apache/sis/geometry/
      - copied from r1422800, sis/branches/JDK7/sis-referencing/src/test/java/org/apache/sis/geometry/
    sis/branches/JDK6/sis-referencing/src/test/java/org/apache/sis/referencing/
      - copied from r1422800, sis/branches/JDK7/sis-referencing/src/test/java/org/apache/sis/referencing/
Removed:
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/CodeLists.java
    sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/iso/CodeListsTest.java
Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/ide-project/NetBeans/nbproject/project.properties
    sis/branches/JDK6/pom.xml
    sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java
    sis/branches/JDK6/sis-referencing/pom.xml
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java
    sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/Statistics.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/Angle.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Characters.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Utilities.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultInternationalString.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/SimpleInternationalString.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/NilObject.java
    sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/xml/XLink.java
    sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java
    sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/Assert.java
    sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
    sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
    sis/branches/JDK6/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java
    sis/branches/JDK6/src/main/javadoc/stylesheet.css

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK7:r1420582-1422800

Modified: sis/branches/JDK6/ide-project/NetBeans/nbproject/project.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/ide-project/NetBeans/nbproject/project.properties?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/ide-project/NetBeans/nbproject/project.properties (original)
+++ sis/branches/JDK6/ide-project/NetBeans/nbproject/project.properties Mon Dec 17 09:08:19 2012
@@ -57,7 +57,7 @@ junit.version        = 4.10
 maven.repository   = ${user.home}/.m2/repository
 endorsed.classpath =
 javac.classpath=\
-    ${maven.repository}/org/opengis/geoapi/${geoapi.version}/geoapi-${geoapi.version}.jar:\
+    ${maven.repository}/org/opengis/geoapi-pending/${geoapi.version}/geoapi-pending-${geoapi.version}.jar:\
     ${maven.repository}/javax/measure/jsr-275/${jsr275.version}/jsr-275-${jsr275.version}.jar:\
     ${maven.repository}/java3d/vecmath/${vecmath.version}/vecmath-${vecmath.version}.jar:\
     ${maven.repository}/org/geonames/georss-rome/${georss.version}/georss-rome-${georss.version}.jar:\

Modified: sis/branches/JDK6/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/pom.xml?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/pom.xml (original)
+++ sis/branches/JDK6/pom.xml Mon Dec 17 09:08:19 2012
@@ -341,6 +341,13 @@ Apache SIS is a toolkit for describing l
             </manifestEntries>
           </archive>
         </configuration>
+        <executions>
+         <execution>
+           <goals>
+             <goal>test-jar</goal>
+           </goals>
+         </execution>
+       </executions>
       </plugin>
 
       <!-- Package as OSGi bundle -->

Modified: sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java (original)
+++ sis/branches/JDK6/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_ObligationCode.java Mon Dec 17 09:08:19 2012
@@ -18,7 +18,7 @@ package org.apache.sis.internal.jaxb.cod
 
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import org.opengis.metadata.Obligation;
-import org.apache.sis.util.iso.CodeLists;
+import org.apache.sis.util.iso.Types;
 
 
 /**
@@ -40,7 +40,7 @@ public final class MD_ObligationCode ext
      */
     @Override
     public Obligation unmarshal(String value) {
-        return CodeLists.valueOf(Obligation.class, value);
+        return Types.forCodeName(Obligation.class, value, true);
     }
 
     /**

Modified: sis/branches/JDK6/sis-referencing/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-referencing/pom.xml?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-referencing/pom.xml (original)
+++ sis/branches/JDK6/sis-referencing/pom.xml Mon Dec 17 09:08:19 2012
@@ -33,14 +33,44 @@
 
   <artifactId>sis-referencing</artifactId>
   <packaging>bundle</packaging>
-  <name>Apache SIS core</name>
+  <name>Apache SIS referencing</name>
   <url>http://incubator.apache.org/sis/</url>
 
+
+  <!-- ===========================================================
+           Dependencies
+       =========================================================== -->
   <dependencies>
     <dependency>
+      <groupId>org.apache.sis</groupId>
+      <artifactId>sis-utility</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opengis</groupId>
+      <artifactId>geoapi-pending</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opengis</groupId>
+      <artifactId>geoapi-conformance</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>net.jcip</groupId>
+      <artifactId>jcip-annotations</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.geonames</groupId>
       <artifactId>georss-rome</artifactId>
     </dependency>
+
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>org.apache.sis</groupId>
+      <artifactId>sis-utility</artifactId>
+      <version>${project.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
 </project>

Modified: sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java?rev=1422804&r1=1422800&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java (original)
+++ sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractDirectPosition.java Mon Dec 17 09:08:19 2012
@@ -22,7 +22,6 @@ package org.apache.sis.geometry;
  * to force installation of the Java2D module (e.g. JavaFX/SWT).
  */
 import java.util.Arrays;
-import java.util.Objects;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
 import org.opengis.geometry.MismatchedReferenceSystemException;
@@ -36,6 +35,9 @@ import static java.lang.Double.doubleToL
 import static org.apache.sis.util.Arrays.resize;
 import static org.apache.sis.util.StringBuilders.trimFractionalPart;
 
+// Related to JDK7
+import org.apache.sis.internal.util.Objects;
+
 
 /**
  * Base class for {@link DirectPosition} implementations.

Modified: sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java?rev=1422804&r1=1422800&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java (original)
+++ sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java Mon Dec 17 09:08:19 2012
@@ -45,7 +45,7 @@ import static org.apache.sis.math.MathFu
 import static org.apache.sis.math.MathFunctions.isPositive;
 
 // Related to JDK7
-import java.util.Objects;
+import org.apache.sis.internal.util.Objects;
 
 
 /**

Modified: sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java?rev=1422804&r1=1422800&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java (original)
+++ sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java Mon Dec 17 09:08:19 2012
@@ -22,7 +22,6 @@ package org.apache.sis.geometry;
  * force installation of the Java2D module (e.g. JavaFX/SWT).
  */
 import java.util.Arrays;
-import java.util.Objects;
 import java.io.Serializable;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
@@ -41,6 +40,9 @@ import static org.apache.sis.util.Argume
 import static org.apache.sis.math.MathFunctions.isNegative;
 import static org.apache.sis.internal.referencing.Utilities.isPoleToPole;
 
+// Related to JDK7
+import org.apache.sis.internal.util.Objects;
+
 
 /**
  * Base class of envelopes backed by an array.

Modified: sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java?rev=1422804&r1=1422800&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java (original)
+++ sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java Mon Dec 17 09:08:19 2012
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.geometry;
 
-import java.util.Objects;
 import java.awt.geom.Point2D;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
@@ -33,6 +32,9 @@ import static org.apache.sis.util.String
 import static org.apache.sis.geometry.AbstractDirectPosition.ensureDimensionMatch;
 import static org.apache.sis.geometry.AbstractDirectPosition.parse;
 
+// Related to JDK7
+import org.apache.sis.internal.util.Objects;
+
 
 /**
  * Holds the coordinates for a two-dimensional position on top of {@link Point2D}.

Modified: sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java?rev=1422804&r1=1422800&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java (original)
+++ sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java Mon Dec 17 09:08:19 2012
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.geometry;
 
-import java.util.Objects;
 import java.awt.geom.Rectangle2D;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
@@ -49,6 +48,9 @@ import static org.apache.sis.geometry.Ab
 import static org.apache.sis.geometry.AbstractEnvelope.isWrapAround;
 import static org.apache.sis.geometry.AbstractEnvelope.isNegativeUnsafe;
 
+// Related to JDK7
+import org.apache.sis.internal.util.Objects;
+
 
 /**
  * A two-dimensional envelope on top of {@link Rectangle2D}.

Modified: sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java?rev=1422804&r1=1422800&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java (original)
+++ sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java Mon Dec 17 09:08:19 2012
@@ -263,7 +263,7 @@ public class GeneralDirectPosition exten
             field.setAccessible(true);
             field.set(e, ordinates.clone());
             return e;
-        } catch (ReflectiveOperationException | CloneNotSupportedException exception) {
+        } catch (Exception exception) { // (ReflectiveOperationException | CloneNotSupportedException) on JDK7
             // Should not happen, since we are cloneable.
             // Should not happen, since the "ordinates" field exists.
             // etc...

Modified: sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java?rev=1422804&r1=1422800&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java (original)
+++ sis/branches/JDK6/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java Mon Dec 17 09:08:19 2012
@@ -735,7 +735,7 @@ public class GeneralEnvelope extends Arr
             GeneralEnvelope e = (GeneralEnvelope) super.clone();
             field.set(e, ordinates.clone());
             return e;
-        } catch (CloneNotSupportedException | ReflectiveOperationException exception) {
+        } catch (Exception exception) { // (CloneNotSupportedException | ReflectiveOperationException) on JDK7
             // Should not happen, since we are cloneable, the
             // field is known to exist and we made it accessible.
             throw new AssertionError(exception);

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListAdapter.java Mon Dec 17 09:08:19 2012
@@ -18,7 +18,7 @@ package org.apache.sis.internal.jaxb.gmd
 
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import org.opengis.util.CodeList;
-import org.apache.sis.util.iso.CodeLists;
+import org.apache.sis.util.iso.Types;
 import org.apache.sis.internal.jaxb.MarshalContext;
 
 
@@ -117,7 +117,7 @@ public abstract class CodeListAdapter<Va
         if (adapter == null) {
             return null;
         }
-        return CodeLists.valueOf(getCodeListClass(), adapter.proxy.identifier());
+        return Types.forCodeName(getCodeListClass(), adapter.proxy.identifier(), true);
     }
 
     /**
@@ -132,7 +132,7 @@ public abstract class CodeListAdapter<Va
         if (value == null) {
             return null;
         }
-        return wrap(isEnum() ? new CodeListProxy(CodeLists.getCodeName(value))
+        return wrap(isEnum() ? new CodeListProxy(Types.getCodeName(value))
                              : new CodeListProxy(MarshalContext.current(), value));
     }
 

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gmd/CodeListProxy.java Mon Dec 17 09:08:19 2012
@@ -24,7 +24,7 @@ import javax.xml.bind.annotation.XmlType
 import javax.xml.bind.annotation.XmlValue;
 import org.opengis.util.CodeList;
 import org.apache.sis.util.logging.Logging;
-import org.apache.sis.util.iso.CodeLists;
+import org.apache.sis.util.iso.Types;
 import org.apache.sis.internal.jaxb.MarshalContext;
 
 
@@ -166,21 +166,22 @@ public final class CodeListProxy {
      * @param code    The code list to wrap.
      */
     CodeListProxy(final MarshalContext context, final CodeList<?> code) {
-        final String classID = CodeLists.getListName(code);
-        final String fieldID = CodeLists.getCodeName(code);
+        final String classID = Types.getListName(code);
+        final String fieldID = Types.getCodeName(code);
         codeList = schema(context, "gmxCodelists.xml", classID);
         /*
          * Get the localized name of the field identifier, if possible.
-         * This code partially duplicates CodeList.getCodeTitle(CodeList, Locale).
+         * This code partially duplicates Types.getCodeTitle(CodeList, Locale).
          * This duplication exists because this constructor stores more information in
          * an opportunist way. If this constructor is updated, please consider updating
-         * the CodeList.getCodeTitle(CodeList, Locale) method accordingly.
+         * the Types.getCodeTitle(CodeList, Locale) method accordingly.
          */
         final Locale locale = context.getLocale();
         if (locale != null) {
             final String key = classID + '.' + fieldID;
             try {
-                value = ResourceBundle.getBundle("org.opengis.metadata.CodeLists", locale).getString(key);
+                value = ResourceBundle.getBundle("org.opengis.metadata.CodeLists",
+                        locale, CodeList.class.getClassLoader()).getString(key);
             } catch (MissingResourceException e) {
                 Logging.recoverableException(CodeListAdapter.class, "marshal", e);
             }
@@ -191,7 +192,7 @@ public final class CodeListProxy {
             // Fallback when no value is defined for the code list. Build a value from the
             // most descriptive name (excluding the field name), which is usually the UML
             // name except for CharacterSet in which case it is a string like "UTF-8".
-            value = CodeLists.getCodeTitle(code);
+            value = Types.getCodeTitle(code);
         }
         codeListValue = fieldID;
     }

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java Mon Dec 17 09:08:19 2012
@@ -32,6 +32,25 @@ import org.apache.sis.util.CharSequences
  */
 public final class Utilities extends Static {
     /**
+     * Bit mask to isolate the sign bit of non-{@linkplain Double#isNaN(double) NaN} values in a
+     * {@code double}. For any real value, the following code evaluate to 0 if the given value is
+     * positive:
+     *
+     * {@preformat java
+     *     Double.doubleToRawLongBits(value) & SIGN_BIT_MASK;
+     * }
+     *
+     * Note that this idiom differentiates positive zero from negative zero.
+     * It should be used only when such difference matter.
+     *
+     * @see org.apache.sis.math.MathFunctions#isPositive(double)
+     * @see org.apache.sis.math.MathFunctions#isNegative(double)
+     * @see org.apache.sis.math.MathFunctions#isSameSign(double, double)
+     * @see org.apache.sis.math.MathFunctions#xorSign(double, double)
+     */
+    public static final long SIGN_BIT_MASK = Long.MIN_VALUE;
+
+    /**
      * Do not allow instantiation of this class.
      */
     private Utilities() {

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java Mon Dec 17 09:08:19 2012
@@ -29,6 +29,7 @@ import static java.lang.Double.doubleToR
 import static org.apache.sis.util.Arrays.resize;
 import static org.apache.sis.util.Arrays.isSorted;
 import static org.apache.sis.util.Arrays.EMPTY_INT;
+import static org.apache.sis.internal.util.Utilities.SIGN_BIT_MASK;
 
 
 /**
@@ -82,25 +83,6 @@ public final class MathFunctions extends
     };
 
     /**
-     * Bit mask to isolate the sign bit of non-{@linkplain Double#isNaN(double) NaN} values in a
-     * {@code double}. For any real value, the following code evaluate to 0 if the given value is
-     * positive:
-     *
-     * {@preformat java
-     *     Double.doubleToRawLongBits(value) & SIGN_BIT_MASK;
-     * }
-     *
-     * Note that this idiom differentiates positive zero from negative zero.
-     * It should be used only when such difference matter.
-     *
-     * @see #isPositive(double)
-     * @see #isNegative(double)
-     * @see #isSameSign(double, double)
-     * @see #xorSign(double, double)
-     */
-    private static final long SIGN_BIT_MASK = Long.MIN_VALUE;
-
-    /**
      * The minimal ordinal value for {@code NaN} numbers created by {@link #toNanFloat(int)}.
      *
      * @see #toNanFloat(int)
@@ -562,6 +544,50 @@ public final class MathFunctions extends
     }
 
     /**
+     * Returns {@code true} if the given values are {@linkplain Float#equals(Object) equal}
+     * or if their difference is not greater than the given threshold. More specifically:
+     *
+     * <ul>
+     *   <li>If both values are {@linkplain Float#POSITIVE_INFINITY positive infinity}, or
+     *       if both values are {@linkplain Float#NEGATIVE_INFINITY negative infinity},
+     *       then this method returns {@code true}.</li>
+     *   <li>If both values {@linkplain Float#isNaN(float) are NaN}, then this method returns {@code true}.
+     *       Note that this method does not differentiate the various NaN values.</li>
+     *   <li>Otherwise, this method returns the result of the {@code abs(v1 - v2) <= ε} comparison.</li>
+     * </ul>
+     *
+     * @param  v1 The first value to compare.
+     * @param  v2 The second value to compare.
+     * @param  ε  The tolerance threshold, which must be positive.
+     * @return {@code true} If both values are equal given the tolerance threshold.
+     */
+    public static boolean epsilonEqual(final float v1, final float v2, final float ε) {
+        return (Math.abs(v1 - v2) <= ε) || Float.floatToIntBits(v1) == Float.floatToIntBits(v2);
+    }
+
+    /**
+     * Returns {@code true} if the given values are {@linkplain Double#equals(Object) equal}
+     * or if their difference is not greater than the given threshold. More specifically:
+     *
+     * <ul>
+     *   <li>If both values are {@linkplain Double#POSITIVE_INFINITY positive infinity}, or
+     *       if both values are {@linkplain Double#NEGATIVE_INFINITY negative infinity},
+     *       then this method returns {@code true}.</li>
+     *   <li>If both values {@linkplain Double#isNaN(double) are NaN}, then this method returns {@code true}.
+     *       Note that this method does not differentiate the various NaN values.</li>
+     *   <li>Otherwise, this method returns the result of the {@code abs(v1 - v2) <= ε} comparison.</li>
+     * </ul>
+     *
+     * @param  v1 The first value to compare.
+     * @param  v2 The second value to compare.
+     * @param  ε  The tolerance threshold, which must be positive.
+     * @return {@code true} If both values are equal given the tolerance threshold.
+     */
+    public static boolean epsilonEqual(final double v1, final double v2, final double ε) {
+        return (Math.abs(v1 - v2) <= ε) || Double.doubleToLongBits(v1) == Double.doubleToLongBits(v2);
+    }
+
+    /**
      * Returns a {@linkplain Float#isNaN(float) NaN} number for the specified ordinal value.
      * Valid NaN numbers in Java can have bit fields in the ranges listed below.
      * This method allocates one of valid NaN bit fields to each ordinal value.

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/Statistics.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/Statistics.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/Statistics.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/math/Statistics.java Mon Dec 17 09:08:19 2012
@@ -17,7 +17,6 @@
 package org.apache.sis.math;
 
 import java.io.Serializable;
-import org.apache.sis.util.Utilities;
 import org.apache.sis.util.ArgumentChecks;
 
 import static java.lang.Math.*;
@@ -505,10 +504,10 @@ public class Statistics implements Clone
         if (object != null && getClass() == object.getClass()) {
             final Statistics cast = (Statistics) object;
             return count == cast.count && countNaN == cast.countNaN
-                    && Utilities.equals(minimum,   cast.minimum)
-                    && Utilities.equals(maximum,   cast.maximum)
-                    && Utilities.equals(sum,       cast.sum)
-                    && Utilities.equals(squareSum, cast.squareSum);
+                    && doubleToLongBits(minimum)   == doubleToLongBits(cast.minimum)
+                    && doubleToLongBits(maximum)   == doubleToLongBits(cast.maximum)
+                    && doubleToLongBits(sum)       == doubleToLongBits(cast.sum)
+                    && doubleToLongBits(squareSum) == doubleToLongBits(cast.squareSum);
         }
         return false;
     }

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/Angle.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/Angle.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/Angle.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/Angle.java Mon Dec 17 09:08:19 2012
@@ -24,9 +24,10 @@ import java.text.Format;
 import java.text.ParseException;
 import java.io.Serializable;
 import net.jcip.annotations.Immutable;
-import org.apache.sis.util.Utilities;
 import org.apache.sis.math.MathFunctions;
 
+import static java.lang.Double.doubleToLongBits;
+
 
 /**
  * An angle in decimal degrees. An angle is the amount of rotation needed to bring one line or
@@ -156,7 +157,7 @@ public class Angle implements Comparable
             return true;
         }
         if (object != null && getClass() == object.getClass()) {
-            return Utilities.equals(θ, ((Angle) object).θ);
+            return doubleToLongBits(θ) == doubleToLongBits(((Angle) object).θ);
         }
         return false;
     }

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java Mon Dec 17 09:08:19 2012
@@ -51,7 +51,7 @@ import org.apache.sis.internal.util.Obje
  * Parses and formats angles according a specified pattern. The pattern is a string
  * containing any characters, with a special meaning for the following characters:
  *
- * <blockquote><table class="sis">
+ * <table class="sis">
  *   <tr><th>Symbol</th><th>Meaning</th></tr>
  *   <tr><td>{@code D}</td><td>The integer part of degrees</td></tr>
  *   <tr><td>{@code d}</td><td>The fractional part of degrees</td></tr>
@@ -61,7 +61,7 @@ import org.apache.sis.internal.util.Obje
  *   <tr><td>{@code s}</td><td>The fractional part of seconds</td></tr>
  *   <tr><td>{@code #}</td><td>Fraction digits shown only if non-zero</td></tr>
  *   <tr><td>{@code .}</td><td>The decimal separator</td></tr>
- * </table></blockquote>
+ * </table>
  *
  * Upper-case letters {@code D}, {@code M} and {@code S} stand for the integer parts of degrees,
  * minutes and seconds respectively. They shall appear in this order. For example {@code M'D} is
@@ -87,7 +87,7 @@ import org.apache.sis.internal.util.Obje
  *
  * <p>The following table gives some pattern examples:</p>
  *
- * <blockquote><table class="sis">
+ * <table class="sis">
  *   <tr><th>Pattern           </th>  <th>Example   </th></tr>
  *   <tr><td>{@code DD°MM′SS″ }</td>  <td>48°30′00″ </td></tr>
  *   <tr><td>{@code DD°MM′    }</td>  <td>48°30′    </td></tr>
@@ -95,7 +95,7 @@ import org.apache.sis.internal.util.Obje
  *   <tr><td>{@code DD.###    }</td>  <td>48.5      </td></tr>
  *   <tr><td>{@code DDMM      }</td>  <td>4830      </td></tr>
  *   <tr><td>{@code DDMMSS    }</td>  <td>483000    </td></tr>
- * </table></blockquote>
+ * </table>
  *
  * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
  * @since   0.3 (derived from geotk-1.0)

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java Mon Dec 17 09:08:19 2012
@@ -305,57 +305,6 @@ public final class CharSequences extends
     }
 
     /**
-     * Returns the index within the given character sequence of the first occurrence of the
-     * specified character, starting the search at the specified index. If the character is
-     * not found, then this method returns -1.
-     *
-     * <p>There is no restriction on the value of {@code fromIndex}. If negative or greater
-     * than {@code toIndex}, then the behavior of this method is as if the search started
-     * from 0 or {@code toIndex} respectively. This is consistent with the behavior documented
-     * in {@link String#indexOf(int, int)}.</p>
-     *
-     * @param  text      The character sequence in which to perform the search, or {@code null}.
-     * @param  toSearch  The Unicode code point of the character to search.
-     * @param  fromIndex The index to start the search from.
-     * @param  toIndex   The index after the last character where to perform the search.
-     * @return The index of the first occurrence of the given character in the text, or -1
-     *         if no occurrence has been found or if the {@code text} argument is null.
-     *
-     * @see String#indexOf(int, int)
-     */
-    public static int indexOf(final CharSequence text, final int toSearch, int fromIndex, int toIndex) {
-        if (text != null) {
-            final int length = text.length();
-            if (toIndex > length) {
-                toIndex = length;
-            }
-            if (text instanceof String && toIndex == length) {
-                // String provides a faster implementation.
-                return ((String) text).indexOf(toSearch, fromIndex);
-            }
-            if (fromIndex < 0) {
-                fromIndex = 0;
-            }
-            char head  = (char) toSearch;
-            char tail  = (char) 0;
-            if (head != toSearch) { // Outside BMP plane?
-                head = highSurrogate(toSearch);
-                tail = lowSurrogate (toSearch);
-                toIndex--;
-            }
-            while (fromIndex < toIndex) {
-                if (text.charAt(fromIndex) == head) {
-                    if (tail == 0 || text.charAt(fromIndex+1) == tail) {
-                        return fromIndex;
-                    }
-                }
-                fromIndex++;
-            }
-        }
-        return -1;
-    }
-
-    /**
      * Returns the index within the given strings of the first occurrence of the specified part,
      * starting at the specified index. This method is equivalent to the following method call,
      * except that this method works on arbitrary {@link CharSequence} objects instead than
@@ -418,6 +367,107 @@ search:     for (; fromIndex <= toIndex;
     }
 
     /**
+     * Returns the index within the given character sequence of the first occurrence of the
+     * specified character, starting the search at the specified index. If the character is
+     * not found, then this method returns -1.
+     *
+     * <p>There is no restriction on the value of {@code fromIndex}. If negative or greater
+     * than {@code toIndex}, then the behavior of this method is as if the search started
+     * from 0 or {@code toIndex} respectively. This is consistent with the behavior documented
+     * in {@link String#indexOf(int, int)}.</p>
+     *
+     * @param  text      The character sequence in which to perform the search, or {@code null}.
+     * @param  toSearch  The Unicode code point of the character to search.
+     * @param  fromIndex The index to start the search from.
+     * @param  toIndex   The index after the last character where to perform the search.
+     * @return The index of the first occurrence of the given character in the specified sub-sequence,
+     *         or -1 if no occurrence has been found or if the {@code text} argument is null.
+     *
+     * @see String#indexOf(int, int)
+     */
+    public static int indexOf(final CharSequence text, final int toSearch, int fromIndex, int toIndex) {
+        if (text != null) {
+            final int length = text.length();
+            if (toIndex >= length) {
+                if (text instanceof String) {
+                    // String provides a faster implementation.
+                    return ((String) text).indexOf(toSearch, fromIndex);
+                }
+                toIndex = length;
+            }
+            if (fromIndex < 0) {
+                fromIndex = 0;
+            }
+            char head = (char) toSearch;
+            char tail = (char) 0;
+            if (head != toSearch) { // Outside BMP plane?
+                head = highSurrogate(toSearch);
+                tail = lowSurrogate (toSearch);
+                toIndex--;
+            }
+            while (fromIndex < toIndex) {
+                if (text.charAt(fromIndex) == head) {
+                    if (tail == 0 || text.charAt(fromIndex+1) == tail) {
+                        return fromIndex;
+                    }
+                }
+                fromIndex++;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the index within the given character sequence of the last occurrence of the
+     * specified character, searching backward in the given index range.
+     * If the character is not found, then this method returns -1.
+     *
+     * <p>There is no restriction on the value of {@code toIndex}. If greater than the text length
+     * or less than {@code fromIndex}, then the behavior of this method is as if the search started
+     * from {@code length} or {@code fromIndex} respectively. This is consistent with the behavior
+     * documented in {@link String#lastIndexOf(int, int)}.</p>
+     *
+     * @param  text      The character sequence in which to perform the search, or {@code null}.
+     * @param  toSearch  The Unicode code point of the character to search.
+     * @param  fromIndex The index of the first character in the range where to perform the search.
+     * @param  toIndex   The index after the last character in the range where to perform the search.
+     * @return The index of the last occurrence of the given character in the specified sub-sequence,
+     *         or -1 if no occurrence has been found or if the {@code text} argument is null.
+     *
+     * @see String#lastIndexOf(int, int)
+     */
+    public static int lastIndexOf(final CharSequence text, final int toSearch, int fromIndex, int toIndex) {
+        if (text != null) {
+            if (fromIndex <= 0) {
+                if (text instanceof String) {
+                    // String provides a faster implementation.
+                    return ((String) text).lastIndexOf(toSearch, toIndex - 1);
+                }
+                fromIndex = 0;
+            }
+            final int length = text.length();
+            if (toIndex > length) {
+                toIndex = length;
+            }
+            char tail = (char) toSearch;
+            char head = (char) 0;
+            if (tail != toSearch) { // Outside BMP plane?
+                tail = lowSurrogate (toSearch);
+                head = highSurrogate(toSearch);
+                fromIndex++;
+            }
+            while (toIndex > fromIndex) {
+                if (text.charAt(--toIndex) == tail) {
+                    if (head == 0 || text.charAt(--toIndex) == head) {
+                        return toIndex;
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
      * Returns the index of the first character after the given number of lines.
      * This method counts the number of occurrence of {@code '\n'}, {@code '\r'}
      * or {@code "\r\n"} starting from the given position. When {@code numLines}
@@ -486,11 +536,10 @@ search:     for (; fromIndex <= toIndex;
     }
 
     /**
-     * Returns the index of the first character after all leading whitespace characters
-     * in the given range. If the given range contains only space characters, then this method
-     * returns the index of the first character after the given range, which is always equals
-     * or greater than {@code toIndex}. Note that this character may not exist if {@code toIndex}
-     * is equals to the text length.
+     * Returns the index of the first non-white character in the given range.
+     * If the given range contains only space characters, then this method returns the index of the
+     * first character after the given range, which is always equals or greater than {@code toIndex}.
+     * Note that this character may not exist if {@code toIndex} is equals to the text length.
      *
      * <p>Special cases:</p>
      * <ul>
@@ -498,7 +547,7 @@ search:     for (; fromIndex <= toIndex;
      *       then this method unconditionally returns {@code fromIndex}.</li>
      *   <li>If the given range contains only space characters and the character at {@code toIndex-1}
      *       is the high surrogate of a valid supplementary code point, then this method returns
-     *       {@code toIndex+1} since that value is the index of the next code point.</li>
+     *       {@code toIndex+1}, which is the index of the next code point.</li>
      *   <li>If {@code fromIndex} is negative or {@code toIndex} is greater than the text length,
      *       then the behavior of this method is undefined.</li>
      * </ul>
@@ -524,10 +573,9 @@ search:     for (; fromIndex <= toIndex;
     }
 
     /**
-     * Returns the index of the last character before all trailing whitespace characters
-     * in the given range. If the given range contains only space characters, then this method
-     * returns the index of the first character in the given range, which is always equals or
-     * lower than {@code fromIndex}.
+     * Returns the index <em>after</em> the last non-white character in the given range.
+     * If the given range contains only space characters, then this method returns the index of the
+     * first character in the given range, which is always equals or lower than {@code fromIndex}.
      *
      * <p>Special cases:</p>
      * <ul>
@@ -535,7 +583,7 @@ search:     for (; fromIndex <= toIndex;
      *       then this method unconditionally returns {@code toIndex}.</li>
      *   <li>If the given range contains only space characters and the character at {@code fromIndex}
      *       is the low surrogate of a valid supplementary code point, then this method returns
-     *       {@code fromIndex-1} since that value is the index of the code point.</li>
+     *       {@code fromIndex-1}, which is the index of the code point.</li>
      *   <li>If {@code fromIndex} is negative or {@code toIndex} is greater than the text length,
      *       then the behavior of this method is undefined.</li>
      * </ul>

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Characters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Characters.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Characters.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Characters.java Mon Dec 17 09:08:19 2012
@@ -107,7 +107,7 @@ public final class Characters extends St
      * @param  c The character to test.
      * @return {@code true} if the given character is a superscript.
      */
-    public static boolean isSuperScript(final char c) {
+    public static boolean isSuperScript(final int c) {
         switch (c) {
             case '¹':      // Legacy values in "Latin-1 supplement" space: 00B9, 00B2 and 00B3.
             case '²':      // Those values are outside the normal [2070 … 207F] range.
@@ -130,7 +130,7 @@ public final class Characters extends St
      * @param  c The character to test.
      * @return {@code true} if the given character is a subscript.
      */
-    public static boolean isSubScript(final char c) {
+    public static boolean isSubScript(final int c) {
         return (c>='₀' && c<='₎');
     }
 

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Utilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Utilities.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Utilities.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/Utilities.java Mon Dec 17 09:08:19 2012
@@ -43,33 +43,74 @@ public final class Utilities extends Sta
     }
 
     /**
-     * Returns {@code true} if the given floats are equals. Positive and negative zero are
-     * considered different, while a {@link Float#NaN NaN} value is considered equal to all
-     * other NaN values.
-     *
-     * @param o1 The first value to compare.
-     * @param o2 The second value to compare.
-     * @return {@code true} if both values are equal.
+     * Compares the specified objects for equality, ignoring metadata.
+     * If this method returns {@code true}, then:
      *
-     * @see Float#equals(Object)
+     * <ul>
+     *   <li>If the two given objects are
+     *       {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform math transforms},
+     *       then transforming a set of coordinate values using one transform will produce the same
+     *       results than transforming the same coordinates with the other transform.</li>
+     *
+     *   <li>If the two given objects are
+     *       {@linkplain org.apache.sis.referencing.crs.AbstractCRS Coordinate Reference Systems} (CRS), then a call to
+     *       <code>{@linkplain org.apache.sis.referencing.CRS#findMathTransform findMathTransform}(crs1, crs2)</code>
+     *       will return an identity transform.</li>
+     * </ul>
+     *
+     * If a more lenient comparison allowing slight differences in numerical values is wanted,
+     * then {@link #equalsApproximatively(Object, Object)} can be used instead.
+     *
+     * {@section Implementation note}
+     * This is a convenience method for the following method call:
+     *
+     * {@preformat java
+     *     return deepEquals(object1, object2, ComparisonMode.IGNORE_METADATA);
+     * }
+     *
+     * @param  object1 The first object to compare (may be null).
+     * @param  object2 The second object to compare (may be null).
+     * @return {@code true} if both objects are equal, ignoring metadata.
+     *
+     * @see #deepEquals(Object, Object, ComparisonMode)
+     * @see ComparisonMode#IGNORE_METADATA
      */
-    public static boolean equals(final float o1, final float o2) {
-        return Float.floatToIntBits(o1) == Float.floatToIntBits(o2);
+    public static boolean equalsIgnoreMetadata(final Object object1, final Object object2) {
+        return deepEquals(object1, object2, ComparisonMode.IGNORE_METADATA);
     }
 
     /**
-     * Returns {@code true} if the given doubles are equals. Positive and negative zero are
-     * considered different, while a {@link Double#NaN NaN} value is considered equal to all
-     * other NaN values.
-     *
-     * @param o1 The first value to compare.
-     * @param o2 The second value to compare.
-     * @return {@code true} if both values are equal.
+     * Compares the specified objects for equality, ignoring metadata and slight differences
+     * in numerical values. If this method returns {@code true}, then:
+     *
+     * <ul>
+     *   <li>If the two given objects are
+     *       {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform math transforms},
+     *       then transforming a set of coordinate values using one transform will produce <em>approximatively</em>
+     *       the same results than transforming the same coordinates with the other transform.</li>
+     *
+     *   <li>If the two given objects are
+     *       {@linkplain org.apache.sis.referencing.crs.AbstractCRS Coordinate Reference Systems} (CRS), then a call to
+     *       <code>{@linkplain org.apache.sis.referencing.CRS#findMathTransform findMathTransform}(crs1, crs2)</code>
+     *       will return a transform close to the identity transform.</li>
+     * </ul>
+     *
+     * {@section Implementation note}
+     * This is a convenience method for the following method call:
+     *
+     * {@preformat java
+     *     return deepEquals(object1, object2, ComparisonMode.APPROXIMATIVE);
+     * }
+     *
+     * @param  object1 The first object to compare (may be null).
+     * @param  object2 The second object to compare (may be null).
+     * @return {@code true} if both objects are approximatively equal.
      *
-     * @see Double#equals(Object)
+     * @see #deepEquals(Object, Object, ComparisonMode)
+     * @see ComparisonMode#APPROXIMATIVE
      */
-    public static boolean equals(final double o1, final double o2) {
-        return Double.doubleToLongBits(o1) == Double.doubleToLongBits(o2);
+    public static boolean equalsApproximatively(final Object object1, final Object object2) {
+        return deepEquals(object1, object2, ComparisonMode.APPROXIMATIVE);
     }
 
     /**
@@ -86,7 +127,8 @@ public final class Utilities extends Sta
      * @param  mode    The strictness level of the comparison.
      * @return {@code true} if both objects are equal for the given level of strictness.
      *
-     * @see org.apache.sis.referencing.CRS#equalsIgnoreMetadata(Object, Object)
+     * @see #equalsIgnoreMetadata(Object, Object)
+     * @see #equalsApproximatively(Object, Object)
      */
     public static boolean deepEquals(final Object object1, final Object object2, final ComparisonMode mode) {
         if (object1 == object2) {

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java Mon Dec 17 09:08:19 2012
@@ -34,7 +34,7 @@ import org.apache.sis.internal.util.Obje
 
 
 /**
- * A sequence of identifiers rooted within the context of a {@linkplain DefaultNameSpace namespace}.
+ * Base class for sequence of identifiers rooted within the context of a {@linkplain DefaultNameSpace namespace}.
  * Names are <em>immutable</em>. They may be {@linkplain #toFullyQualifiedName() fully qualified}
  * like {@code "org.opengis.util.Record"}, or they may be relative to a {@linkplain #scope() scope}
  * like {@code "util.Record"} in the {@code "org.opengis"} scope.

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/CodeListFilter.java Mon Dec 17 09:08:19 2012
@@ -22,7 +22,7 @@ import org.apache.sis.util.Characters.Fi
 
 
 /**
- * The filters used by {@link CodeLists#valueOf(Class, String)}.
+ * The filters used by {@link Types#forCodeName(Class, String, boolean)}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.02)

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultInternationalString.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultInternationalString.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultInternationalString.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultInternationalString.java Mon Dec 17 09:08:19 2012
@@ -38,9 +38,9 @@ import org.apache.sis.internal.util.Obje
 
 
 /**
- * An {@linkplain InternationalString international string} using a {@linkplain Map map}
- * of strings for different {@linkplain Locale locales}. Strings for new locales can be
- * {@linkplain #add(Locale, String) added}, but existing strings can not be removed or modified.
+ * An international string using a {@linkplain Map map} of strings for different locales.
+ * Strings for new locales can be {@linkplain #add(Locale, String) added},
+ * but existing strings can not be removed or modified.
  * This behavior is a compromise between making constructions easier, and being suitable for
  * use in immutable objects.
  *
@@ -79,7 +79,7 @@ public class DefaultInternationalString 
      * Creates an international string initialized with the given string.
      * Additional localized strings can been added using one of {@link #add add(…)} methods.
      * The string specified to this constructor is the one that will be returned if no localized
-     * string is found for the {@link Locale} argument in a call to {@link #toString(Locale)}.
+     * string is found for the {@code Locale} argument in a call to {@link #toString(Locale)}.
      *
      * @param string The string in no specific locale, or {@code null} if none.
      */
@@ -152,9 +152,8 @@ public class DefaultInternationalString 
 
     /**
      * Adds a string for the given property key. This is a convenience method for constructing an
-     * {@code DefaultInternationalString} during iteration through the
-     * {@linkplain java.util.Map.Entry entries} in a {@link Map}. It infers the {@link Locale}
-     * from the property {@code key}, using the following steps:
+     * {@code DefaultInternationalString} during iteration through the entries in a {@link Map}.
+     * It infers the {@code Locale} from the property {@code key}, using the following steps:
      *
      * <ul>
      *   <li>If the {@code key} does not start with the specified {@code prefix}, then

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java Mon Dec 17 09:08:19 2012
@@ -61,7 +61,6 @@ import static org.apache.sis.util.iso.De
  *
  * <ul>
  *   <li>{@link #parseGenericName(NameSpace, CharSequence)}</li>
- *   <li>{@link #toArray(Object)} – SIS extension, not in GeoAPI interface</li>
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/ResourceInternationalString.java Mon Dec 17 09:08:19 2012
@@ -22,7 +22,6 @@ import java.util.Properties;
 import java.util.ResourceBundle;
 import java.util.MissingResourceException;
 import net.jcip.annotations.Immutable;
-import org.opengis.util.InternationalString;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
@@ -31,14 +30,14 @@ import org.apache.sis.internal.util.Obje
 
 
 /**
- * An {@linkplain InternationalString international string} backed by a {@linkplain ResourceBundle
- * resource bundle}. A resource bundle can be a Java class or a {@linkplain Properties properties}
- * file, one for each language. The constructor expects the fully qualified class name of the base
+ * An international string backed by a {@linkplain ResourceBundle resource bundle}.
+ * A resource bundle can be a Java class or a {@linkplain Properties properties} file,
+ * one for each language. The constructor expects the fully qualified class name of the base
  * resource bundle (the one used when no resource was found in the client's language). The appropriate
  * resource bundle is loaded at runtime for the client's language by looking for a class or a
  * properties file with the right suffix, for example {@code "_en"} for English or {@code "_fr"}
  * for French. This mechanism is explained in J2SE javadoc for the
- * {@link ResourceBundle#getBundle(String,Locale,ClassLoader) getBundle} static method.
+ * {@link ResourceBundle#getBundle(String, Locale, ClassLoader) getBundle(…)} static method.
  *
  * {@section Example}
  * If a file named "{@code MyResources.properties}" exists in the package {@code org.mypackage}
@@ -91,16 +90,6 @@ public class ResourceInternationalString
     private final transient ClassLoader loader;
 
     /**
-     * Creates a new international string from the specified resource bundle and key.
-     *
-     * @param resources The name of the resource bundle, as a fully qualified class name.
-     * @param key The key for the resource to fetch.
-     */
-    public ResourceInternationalString(final String resources, final String key) {
-        this(resources, key, null);
-    }
-
-    /**
      * Creates a new international string from the specified resource bundle, key and class loader.
      *
      * @param resources The name of the resource bundle, as a fully qualified class name.
@@ -125,7 +114,7 @@ public class ResourceInternationalString
      * @param  locale The locale for which to get the resource bundle.
      * @return The resource bundle for the given locale.
      *
-     * @see ResourceBundle#getBundle(String,Locale)
+     * @see ResourceBundle#getBundle(String, Locale)
      */
     protected ResourceBundle getBundle(final Locale locale) {
         return (loader == null) ? ResourceBundle.getBundle(resources, locale) :

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/SimpleInternationalString.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/SimpleInternationalString.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/SimpleInternationalString.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/SimpleInternationalString.java Mon Dec 17 09:08:19 2012
@@ -22,7 +22,6 @@ import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Locale;
 import net.jcip.annotations.Immutable;
-import org.opengis.util.InternationalString;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
@@ -31,12 +30,12 @@ import org.apache.sis.internal.util.Obje
 
 
 /**
- * An {@linkplain InternationalString international string} consisting of a single string
- * for all {@linkplain Locale locales}. For such a particular case, this implementation is
- * more effective than other implementations provided in this package.
+ * An international string consisting of a single string for all locales.
+ * For such a particular case, this implementation is more effective than
+ * other implementations provided in this package.
  *
  * {@section Instantiation}
- * If the characters sequence to wrap is known to be a {@link String} instance, then
+ * If the characters sequence to wrap is known to be a {@code String} instance, then
  * the {@link #SimpleInternationalString(String)} constructor is okay. Otherwise use
  * the {@link Types#toInternationalString(CharSequence)} method.
  *
@@ -54,7 +53,7 @@ public class SimpleInternationalString e
 
     /**
      * Creates a new instance from the given string. If the type of the text
-     * to wrap is the more generic {@link CharSequence} interface, then use
+     * to wrap is the more generic {@code CharSequence} interface, then use
      * the {@link Types#toInternationalString(CharSequence)} method instead.
      *
      * @param text The string for all locales.

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java Mon Dec 17 09:08:19 2012
@@ -25,7 +25,9 @@ import java.util.ResourceBundle;
 import java.util.MissingResourceException;
 import java.io.IOException;
 import java.io.InputStream;
-
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
 import org.opengis.annotation.UML;
 import org.opengis.util.CodeList;
 import org.opengis.util.NameFactory;
@@ -33,6 +35,7 @@ import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.Identifier;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.collection.BackingStoreException;
@@ -40,12 +43,18 @@ import org.apache.sis.internal.util.Defa
 
 
 /**
- * Static methods working on GeoAPI types.
- * The methods in this class can be used for:
+ * Static methods working on GeoAPI types and {@link CodeList} values.
+ * This class provides:
  *
  * <ul>
- *   <li>Creating {@link InternationalString} instances from {@link CharSequence} instances.</li>
- *   <li>Mapping ISO identifiers to the GeoAPI types (interfaces or {@linkplain CodeList code lists}).</li>
+ *   <li>{@link #toInternationalString(CharSequence)} and {@link #toGenericName(Object, NameFactory)}
+ *       for creating name-related objects from various objects.</li>
+ *   <li>{@link #getStandardName(Class)}, {@link #getListName(CodeList)} and {@link #getCodeName(CodeList)}
+ *       for fetching ISO names if possible.</li>
+ *   <li>{@link #getCodeTitle(CodeList, Locale)}, {@link #getDescription(CodeList, Locale)} and
+ *       {@link #getDescription(Class, Locale)} for fetching human-readable descriptions.</li>
+ *   <li>{@link #forStandardName(String)} and {@link #forCodeName(Class, String, boolean)} for
+ *       fetching an instance from a name (converse of above {@code get} methods).</li>
  * </ul>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
@@ -55,8 +64,16 @@ import org.apache.sis.internal.util.Defa
  */
 public final class Types extends Static {
     /**
+     * The class loader to use for fetching GeoAPI resources.
+     * Since the resources are bundled in the GeoAPI JAR file,
+     * we use the instance that loaded GeoAPI for more determinist behavior.
+     */
+    private static final ClassLoader CLASSLOADER = UML.class.getClassLoader();
+
+    /**
      * The types for ISO 19115 UML identifiers. The keys are UML identifiers. Values
      * are either class names as {@link String} objects, or the {@link Class} instances.
+     * This map will be built only when first needed.
      *
      * @see #forName(String)
      */
@@ -74,12 +91,21 @@ public final class Types extends Static 
      * Examples:
      *
      * <ul>
-     *   <li><code>getStandardName({@linkplain org.opengis.metadata.citation.Citation}.class)</code>   returns {@code "CI_Citation"}.</li>
-     *   <li><code>getStandardName({@linkplain org.opengis.referencing.cs.AxisDirection}.class)</code> returns {@code "CS_AxisDirection"}.</li>
+     *   <li><code>getStandardName({@linkplain org.opengis.metadata.citation.Citation}.class)</code>
+     *       (an interface) returns {@code "CI_Citation"}.</li>
+     *   <li><code>getStandardName({@linkplain org.opengis.referencing.cs.AxisDirection}.class)</code>
+     *       (a code list) returns {@code "CS_AxisDirection"}.</li>
      * </ul>
      *
+     * This method looks for the {@link UML} annotation on the given type. It does not search for
+     * parent classes or interfaces if the given type is not directly annotated (i.e. {@code @UML}
+     * annotations are not inherited). If no annotation is found, then this method does not fallback
+     * on the Java name since, as the name implies, this method is about standard names.
+     *
      * @param  type The GeoAPI interface or code list from which to get the ISO name, or {@code null}.
-     * @return The ISO name for the given type, or {@code null} if none or if the type is {@code null}.
+     * @return The ISO name for the given type, or {@code null} if none or if the given type is {@code null}.
+     *
+     * @see #forStandardName(String)
      */
     public static String getStandardName(final Class<?> type) {
         if (type != null) {
@@ -95,6 +121,247 @@ public final class Types extends Static 
     }
 
     /**
+     * Returns the ISO classname (if available) or the Java classname (as a fallback)
+     * of the given code. This method uses the {@link UML} annotation if it exists, or
+     * fallback on the {@linkplain Class#getSimpleName() simple class name} otherwise.
+     * Examples:
+     *
+     * <ul>
+     *   <li>{@code getListName(AxisDirection.NORTH)} returns {@code "CS_AxisDirection"}.</li>
+     *   <li>{@code getListName(CharacterSet.UTF_8)} returns {@code "MD_CharacterSetCode"}.</li>
+     *   <li>{@code getListName(ImagingCondition.BLURRED_IMAGE)} returns {@code "MD_ImagingConditionCode"}.</li>
+     * </ul>
+     *
+     * @param  code The code for which to get the class name, or {@code null}.
+     * @return The ISO (preferred) or Java (fallback) class name, or {@code null} if the given code is null.
+     */
+    public static String getListName(final CodeList<?> code) {
+        if (code == null) {
+            return null;
+        }
+        final Class<?> type = code.getClass();
+        final String id = getStandardName(type);
+        return (id != null) ? id : type.getSimpleName();
+    }
+
+    /**
+     * Returns the ISO name (if available) or the Java name (as a fallback) of the given code.
+     * If the code has no {@link UML} identifier, then the programmatic name is used as a fallback.
+     * Examples:
+     *
+     * <ul>
+     *   <li>{@code getCodeName(AxisDirection.NORTH)} returns {@code "north"}.</li>
+     *   <li>{@code getCodeName(CharacterSet.UTF_8)} returns {@code "utf8"}.</li>
+     *   <li>{@code getCodeName(ImagingCondition.BLURRED_IMAGE)} returns {@code "blurredImage"}.</li>
+     * </ul>
+     *
+     * @param  code The code for which to get the name, or {@code null}.
+     * @return The UML identifiers or programmatic name for the given code,
+     *         or {@code null} if the given code is null.
+     *
+     * @see #getCodeTitle(CodeList)
+     * @see #getDescription(CodeList, Locale)
+     * @see #forCodeName(Class, String, boolean)
+     */
+    public static String getCodeName(final CodeList<?> code) {
+        if (code == null) {
+            return null;
+        }
+        final String id = code.identifier();
+        return (id != null && !id.isEmpty()) ? id : code.name();
+    }
+
+    /**
+     * Returns a unlocalized title for the given code.
+     * This method builds a title using heuristics rules, which should give reasonable
+     * results without the need of resource bundles. For better results, consider using
+     * {@link #getCodeTitle(CodeList, Locale)} instead.
+     *
+     * <p>The current heuristic implementation iterates over {@linkplain CodeList#names() all
+     * code names}, selects the longest one excluding the {@linkplain CodeList#name() field name}
+     * if possible, then {@linkplain CharSequences#camelCaseToSentence(CharSequence) makes a sentence}
+     * from that name. Examples:</p>
+     *
+     * <ul>
+     *   <li>{@code getCodeTitle(AxisDirection.NORTH)} returns {@code "North"}.</li>
+     *   <li>{@code getCodeTitle(CharacterSet.UTF_8)} returns {@code "UTF-8"}.</li>
+     *   <li>{@code getCodeTitle(ImagingCondition.BLURRED_IMAGE)} returns {@code "Blurred image"}.</li>
+     * </ul>
+     *
+     * @param  code The code from which to get a title, or {@code null}.
+     * @return A unlocalized title for the given code, or {@code null} if the given code is null.
+     *
+     * @see #getCodeName(CodeList)
+     * @see #getDescription(CodeList, Locale)
+     */
+    public static String getCodeTitle(final CodeList<?> code) {
+        if (code == null) {
+            return null;
+        }
+        String id = code.identifier();
+        final String name = code.name();
+        if (id == null) {
+            id = name;
+        }
+        for (final String candidate : code.names()) {
+            if (!candidate.equals(name) && candidate.length() >= id.length()) {
+                id = candidate;
+            }
+        }
+        return CharSequences.camelCaseToSentence(id).toString();
+    }
+
+    /**
+     * Returns the localized title of the given code.
+     * Special cases:
+     *
+     * <ul>
+     *   <li>If {@code code} is {@code null}, then this method returns {@code null}.</li>
+     *   <li>If {@code locale} is {@code null}, then this method uses {@link Locale#US}
+     *       as a close approximation of "unlocalized" strings since OGC standards are
+     *       defined in English.</li>
+     *   <li>If there is no resources for the given code in the given language, then this method
+     *       fallback on other languages as described in {@link ResourceBundle} javadoc.</li>
+     *   <li>If there is no localized resources for the given code, then this method fallback
+     *       on {@link #getCodeTitle(CodeList)}.</li>
+     * </ul>
+     *
+     * @param  code   The code for which to get the localized name, or {@code null}.
+     * @param  locale The local, or {@code null} if none.
+     * @return The localized title, or {@code null} if the given code is null.
+     *
+     * @see #getDescription(CodeList, Locale)
+     */
+    public static String getCodeTitle(final CodeList<?> code, Locale locale) {
+        if (code == null) {
+            return null;
+        }
+        if (locale == null) {
+            locale = Locale.US;
+        }
+        /*
+         * The code below is a duplicated - in a different way - of CodeListProxy(CodeList)
+         * constructor (org.apache.sis.internal.jaxb.code package). This duplication exists
+         * because CodeListProxy constructor stores more information in an opportunist way.
+         * If this method is updated, please update CodeListProxy(CodeList) accordingly.
+         */
+        final String key = getListName(code) + '.' + getCodeName(code);
+        try {
+            return ResourceBundle.getBundle("org.opengis.metadata.CodeLists", locale, CLASSLOADER).getString(key);
+        } catch (MissingResourceException e) {
+            Logging.recoverableException(Types.class, "getCodeTitle", e);
+            return getCodeTitle(code);
+        }
+    }
+
+    /**
+     * Returns the localized description of the given code, or {@code null} if none.
+     * Special cases:
+     *
+     * <ul>
+     *   <li>If {@code code} is {@code null}, then this method returns {@code null}.</li>
+     *   <li>If {@code locale} is {@code null}, then this method uses the
+     *       {@linkplain Locale#getDefault() default locale} - there is no such thing
+     *       like "unlocalized" description.</li>
+     *   <li>If there is no resources for the given code in the given language, then this method
+     *       fallback on other languages as described in {@link ResourceBundle} javadoc.</li>
+     *   <li>If there is no localized resources for the given code, then this method returns
+     *       {@code null} - there is no fallback.</li>
+     * </ul>
+     *
+     * For a description of the code list as a whole instead than a particular code,
+     * see {@link Types#getDescription(Class, Locale)}.
+     *
+     * @param  code   The code for which to get the localized description, or {@code null}.
+     * @param  locale The desired local, or {@code null} for the default locale.
+     * @return The localized description, or {@code null} if the given code is null.
+     *
+     * @see #getCodeTitle(CodeList, Locale)
+     * @see #getDescription(Class, Locale)
+     */
+    public static String getDescription(final CodeList<?> code, final Locale locale) {
+        return (code != null) ? getDescription(getListName(code) + '.' + getCodeName(code), locale) : null;
+    }
+
+    /**
+     * Returns a localized description for the given class, or {@code null} if none.
+     * This method can be used for GeoAPI interfaces or {@link CodeList}.
+     * Special cases:
+     *
+     * <ul>
+     *   <li>If {@code code} is {@code null}, then this method returns {@code null}.</li>
+     *   <li>If {@code locale} is {@code null}, then this method uses the
+     *       {@linkplain Locale#getDefault() default locale} - there is no such thing
+     *       like "unlocalized" description.</li>
+     *   <li>If there is no resources for the given type in the given language, then this method
+     *       fallback on other languages as described in {@link ResourceBundle} javadoc.</li>
+     *   <li>If there is no localized resources for the given type, then this method returns
+     *       {@code null} - there is no fallback.</li>
+     * </ul>
+     *
+     * @param  type The GeoAPI interface or code list from which to get the description, or {@code null}.
+     * @param  locale The desired local, or {@code null} for the default locale.
+     * @return The ISO name for the given type, or {@code null} if none or if the type is {@code null}.
+     *
+     * @see #getDescription(CodeList, Locale)
+     */
+    public static String getDescription(final Class<?> type, final Locale locale) {
+        return getDescription(getStandardName(type), locale);
+    }
+
+    /**
+     * Returns the descriptions for the given key in the given locale.
+     *
+     * @param  key     The ISO identifier of a class, or a class property, or a code list value.
+     * @param  locale  The locale in which to get the description.
+     * @return The description, or {@code null} if none.
+     */
+    private static String getDescription(final String key, Locale locale) {
+        if (key != null) {
+            if (locale == null) {
+                locale = Locale.getDefault();
+            }
+            try {
+                return ResourceBundle.getBundle("org.opengis.metadata.Descriptions", locale, CLASSLOADER).getString(key);
+            } catch (MissingResourceException e) {
+                Logging.recoverableException(Types.class, "getDescription", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns all known values for the given type of code list.
+     * Note that the size of the returned array may growth between different invocations of this method,
+     * since users can add their own codes to an existing list.
+     *
+     * @param <T> The compile-time type given as the {@code codeType} parameter.
+     * @param codeType The type of code list.
+     * @return The list of values for the given code list, or an empty array if none.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T extends CodeList<?>> T[] getCodeValues(final Class<T> codeType) {
+        Object values;
+        try {
+            values = codeType.getMethod("values", (Class<?>[]) null).invoke(null, (Object[]) null);
+        } catch (InvocationTargetException e) {
+            final Throwable cause = e.getCause();
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException) cause;
+            }
+            if (cause instanceof Error) {
+                throw (Error) cause;
+            }
+            throw new UndeclaredThrowableException(cause);
+        } catch (NoSuchMethodException e) {
+            values = Array.newInstance(codeType, 0);
+        } catch (IllegalAccessException e) {
+            values = Array.newInstance(codeType, 0);
+        }
+        return (T[]) values;
+    }
+
+    /**
      * Returns the GeoAPI interface for the given ISO name, or {@code null} if none.
      * The identifier argument shall be the value documented in the {@link UML#identifier()}
      * annotation associated with the GeoAPI interface.
@@ -125,7 +392,9 @@ public final class Types extends Static 
             try {
                 props.load(in);
                 in.close();
-            } catch (Exception e) { // (IOException | IllegalArgumentException) on JDK7
+            } catch (IOException e) {
+                throw new BackingStoreException(e);
+            } catch (IllegalArgumentException e) {
                 throw new BackingStoreException(e);
             }
             typeForNames = new HashMap<Object,Object>(props);
@@ -145,42 +414,43 @@ public final class Types extends Static 
     }
 
     /**
-     * Returns a localized description for the given class, or {@code null} if none.
-     * This method can be used for GeoAPI interfaces or {@link CodeList}.
-     * Special cases:
+     * Returns the code of the given type that matches the given name, or optionally returns a new
+     * one if none match it. This method performs the same work than the GeoAPI {@code valueOf(…)}
+     * method, except that this method is more tolerant on string comparisons when looking for an
+     * existing code:
      *
      * <ul>
-     *   <li>If {@code code} is {@code null}, then this method returns {@code null}.</li>
-     *   <li>If {@code locale} is {@code null}, then this method uses the
-     *       {@linkplain Locale#getDefault() default locale} - there is no such thing
-     *       like "unlocalized" description.</li>
-     *   <li>If there is no resources for the given type in the given language, then this method
-     *       fallback on other languages as described in {@link ResourceBundle} javadoc.</li>
-     *   <li>If there is no localized resources for the given type, then this method returns
-     *       {@code null} - there is no fallback.</li>
+     *   <li>Name comparisons are case-insensitive.</li>
+     *   <li>Only {@linkplain Character#isLetterOrDigit(int) letter and digit} characters are compared.
+     *       Spaces and punctuation characters like {@code '_'} and {@code '-'} are ignored.</li>
      * </ul>
      *
-     * @param  type The GeoAPI interface or code list from which to get the description, or {@code null}.
-     * @param  locale The desired local, or {@code null} for the default locale.
-     * @return The ISO name for the given type, or {@code null} if none or if the type is {@code null}.
+     * If no match is found, then a new code is created only if the {@code canCreate} argument is
+     * {@code true}. Otherwise this method returns {@code null}.
+     *
+     * @param <T>        The compile-time type given as the {@code codeType} parameter.
+     * @param codeType   The type of code list.
+     * @param name       The name of the code to obtain, or {@code null}.
+     * @param canCreate  {@code true} if this method is allowed to create new code.
+     * @return A code matching the given name, or {@code null} if the name is null
+     *         or if no matching code is found and {@code canCreate} is {@code false}.
      *
-     * @see CodeLists#getDescription(CodeList, Locale)
+     * @see CodeList#valueOf(Class, String)
      */
-    public static String getDescription(final Class<?> type, Locale locale) {
-        if (type != null) {
-            final String name = getStandardName(type);
-            if (name != null) {
-                if (locale == null) {
-                    locale = Locale.getDefault();
-                }
-                try {
-                    return ResourceBundle.getBundle("org.opengis.metadata.Descriptions", locale).getString(name);
-                } catch (MissingResourceException e) {
-                    Logging.recoverableException(Types.class, "getDescription", e);
-                }
-            }
+    public static <T extends CodeList<T>> T forCodeName(final Class<T> codeType, String name, final boolean canCreate) {
+        name = CharSequences.trimWhitespaces(name);
+        if (name == null || name.isEmpty()) {
+            return null;
         }
-        return null;
+        final String typeName = codeType.getName();
+        try {
+            // Forces initialization of the given class in order
+            // to register its list of static final constants.
+            Class.forName(typeName, true, codeType.getClassLoader());
+        } catch (ClassNotFoundException e) {
+            throw new TypeNotPresentException(typeName, e); // Should never happen.
+        }
+        return CodeList.valueOf(codeType, new CodeListFilter(name, canCreate));
     }
 
     /**

Modified: sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java?rev=1422804&r1=1422803&r2=1422804&view=diff
==============================================================================
--- sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java (original)
+++ sis/branches/JDK6/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java Mon Dec 17 09:08:19 2012
@@ -48,7 +48,7 @@
  * in the {@code "org.opengis"} scope). The illustration below shows all possible constructions
  * for {@code "org.opengis.util.Record"}:
  *
- * <blockquote><table border="1" cellpadding="15"><tr><td><table border="0" cellspacing="0">
+ * <blockquote><table class="compact"><tr><td><table class="compact">
  *   <tr>
  *     <th align="right">org</th>
  *     <th>.</th><th>opengis</th>
@@ -66,7 +66,7 @@
  *     <td bgcolor="palegoldenrod" colspan="5"><font size="-1">{@linkplain org.apache.sis.util.iso.DefaultScopedName#tail() tail}</font></td>
  *     <td rowspan="2"></td>
  *     <td rowspan="2" bgcolor="beige" align="left">{@linkplain org.apache.sis.util.iso.DefaultNameSpace#isGlobal() global}</td>
- *     <td rowspan="2" bgcolor="beige" align="right">{@literal {"org", "opengis", "util", "Record"}}</td>
+ *     <td rowspan="2" bgcolor="beige" align="right">{@code {"org", "opengis", "util", "Record"}}</td>
  *     <td rowspan="2"></td>
  *     <td rowspan="2">{@link org.apache.sis.util.iso.DefaultScopedName ScopedName}</td>
  *   </tr>
@@ -81,8 +81,8 @@
  *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">head</font></td><td></td>
  *     <td bgcolor="palegoldenrod" colspan="3"><font size="-1">tail</font></td>
  *     <td rowspan="2"></td>
- *     <td rowspan="2" bgcolor="beige" align="left">{@literal "org"}</td>
- *     <td rowspan="2" bgcolor="beige" align="right">{@literal {"opengis", "util", "Record"}}</td>
+ *     <td rowspan="2" bgcolor="beige" align="left">{@code "org"}</td>
+ *     <td rowspan="2" bgcolor="beige" align="right">{@code {"opengis", "util", "Record"}}</td>
  *     <td rowspan="2"></td>
  *     <td rowspan="2">{@code ScopedName}</td>
  *   </tr>
@@ -97,8 +97,8 @@
  *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">head</font></td><td></td>
  *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">tail</font></td>
  *     <td rowspan="2"></td>
- *     <td rowspan="2" bgcolor="beige" align="left">{@literal "org.opengis"}</td>
- *     <td rowspan="2" bgcolor="beige" align="right">{@literal {"util", "Record"}}</td>
+ *     <td rowspan="2" bgcolor="beige" align="left">{@code "org.opengis"}</td>
+ *     <td rowspan="2" bgcolor="beige" align="right">{@code {"util", "Record"}}</td>
  *     <td rowspan="2"></td>
  *     <td rowspan="2">{@code ScopedName}</td>
  *   </tr>
@@ -112,8 +112,8 @@
  *     <td bgcolor="palegoldenrod" colspan="5" rowspan="2"><font size="-1">scope</font></td><td rowspan="2"></td>
  *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">head</font></td>
  *     <td rowspan="2"></td>
- *     <td rowspan="2" bgcolor="beige" align="left">{@literal "org.opengis.util"}</td>
- *     <td rowspan="2" bgcolor="beige" align="right">{@literal {"Record"}}</td>
+ *     <td rowspan="2" bgcolor="beige" align="left">{@code "org.opengis.util"}</td>
+ *     <td rowspan="2" bgcolor="beige" align="right">{@code {"Record"}}</td>
  *     <td rowspan="2"></td>
  *     <td rowspan="2">{@link org.apache.sis.util.iso.DefaultLocalName LocalName}</td>
  *   </tr>