sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1553457 [2/4] - in /sis/trunk: ./ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ core/sis-metadata/src/test...
Date Thu, 26 Dec 2013 06:04:00 GMT
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -20,7 +20,6 @@ import java.io.Serializable;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import org.opengis.referencing.cs.AxisDirection;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.referencing.AxisDirections;
@@ -30,12 +29,14 @@ import org.apache.sis.internal.referenci
  * Parses {@linkplain AxisDirection axis direction} of the kind "<cite>South along 90 deg East</cite>".
  * Those directions are used in the EPSG database for polar stereographic projections.
  *
+ * {@section Immutability and thread safety}
+ * This final class is immutable and thus inherently thread-safe.
+ *
  * @author  Martin Desruisseaux (IRD)
  * @since   0.4 (derived from geotk-2.4)
  * @version 0.4
  * @module
  */
-@Immutable
 final class DirectionAlongMeridian implements Comparable<DirectionAlongMeridian>, Serializable {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -32,7 +32,6 @@ import org.apache.sis.referencing.Identi
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.util.Classes;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.internal.metadata.MetadataUtilities;
 import org.apache.sis.internal.jaxb.gco.DateAsLongAdapter;
@@ -55,6 +54,12 @@ import org.apache.sis.internal.jdk7.Obje
  * This class is conceptually <cite>abstract</cite>, even if it is technically possible to instantiate it.
  * Typical applications should create instances of the most specific subclass prefixed by {@code Default} instead.
  *
+ * {@section Immutability and thread safety}
+ * This base class is immutable if the property <em>values</em> (not necessarily the map itself) given to the
+ * constructor are also immutable. Most SIS subclasses and related classes are immutable under similar conditions.
+ * This means that unless otherwise noted in the javadoc, {@code Datum} instances created using only SIS factories
+ * and static constants can be shared by many objects and passed between threads without synchronization.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-1.2)
  * @version 0.4
@@ -63,7 +68,6 @@ import org.apache.sis.internal.jdk7.Obje
  * @see org.apache.sis.referencing.cs.AbstractCS
  * @see org.apache.sis.referencing.crs.AbstractCRS
  */
-@Immutable
 @XmlType(name="AbstractDatumType")
 @XmlSeeAlso(
     DefaultGeodeticDatum.class

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -37,7 +37,6 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.io.wkt.Formatter;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.resources.Errors;
 
@@ -105,6 +104,11 @@ import org.apache.sis.internal.jdk7.Obje
  *     Ellipsoid e = GeodeticObjects.WGS84.ellipsoid();
  * }
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
+ * given to the constructors are also immutable. Unless otherwise noted in the javadoc, this condition holds if all
+ * components were created using only SIS factories and static constants.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.4 (derived from geotk-1.2)
@@ -113,7 +117,6 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * @see org.apache.sis.referencing.GeodeticObjects#ellipsoid()
  */
-@Immutable
 @XmlType(name="EllipsoidType", propOrder={
     "semiMajorAxisMeasure",
     "secondDefiningParameter"
@@ -349,12 +352,10 @@ public class DefaultEllipsoid extends Ab
      * been defined, it is now possible to calculate the value of the missing parameter
      * using the values of those that are set.
      *
-     * <p>This method is invoked by JAXB only.</p>
-     *
      * @see #setSemiMajorAxisMeasure(Measure)
      * @see #setSecondDefiningParameter(SecondDefiningParameter)
      */
-    private void afterUnmarshal(Object target, Object parent) {
+    private void afterUnmarshal() {
         if (ivfDefinitive) {
             if (semiMinorAxis == 0) {
                 semiMinorAxis = semiMajorAxis * (1 - 1/inverseFlattening);
@@ -412,9 +413,12 @@ public class DefaultEllipsoid extends Ab
             warnDuplicated("semiMajorAxis");
         } else {
             final Unit<Length> uom = unit; // In case semi-minor were defined before semi-major.
-            semiMajorAxis = measure.value;
+            ensureStrictlyPositive("semiMajorAxis", semiMajorAxis = measure.value);
             unit = measure.getUnit(Length.class);
             harmonizeAxisUnits(uom);
+            if ((ivfDefinitive ? inverseFlattening : semiMinorAxis) != 0) {
+                afterUnmarshal();
+            }
         }
     }
 
@@ -513,30 +517,37 @@ public class DefaultEllipsoid extends Ab
         }
         final Measure measure = second.measure;
         if (measure != null) {
-            double value = measure.value;
-            if (second.isIvfDefinitive()) {
-                if (inverseFlattening == 0) {
-                    inverseFlattening = value;
-                    ivfDefinitive = true;
-                    return;
+            final boolean isIvfDefinitive = second.isIvfDefinitive();
+            if ((isIvfDefinitive ? inverseFlattening : semiMinorAxis) != 0) {
+                warnDuplicated("secondDefiningParameter");
+            } else {
+                ivfDefinitive = isIvfDefinitive;
+                double value = measure.value;
+                if (isIvfDefinitive) {
+                    if (value == 0) {
+                        value = Double.POSITIVE_INFINITY;
+                    }
+                    ensureStrictlyPositive("inverseFlattening", inverseFlattening = value);
+                } else if (semiMinorAxis == 0) {
+                    ensureStrictlyPositive("semiMinorAxis", semiMinorAxis = value);
+                    if (unit == null) {
+                        unit = measure.getUnit(Length.class);
+                    } else {
+                        harmonizeAxisUnits(measure.unit);
+                    }
                 }
-            } else if (semiMinorAxis == 0) {
-                semiMinorAxis = value;
-                ivfDefinitive = false;
-                if (unit == null) {
-                    unit = measure.getUnit(Length.class);
-                } else {
-                    harmonizeAxisUnits(measure.unit);
+                if (semiMajorAxis != 0) {
+                    afterUnmarshal();
                 }
-                return;
             }
-            warnDuplicated("secondDefiningParameter");
         }
     }
 
     /**
      * Ensures that the semi-minor axis uses the same unit than the semi-major one.
+     * The {@link #unit} field shall be set to the semi-major axis unit before this method call.
      *
+     * @param  uom The semi-minor axis unit.
      * @throws ConversionException If semi-major and semi-minor axes use inconsistent units
      *         and we can not convert from one to the other.
      */

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -24,7 +24,6 @@ import org.opengis.util.InternationalStr
 import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.referencing.datum.EngineeringDatum;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.io.wkt.Formatter;
 
 
@@ -34,12 +33,16 @@ import org.apache.sis.io.wkt.Formatter;
  * This origin can be fixed with respect to the earth (such as a defined point at a construction site),
  * or be a defined point on a moving vehicle (such as on a ship or satellite).
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
+ * given to the constructor are also immutable. Unless otherwise noted in the javadoc, this condition holds if all
+ * components were created using only SIS factories and static constants.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-1.2)
  * @version 0.4
  * @module
  */
-@Immutable
 @XmlType(name = "EngineeringDatumType")
 @XmlRootElement(name = "EngineeringDatum")
 public class DefaultEngineeringDatum extends AbstractDatum implements EngineeringDatum {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -37,7 +37,6 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.io.wkt.FormattableObject;
 
@@ -104,6 +103,12 @@ import org.apache.sis.internal.jdk7.Obje
  *     GeodeticDatum datum = GeodeticObjects.WGS84.datum();
  * }
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself),
+ * the {@link Ellipsoid} and the {@link PrimeMeridian} given to the constructor are also immutable. Unless otherwise
+ * noted in the javadoc, this condition holds if all components were created using only SIS factories and static
+ * constants.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-1.2)
  * @version 0.4
@@ -113,7 +118,6 @@ import org.apache.sis.internal.jdk7.Obje
  * @see DefaultPrimeMeridian
  * @see org.apache.sis.referencing.GeodeticObjects#datum()
  */
-@Immutable
 @XmlType(name = "GeodeticDatumType", propOrder = {
     "primeMeridian",
     "ellipsoid"

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -26,7 +26,6 @@ import org.opengis.referencing.datum.Ima
 import org.opengis.referencing.datum.PixelInCell;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.Immutable;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
@@ -39,12 +38,16 @@ import org.apache.sis.internal.jdk7.Obje
  * context only. For an image datum, the anchor point is usually either the centre of the image
  * or the corner of the image.
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
+ * given to the constructor are also immutable. Unless otherwise noted in the javadoc, this condition holds if
+ * all components were created using only SIS factories and static constants.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-2.0)
  * @version 0.4
  * @module
  */
-@Immutable
 @XmlType(name = "ImageDatumType")
 @XmlRootElement(name = "ImageDatum")
 public class DefaultImageDatum extends AbstractDatum implements ImageDatum {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -32,7 +32,6 @@ import org.apache.sis.internal.jaxb.gco.
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.Immutable;
 
 import static org.apache.sis.util.ArgumentChecks.ensureFinite;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -71,6 +70,11 @@ import org.apache.sis.internal.jdk7.Obje
  *     PrimeMeridian pm = GeodeticObjects.WGS84.primeMeridian();
  * }
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
+ * given to the constructor are also immutable. Unless otherwise noted in the javadoc, this condition holds if
+ * all components were created using only SIS factories and static constants.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.4 (derived from geotk-1.2)
@@ -79,7 +83,6 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * @see org.apache.sis.referencing.GeodeticObjects#primeMeridian()
  */
-@Immutable
 @XmlType(name = "PrimeMeridianType")
 @XmlRootElement(name = "PrimeMeridian")
 public class DefaultPrimeMeridian extends AbstractIdentifiedObject implements PrimeMeridian {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java Thu Dec 26 06:03:57 2013
@@ -26,7 +26,6 @@ import org.opengis.referencing.Reference
 import org.opengis.referencing.datum.TemporalDatum;
 import org.apache.sis.internal.metadata.MetadataUtilities;
 import org.apache.sis.util.ComparisonMode;
-import org.apache.sis.util.Immutable;
 
 import static org.apache.sis.internal.util.Numerics.hash;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -61,6 +60,11 @@ import org.apache.sis.internal.jdk7.Obje
  *     TemporalDatum datum = GeodeticObjects.Temporal.JULIAN.datum();
  * }
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
+ * given to the constructor are also immutable. Unless otherwise noted in the javadoc, this condition holds if
+ * all components were created using only SIS factories and static constants.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-1.2)
  * @version 0.4
@@ -68,7 +72,6 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * @see org.apache.sis.referencing.GeodeticObjects.Temporal#datum()
  */
-@Immutable
 @XmlType(name = "TemporalDatumType")
 @XmlRootElement(name = "TemporalDatum")
 public class DefaultTemporalDatum extends AbstractDatum implements TemporalDatum {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -26,7 +26,6 @@ import org.opengis.referencing.Reference
 import org.opengis.referencing.datum.VerticalDatum;
 import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.io.wkt.Formatter;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.jaxb.LegacyNamespaces;
@@ -67,6 +66,11 @@ import org.apache.sis.internal.jdk7.Obje
  *     VerticalDatum datum = GeodeticObjects.Vertical.GEOID.datum();
  * }
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
+ * given to the constructor are also immutable. Unless otherwise noted in the javadoc, this condition holds if
+ * all components were created using only SIS factories and static constants.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-1.2)
  * @version 0.4
@@ -74,7 +78,6 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * @see org.apache.sis.referencing.GeodeticObjects.Vertical#datum()
  */
-@Immutable
 @XmlType(name = "VerticalDatumType")
 @XmlRootElement(name = "VerticalDatum")
 public class DefaultVerticalDatum extends AbstractDatum implements VerticalDatum {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -20,7 +20,6 @@ import java.util.Map;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Length;
 import javax.xml.bind.annotation.XmlTransient;
-import org.apache.sis.util.Immutable;
 
 import static java.lang.Math.*;
 
@@ -29,12 +28,16 @@ import static java.lang.Math.*;
  * A ellipsoid which is spherical. This ellipsoid implements a faster
  * {@link #orthodromicDistance(double, double, double, double)} method.
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
+ * given to the constructor are also immutable. Unless otherwise noted in the javadoc, this condition holds if
+ * all components were created using only SIS factories and static constants.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-2.0)
  * @version 0.4
  * @module
  */
-@Immutable
 @XmlTransient
 final class Sphere extends DefaultEllipsoid {
     /**

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -19,11 +19,14 @@ package org.apache.sis.referencing;
 import java.util.Set;
 import java.util.Map;
 import java.util.HashMap;
+import java.util.LinkedHashSet;
 import java.util.Locale;
 import java.util.Collections;
 import org.opengis.test.Validators;
 import org.opengis.referencing.ReferenceIdentifier;
 import org.apache.sis.metadata.iso.ImmutableIdentifier;
+import org.apache.sis.referencing.datum.AbstractDatum;
+import org.apache.sis.internal.jaxb.referencing.Code;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -44,34 +47,36 @@ import static org.apache.sis.metadata.is
  */
 @DependsOn({
     IdentifiedObjectsTest.class, NamedIdentifierTest.class,
-    org.apache.sis.internal.jaxb.referencing.RS_IdentifierTest.class
+    org.apache.sis.internal.jaxb.referencing.CodeTest.class
 })
 public final strictfp class AbstractIdentifiedObjectTest extends TestCase {
     /**
-     * Tests the {@link AbstractIdentifiedObject#AbstractIdentifiedObject(Map)} constructor.
+     * Creates a map of properties to be given to the {@link AbstractIdentifiedObject} constructor.
+     * The values in the map are consistent with the values expected by the {@link #validate} method.
+     *
+     * @param identifier The value for the {@code "identifiers"} property.
      */
-    @Test
-    public void testCreateFromMap() {
+    private static Map<String,Object> properties(final Set<ReferenceIdentifier> identifiers) {
         final Map<String,Object> properties = new HashMap<String,Object>(8);
         assertNull(properties.put("name",       "GRS 1980"));
+        assertNull(properties.put("identifiers", identifiers.toArray(new ReferenceIdentifier[identifiers.size()])));
         assertNull(properties.put("codespace",  "EPSG"));
         assertNull(properties.put("version",    "8.3"));
-        assertNull(properties.put("alias",      "International 1979"));//7019
+        assertNull(properties.put("alias",      "International 1979"));
         assertNull(properties.put("remarks",    "Adopted by IUGG 1979 Canberra"));
         assertNull(properties.put("remarks_fr", "Adopté par IUGG 1979 Canberra"));
-        validate(new AbstractIdentifiedObject(properties), Collections.<ReferenceIdentifier>emptySet(), "GRS1980");
-        /*
-         * Adds an identifier. This should change the choice made by AbstractIdentifiedObject.getID().
-         */
-        final ReferenceIdentifier identifier = new ImmutableIdentifier(null, "EPSG", "4326");
-        assertNull(properties.put("identifiers", identifier));
-        validate(new AbstractIdentifiedObject(properties), Collections.singleton(identifier), "EPSG4326");
+        return properties;
     }
 
     /**
      * Validates the given object created by {@link #testCreateFromMap()}.
+     *
+     * @param  object      The object to validate.
+     * @param  identifiers The expected value of {@link AbstractIdentifiedObject#getIdentifiers()}.
+     * @param  gmlID       The expected value of {@link AbstractIdentifiedObject#getID()}.
+     * @return The value of {@link AbstractIdentifiedObject#getIdentifier()}.
      */
-    private static void validate(final AbstractIdentifiedObject object,
+    private static ReferenceIdentifier validate(final AbstractIdentifiedObject object,
             final Set<ReferenceIdentifier> identifiers, final String gmlID)
     {
         Validators.validate(object);
@@ -85,51 +90,89 @@ public final strictfp class AbstractIden
         assertEquals("ID",          gmlID,                           object.getID());
         assertEquals("remarks",     "Adopted by IUGG 1979 Canberra", object.getRemarks().toString(Locale.ENGLISH));
         assertEquals("remarks_fr",  "Adopté par IUGG 1979 Canberra", object.getRemarks().toString(Locale.FRENCH));
+        final Code code = object.getIdentifier();
+        return (code != null) ? code.getIdentifier() : null;
+    }
+
+    /**
+     * Tests the {@link AbstractIdentifiedObject#AbstractIdentifiedObject(Map)} constructor without identifier.
+     * This method compares the property values against the expected values.
+     */
+    @Test
+    public void testWithoutIdentifier() {
+        final Set<ReferenceIdentifier> identifiers = Collections.<ReferenceIdentifier>emptySet();
+        final AbstractIdentifiedObject object      = new AbstractIdentifiedObject(properties(identifiers));
+        final ReferenceIdentifier      gmlId       = validate(object, identifiers, "GRS1980");
+        assertNull("gmlId", gmlId);
     }
 
     /**
-     * Tests identifiers getter. The methods of interest to this test are:
+     * Tests the {@link AbstractIdentifiedObject#AbstractIdentifiedObject(Map)} constructor
+     * with only one identifier. The methods of interest for this test are:
      *
      * <ul>
      *   <li>{@link AbstractIdentifiedObject#getIdentifiers()}</li>
+     *   <li>{@link AbstractIdentifiedObject#getIdentifier()}</li>
      *   <li>{@link AbstractIdentifiedObject#getID()}</li>
      * </ul>
-     *
-     * Note that {@code getID()} were also tested in {@link #testCreateFromMap()}
-     * but in the absence of identifiers.
      */
     @Test
-    @DependsOnMethod("testCreateFromMap")
-    public void testGetIdentifiers() {
-        final Map<String,Object> properties = new HashMap<String,Object>(8);
-        assertNull(properties.put("name", "WGS 84"));
-        assertNull(properties.put("identifiers", new NamedIdentifier[] {
-            new NamedIdentifier(EPSG, "4326"),
-            new NamedIdentifier(EPSG, "IgnoreMe")
-        }));
+    @DependsOnMethod("testWithoutIdentifier")
+    public void testWithSingleIdentifier() {
+        final ReferenceIdentifier      identifier  = new ImmutableIdentifier(null, "EPSG", "7019");
+        final Set<ReferenceIdentifier> identifiers = Collections.singleton(identifier);
+        final AbstractIdentifiedObject object      = new AbstractIdentifiedObject(properties(identifiers));
+        final ReferenceIdentifier      gmlId       = validate(object, identifiers, "epsg-7019");
+        assertNotNull("gmlId",                   gmlId);
+        assertEquals ("gmlId.codespace", "EPSG", gmlId.getCodeSpace());
+        assertEquals ("gmlId.code",      "7019", gmlId.getCode());
+    }
 
-        final AbstractIdentifiedObject object = new AbstractIdentifiedObject(properties);
-        Validators.validate(object);
+    /**
+     * Tests the {@link AbstractIdentifiedObject#AbstractIdentifiedObject(Map)} constructor
+     * with more than one identifier. This method tries a different identifier implementation
+     * than the {@link #testCreateWithSingleIdentifier()} one.
+     */
+    @Test
+    @DependsOnMethod("testWithSingleIdentifier")
+    public void testWithManyIdentifiers() {
+        final Set<ReferenceIdentifier> identifiers = new LinkedHashSet<ReferenceIdentifier>(4);
+        assertTrue(identifiers.add(new NamedIdentifier(EPSG, "7019")));
+        assertTrue(identifiers.add(new NamedIdentifier(EPSG, "IgnoreMe")));
+        final AbstractIdentifiedObject object = new AbstractIdentifiedObject(properties(identifiers));
+        final ReferenceIdentifier      gmlId  = validate(object, identifiers, "epsg-7019");
+        assertNotNull("gmlId",                   gmlId);
+        assertEquals ("gmlId.codespace", "EPSG", gmlId.getCodeSpace());
+        assertEquals ("gmlId.code",      "7019", gmlId.getCode());
+    }
 
-        assertEquals("name",        "WGS 84",                     object.getName().getCode());
-        assertEquals("identifiers", "[EPSG:4326, EPSG:IgnoreMe]", object.getIdentifiers().toString());
-        assertEquals("ID",          "EPSG4326",                   object.getID());
+    /**
+     * Tests {@link AbstractIdentifiedObject#getIdentifier()} with a sub-type of {@code AbstractIdentifiedObject}.
+     * The use of a subtype will allow {@code getIdentifier()} to build a URN and {@code getId()} to know what to
+     * insert between {@code "epsg-"} and the code.
+     */
+    @Test
+    @DependsOnMethod("testWithManyIdentifiers")
+    public void testAsSubtype() {
+        final ReferenceIdentifier      identifier  = new NamedIdentifier(EPSG, "7019");
+        final Set<ReferenceIdentifier> identifiers = Collections.singleton(identifier);
+        final AbstractIdentifiedObject object      = new AbstractDatum(properties(identifiers));
+        final ReferenceIdentifier      gmlId       = validate(object, identifiers, "epsg-datum-7019");
+        assertNotNull("gmlId",                   gmlId);
+        assertEquals ("gmlId.codespace", "EPSG", gmlId.getCodeSpace());
+        assertEquals ("gmlId.code",      "7019", gmlId.getCode());
     }
 
     /**
      * Tests serialization.
      */
     @Test
-    @DependsOnMethod("testCreateFromMap")
+    @DependsOnMethod("testWithoutIdentifier")
     public void testSerialization() {
-        final Map<String,Object> properties = new HashMap<String,Object>(8);
-        assertNull(properties.put("code",      "4326"));
-        assertNull(properties.put("codeSpace", "EPSG"));
-        assertNull(properties.put("remarks",   "There is remarks"));
-
-        final AbstractIdentifiedObject object = new AbstractIdentifiedObject(properties);
-        Validators.validate(object);
-
-        assertNotSame(object, assertSerializedEquals(object));
+        final Set<ReferenceIdentifier> identifiers = Collections.emptySet();
+        final AbstractIdentifiedObject object      = new AbstractIdentifiedObject(properties(identifiers));
+        final AbstractIdentifiedObject actual      = assertSerializedEquals(object);
+        assertNotSame(object, actual);
+        assertNull("gmlId", validate(actual, identifiers, "GRS1980"));
     }
 }

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DatumTestCase.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DatumTestCase.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DatumTestCase.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DatumTestCase.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -24,7 +24,7 @@ import org.opengis.referencing.datum.Pri
 import org.apache.sis.xml.MarshallerPool;
 import org.apache.sis.test.XMLTestCase;
 
-import static org.opengis.test.Assert.*;
+import static org.apache.sis.test.Assert.*;
 
 
 /**
@@ -61,6 +61,19 @@ abstract strictfp class DatumTestCase ex
     }
 
     /**
+     * Marshals the given object and ensure that the result is equals to the content of the given file,
+     * ignoring namespace declarations.
+     *
+     * @param  filename The name of the XML file.
+     * @param  object The object to marshal.
+     * @throws JAXBException If an error occurred during marshalling.
+     */
+    final void assertMarshalEqualsFile(final String filename, final Object object) throws JAXBException {
+        assertXmlEquals(getResource(filename), marshal(object), "xlmns:*", "xsi:schemaLocation",
+                "xmlns:xsi"); // Not necessary on JDK7 but needed on JDK6, not sure why...
+    }
+
+    /**
      * Unmarshalls the given test file.
      *
      * @param  type The expected object type.

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -17,6 +17,8 @@
 package org.apache.sis.referencing.datum;
 
 import java.util.Random;
+import javax.xml.bind.JAXBException;
+import javax.measure.unit.NonSI;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Longitude;
 import org.apache.sis.referencing.IdentifiedObjects;
@@ -157,4 +159,25 @@ public final strictfp class DefaultEllip
         final DefaultEllipsoid e = new DefaultEllipsoid(GeodeticDatumMock.WGS84.getEllipsoid());
         assertWktEquals(e, "SPHEROID[“WGS84”, 6378137.0, 298.257223563]");
     }
+
+    /**
+     * Tests unmarshalling and marshalling.
+     *
+     * @throws JAXBException If an error occurred during (un)marshalling.
+     */
+    @Test
+    public void testXML() throws JAXBException {
+        final DefaultEllipsoid ellipsoid = unmarshall(DefaultEllipsoid.class, "Clarke 1880.xml");
+        assertEquals("name", "Clarke 1880 (international foot)", ellipsoid.getName().getCode());
+        assertEquals("remarks", "Definition in feet assumed to be international foot.", ellipsoid.getRemarks().toString());
+        assertFalse ("isIvfDefinitive",                       ellipsoid.isIvfDefinitive());
+        assertEquals("semiMajorAxis",     20926202,           ellipsoid.getSemiMajorAxis(), 0);
+        assertEquals("semiMinorAxis",     20854895,           ellipsoid.getSemiMinorAxis(), 0);
+        assertEquals("inverseFlattening", 293.46630765562986, ellipsoid.getInverseFlattening(), 1E-12);
+        assertEquals("axisUnit",          NonSI.FOOT,         ellipsoid.getAxisUnit());
+        /*
+         * Marshall and compare to the original file.
+         */
+        assertMarshalEqualsFile("Clarke 1880.xml", ellipsoid);
+    }
 }

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -142,7 +142,7 @@ public final strictfp class DefaultPrime
         assertWktEquals(pm, "PRIMEM[“Paris”, 2.33722917, AUTHORITY[“EPSG”, “8903”]]");
         assertXmlEquals(
                 "<gml:PrimeMeridian xmlns:gml=\"" + Namespaces.GML + "\">\n" +
-                "  <gml:identifier codeSpace=\"EPSG\">8903</gml:identifier>" +
+                "  <gml:identifier codeSpace=\"OGP\">urn:ogc:def:meridian:EPSG::8903</gml:identifier>" +
                 "  <gml:name>Paris</gml:name>\n" +
                 "  <gml:remarks>Equivalent to 2°20′14.025″.</gml:remarks>\n" +
                 "  <gml:greenwichLongitude uom=\"urn:ogc:def:uom:EPSG::9105\">2.5969213</gml:greenwichLongitude>\n" +

Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -44,10 +44,11 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.referencing.FormulasTest.class,
     org.apache.sis.internal.referencing.VerticalDatumTypesTest.class,
     org.apache.sis.internal.referencing.AxisDirectionsTest.class,
+    org.apache.sis.internal.referencing.ReferencingUtilitiesTest.class,
     org.apache.sis.io.wkt.ConventionTest.class,
     org.apache.sis.io.wkt.SymbolsTest.class,
     org.apache.sis.io.wkt.FormatterTest.class,
-    org.apache.sis.internal.jaxb.referencing.RS_IdentifierTest.class,
+    org.apache.sis.internal.jaxb.referencing.CodeTest.class,
     org.apache.sis.referencing.IdentifiedObjectsTest.class,
     org.apache.sis.referencing.NamedIdentifierTest.class,
     org.apache.sis.referencing.AbstractIdentifiedObjectTest.class,

Modified: sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Greenwich.xml
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Greenwich.xml?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Greenwich.xml (original)
+++ sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Greenwich.xml Thu Dec 26 06:03:57 2013
@@ -21,7 +21,8 @@
 <gml:PrimeMeridian
     xmlns:gml = "http://www.opengis.net/gml/3.2"
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation = "http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/datums.xsd">
+    xsi:schemaLocation = "http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/datums.xsd"
+    gml:id = "epsg-meridian-8901">
 
   <gml:identifier codeSpace="OGP">urn:ogc:def:meridian:EPSG::8901</gml:identifier>
   <gml:name>Greenwich</gml:name>

Modified: sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Paris.xml
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Paris.xml?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Paris.xml (original)
+++ sis/trunk/core/sis-referencing/src/test/resources/org/apache/sis/referencing/datum/Paris.xml Thu Dec 26 06:03:57 2013
@@ -21,10 +21,11 @@
 <gml:PrimeMeridian
     xmlns:gml = "http://www.opengis.net/gml/3.2"
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation = "http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/datums.xsd">
+    xsi:schemaLocation = "http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/datums.xsd"
+    gml:id = "epsg-meridian-8903">
 
   <gml:identifier codeSpace="OGP">urn:ogc:def:meridian:EPSG::8903</gml:identifier>
   <gml:name>Paris</gml:name>
-  <gml:greenwichLongitude uom="urn:ogc:def:uom:EPSG::9105">2.5969213</gml:greenwichLongitude>
   <gml:remarks>Equivalent to 2°20′14.025″.</gml:remarks>
+  <gml:greenwichLongitude uom="urn:ogc:def:uom:EPSG::9105">2.5969213</gml:greenwichLongitude>
 </gml:PrimeMeridian>

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/AngleConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/AngleConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/AngleConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/AngleConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.internal.converte
 
 import java.util.Set;
 import org.apache.sis.measure.Angle;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.math.FunctionProperty;
 
@@ -26,12 +25,15 @@ import org.apache.sis.math.FunctionPrope
 /**
  * Handles conversions between {@link Angle} and {@link Double}.
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus inherently thread-safe.
+ * The same {@link #INSTANCE} can be passed between threads without synchronization.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
  * @version 0.3
  * @module
  */
-@Immutable
 public final class AngleConverter extends SystemConverter<Angle,Double> {
     /** For cross-version compatibility. */
     private static final long serialVersionUID = -5124032874967170238L;
@@ -67,8 +69,10 @@ public final class AngleConverter extend
 
     /**
      * The inverse of {@link AngleConverter}.
+     *
+     * {@section Thread safety}
+     * This class is immutable, and thus inherently thread-safe.
      */
-    @Immutable
     public static final class Inverse extends SystemConverter<Double,Angle> {
         /** For cross-version compatibility. */
         private static final long serialVersionUID = -1736966474591258159L;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ArrayConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ArrayConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ArrayConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ArrayConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -20,7 +20,6 @@ import java.util.Set;
 import java.util.EnumSet;
 import java.lang.reflect.Array;
 import org.apache.sis.math.FunctionProperty;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
@@ -32,12 +31,15 @@ import org.apache.sis.util.Unconvertible
  * the source and target types of the element converter shall be {@code <? super S>} and {@code <? extends T>}
  * respectively.
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable, and thus inherently thread-safe,
+ * if the converter given to the constructor is also immutable.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
  * @version 0.3
  * @module
  */
-@Immutable
 final class ArrayConverter<S,T> extends SystemConverter<S,T> {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/CharSequenceConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/CharSequenceConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/CharSequenceConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/CharSequenceConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.internal.converte
 
 import java.util.EnumSet;
 import java.util.Set;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.math.FunctionProperty;
 import org.apache.sis.util.UnconvertibleObjectException;
@@ -33,12 +32,15 @@ import org.apache.sis.util.Unconvertible
  * <p>The main purpose of this class is to support the conversion of
  * {@link org.opengis.util.InternationalString}.</p>
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable, and thus inherently thread-safe,
+ * if the converter given to the constructor is also immutable.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.02)
  * @version 0.3
  * @module
  */
-@Immutable
 final class CharSequenceConverter<T> extends SystemConverter<CharSequence,T> {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ClassPair.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.internal.converte
 
 import java.io.Serializable;
 import org.apache.sis.util.ObjectConverter;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.Debug;
 
 
@@ -30,6 +29,11 @@ import org.apache.sis.util.Debug;
  * <strong>No other direct subtype shall exist</strong>.
  * See {@link #equals(Object)} for an explanation.</p>
  *
+ * {@section Immutability and thread safety}
+ * This base class is immutable and thus inherently thread-safe. {@code ClassPair} immutability is necessary
+ * for {@link ConverterRegistry}. Subclasses should also be immutable, but this requirement is not as strong
+ * as for {@code ClassPair} (because subclasses are not used as keys in hash map).
+ *
  * @param <S> The base type of source objects.
  * @param <T> The base type of converted objects.
  *
@@ -38,7 +42,6 @@ import org.apache.sis.util.Debug;
  * @version 0.3
  * @module
  */
-@Immutable
 class ClassPair<S,T> implements Serializable {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/CollectionConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/CollectionConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/CollectionConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/CollectionConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -20,7 +20,6 @@ import java.util.Collection;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.LinkedHashSet;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.math.FunctionProperty;
 
 
@@ -29,12 +28,15 @@ import org.apache.sis.math.FunctionPrope
  * The source class is fixed to {@code Collection}. The target class is determined
  * by the inner class which extends this {@code CollectionConverter} class.
  *
+ * {@section Immutability and thread safety}
+ * This base class is immutable, and thus inherently thread-safe. Subclasses should be immutable
+ * and thread-safe too if they are intended to be cached in {@link ConverterRegistry}.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.02)
  * @version 0.3
  * @module
  */
-@Immutable
 abstract class CollectionConverter<T> extends SystemConverter<Collection<?>,T> {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ConverterRegistry.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -21,7 +21,6 @@ import java.util.LinkedHashMap;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.Numbers;
-import org.apache.sis.util.ThreadSafe;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
@@ -41,17 +40,19 @@ import org.apache.sis.util.resources.Err
  * initialized with default converters is provided by the {@link SystemRegistry#INSTANCE} constant.</p>
  *
  * {@section Note about conversions from interfaces}
- * {@code ConverterRegistry} is primarily designed for handling converters from classes to
- * other classes. Handling of interfaces are not prohibited (and actually sometime supported),
- * but their behavior may be more ambiguous than in the case of classes because of
- * multi-inheritance in interface hierarchy.
+ * {@code ConverterRegistry} is primarily designed for handling converters from classes to other classes.
+ * Handling of interfaces are not prohibited (and actually sometime supported), but their behavior may be
+ * more ambiguous than in the case of classes because of multi-inheritance in interface hierarchy.
+ *
+ * {@section Thread safety}
+ * This base class is thread-safe. Subclasses shall make sure that any overridden methods remain safe to call
+ * from multiple threads.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
  * @version 0.3
  * @module
  */
-@ThreadSafe
 public class ConverterRegistry {
     /**
      * The map of converters of any kind. For any key of type {@code ClassPair<S,T>},

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/DateConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -19,7 +19,6 @@ package org.apache.sis.internal.converte
 import java.util.Date;
 import java.util.Set;
 import java.util.EnumSet;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.math.FunctionProperty;
 
@@ -35,12 +34,14 @@ import org.apache.sis.math.FunctionPrope
  * The converter from dates to timestamps is not injective, because the same date could be mapped
  * to many timestamps since timestamps have an additional nanoseconds field.
  *
+ * {@section Immutability and thread safety}
+ * This base class and all inner classes are immutable, and thus inherently thread-safe.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)
  * @version 0.3
  * @module
  */
-@Immutable
 abstract class DateConverter<T> extends SystemConverter<Date,T> {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/FallbackConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -20,7 +20,6 @@ import java.util.Arrays;
 import java.util.Set;
 import java.util.EnumSet;
 import java.util.Iterator;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.math.FunctionProperty;
@@ -48,6 +47,10 @@ import org.apache.sis.util.Debug;
  * It is invoked when a new converter is {@linkplain ConverterRegistry#register(ObjectConverter)
  * registered} for the same source and target class than an existing converter.</p>
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable, and thus inherently thread-safe,
+ * if the converters given to the static factory method are also immutable.
+ *
  * @param <S> The base type of source objects.
  * @param <T> The base type of converted objects.
  *
@@ -56,7 +59,6 @@ import org.apache.sis.util.Debug;
  * @version 0.3
  * @module
  */
-@Immutable
 final class FallbackConverter<S,T> extends SystemConverter<S,T> {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/IdentityConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.internal.converte
 
 import java.util.Set;
 import java.util.EnumSet;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.math.FunctionProperty;
 
@@ -26,6 +25,9 @@ import org.apache.sis.math.FunctionPrope
 /**
  * An object converter which returns the source unchanged.
  *
+ * {@section Immutability and thread safety}
+ * This class is immutable and thus inherently thread-safe.
+ *
  * @param <S> The base type of source objects.
  * @param <T> The base type of converted objects.
  *
@@ -36,7 +38,6 @@ import org.apache.sis.math.FunctionPrope
  *
  * @see org.apache.sis.util.ObjectConverters#identity(Class)
  */
-@Immutable
 public final class IdentityConverter<T, S extends T> extends SystemConverter<S,T> {
     // JDK6 NOTE: Order of above <T> and <S> parameters is reversed compared to the
     // JDK7 branch, because the JDK6 compiler does not supports forward reference.
@@ -74,8 +75,9 @@ public final class IdentityConverter<T, 
      * This method returns a new {@link EnumSet} instead than returning a constant, because
      * creating {@code EnumSet} is cheap and the standard JDK implementation has optimizations
      * for bulk operations between {@code EnumSet} instances. Those optimizations are lost (at
-     * least on JDK6) is we wrap the {@code EnumSet} in a {@code Collections.unmodifiableSet}
-     * view.
+     * least on JDK6) is we wrap the {@code EnumSet} in a {@code Collections.unmodifiableSet} view.
+     *
+     * @return The manners in which source values are mapped to target values.
      */
     @Override
     public Set<FunctionProperty> properties() {
@@ -88,6 +90,8 @@ public final class IdentityConverter<T, 
 
     /**
      * Returns the inverse converter, if any.
+     *
+     * @return A converter for converting instances of <var>T</var> back to instances of <var>S</var>.
      */
     @Override
     public ObjectConverter<T,S> inverse() throws UnsupportedOperationException {
@@ -98,6 +102,7 @@ public final class IdentityConverter<T, 
      * Returns the given object unchanged.
      *
      * @param source The value to convert.
+     * @return The given value unchanged.
      */
     @Override
     public T apply(final S source) {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/NumberConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.internal.converte
 
 import java.util.Set;
 import java.util.EnumSet;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.math.FunctionProperty;
 import org.apache.sis.util.ObjectConverter;
@@ -41,6 +40,9 @@ import org.apache.sis.util.resources.Err
  * If nevertheless performance appears to be a problem, consider reverting to revision 1455255
  * of this class, which was using one subclass per target type as described above.
  *
+ * {@section Immutability and thread safety}
+ * This class and all inner classes are immutable, and thus inherently thread-safe.
+ *
  * @param <S> The source number type.
  * @param <T> The target number type.
  *
@@ -49,7 +51,6 @@ import org.apache.sis.util.resources.Err
  * @version 0.3
  * @module
  */
-@Immutable
 final class NumberConverter<S extends Number, T extends Number> extends SystemConverter<S,T> {
     /**
      * For cross-version compatibility.
@@ -122,7 +123,6 @@ final class NumberConverter<S extends Nu
      * Converter from numbers to comparables. This special case exists because {@link Number}
      * does not implement {@link java.lang.Comparable} directly, but all known subclasses do.
      */
-    @Immutable
     static final class Comparable<S extends Number> extends SystemConverter<S, java.lang.Comparable<?>> {
         /**
          * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/ObjectToString.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.internal.converte
 
 import java.util.Set;
 import java.util.EnumSet;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.math.FunctionProperty;
 
@@ -35,6 +34,9 @@ import org.apache.sis.math.FunctionPrope
  *     ObjectConverter<S,String> c = StringConverter.getInstance(sourceClass).inverse();
  * }
  *
+ * {@section Immutability and thread safety}
+ * This base class and all inner classes are immutable, and thus inherently thread-safe.
+ *
  * @param <S> The source type.
  *
  * @author  Martin Desruisseaux (Geomatys)
@@ -42,7 +44,6 @@ import org.apache.sis.math.FunctionPrope
  * @version 0.3
  * @module
  */
-@Immutable
 class ObjectToString<S> extends SystemConverter<S,String> {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/PathConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/PathConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/PathConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/PathConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -24,7 +24,6 @@ import java.net.URI;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import org.apache.sis.math.FunctionProperty;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
 
@@ -32,12 +31,14 @@ import org.apache.sis.util.Unconvertible
 /**
  * Handles conversions between {@link Path}, {@link File}, {@link URI} and {@link URL} objects.
  *
+ * {@section Immutability and thread safety}
+ * This base class and all inner classes are immutable, and thus inherently thread-safe.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.01)
  * @version 0.3
  * @module
  */
-@Immutable
 abstract class PathConverter<S,T> extends SystemConverter<S,T> {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/StringConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -24,7 +24,6 @@ import java.net.MalformedURLException;
 import org.apache.sis.math.FunctionProperty;
 import org.apache.sis.util.Locales;
 import org.apache.sis.util.Numbers;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
@@ -57,12 +56,14 @@ import org.apache.sis.util.iso.SimpleInt
  *    <tr><td>{@code "0"}     </td><td>{@link java.lang.Boolean#FALSE} </td></tr>
  * </table>
  *
+ * {@section Immutability and thread safety}
+ * This base class and all inner classes are immutable, and thus inherently thread-safe.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.4)
  * @version 0.3
  * @module
  */
-@Immutable
 abstract class StringConverter<T> extends SystemConverter<String, T> {
     /**
      * For cross-version compatibility.
@@ -147,7 +148,6 @@ abstract class StringConverter<T> extend
     /**
      * Converter from {@link String} to various kinds of {@link java.lang.Number}.
      */
-    @Immutable
     public static final class Number extends StringConverter<java.lang.Number> {
         private static final long serialVersionUID = 8356246549731207392L;
         public Number() {super(java.lang.Number.class);} // Instantiated by ServiceLoader.
@@ -319,7 +319,6 @@ abstract class StringConverter<T> extend
      * <p>Instances of this class are created by
      * {@link SystemRegistry#createConverter(Class, Class)}.</p>
      */
-    @Immutable
     static final class CodeList<T extends org.opengis.util.CodeList<T>> extends StringConverter<T> {
         /** For cross-version compatibility on serialization. */
         private static final long serialVersionUID = -6351669842222010105L;

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -26,8 +26,11 @@ import org.apache.sis.util.resources.Err
 
 /**
  * Base class of all converters defined in the {@code org.apache.sis.internal} package.
- * Those converters are returned by system-wide {@link ConverterRegitry}, and cached for
- * reuse.
+ * Those converters are returned by system-wide {@link ConverterRegitry}, and cached for reuse.
+ *
+ * {@section Immutability and thread safety}
+ * This base class is immutable, and thus inherently thread-safe. Subclasses should be immutable
+ * and thread-safe too if they are intended to be cached in {@link ConverterRegistry}.
  *
  * @param <S> The base type of source objects.
  * @param <T> The base type of converted objects.
@@ -111,6 +114,10 @@ abstract class SystemConverter<S,T> exte
      *       (as in {@link ConverterRegistry#find(Class, Class)}), the key shall be
      *       an instance of {@code ClassPair} instance (not a subclass).</li>
      * </ul>
+     *
+     * @param  other The object to compare with this {@code SystemConverter}.
+     * @return {@code true} if the given object is a {@code ClassPair} or a converter of the
+     *         same class than {@code this}, and both have the same source and target classes.
      */
     @Override
     public final boolean equals(final Object other) {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemRegistry.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -20,7 +20,6 @@ import java.util.Date;
 import java.util.ServiceLoader;
 import org.opengis.util.CodeList;
 import org.apache.sis.util.Numbers;
-import org.apache.sis.util.ThreadSafe;
 import org.apache.sis.util.ObjectConverter;
 import org.apache.sis.util.UnconvertibleObjectException;
 import org.apache.sis.internal.system.SystemListener;
@@ -46,12 +45,14 @@ import org.apache.sis.internal.system.Mo
  * of the above-cited heuristic rules. This differs from the {@link ConverterRegistry} behavior,
  * where only registered converters are used.
  *
+ * {@section Thread safety}
+ * The same {@link #INSTANCE} can be safely used by many threads without synchronization on the part of the caller.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.02)
  * @version 0.3
  * @module
  */
-@ThreadSafe
 public final class SystemRegistry extends ConverterRegistry {
     /**
      * The default system-wide instance. This register is initialized with conversions between

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCharacterIterator.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCharacterIterator.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCharacterIterator.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCharacterIterator.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.internal.simple;
 
 import java.io.Serializable;
 import java.text.CharacterIterator;
-import org.apache.sis.util.Decorator;
 import org.apache.sis.util.ArgumentChecks;
 
 
@@ -31,7 +30,6 @@ import org.apache.sis.util.ArgumentCheck
  * @version 0.3
  * @module
  */
-@Decorator(CharSequence.class)
 public class SimpleCharacterIterator implements CharacterIterator, CharSequence, Serializable {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -17,8 +17,8 @@
 package org.apache.sis.internal.simple;
 
 import java.io.Serializable;
-import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.util.InternationalString;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.metadata.citation.Citation;
 import org.apache.sis.internal.util.Citations;
 import org.apache.sis.util.CharSequences;
@@ -34,12 +34,12 @@ import org.apache.sis.internal.jdk7.Obje
 /**
  * An implementation of {@link ReferenceIdentifier} as a wrapper around a {@link Citation}.
  * {@code ReferenceIdentifier} is defined by the ISO 19111 standard and is implemented publicly
- * in the {@link org.apache.sis.referencing} package. This class is provided for non-referencing
- * code that need a lightweight version.
+ * in the {@link org.apache.sis.referencing} package. This class is provided for codes that do
+ * not depend on the {@code sis-referencing} module but still need a lightweight implementation.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.4
  * @module
  */
 public class SimpleReferenceIdentifier implements ReferenceIdentifier, Serializable {

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -22,7 +22,9 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import org.apache.sis.internal.jaxb.Context;
+import org.apache.sis.util.Classes;
 import org.apache.sis.util.ArraysExt;
+import org.apache.sis.util.NullArgumentException;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.collection.CheckedContainer;
 
@@ -93,21 +95,48 @@ public final class CheckedArrayList<E> e
     }
 
     /**
-     * Returns {@code true} if a unmarshalling process is under way.
-     * In the later case, logs a warning for non-null element of the wrong type.
+     * Invoked when an illegal element has been given to the {@code add(E)} method.
+     * The element may be illegal either because null or because of invalid type.
+     * This method will perform only one of the following actions:
+     *
+     * <ul>
+     *   <li>If a unmarshalling process is under way, then this method logs a warning and returns {@code null}.
+     *       The {@code add(E)} caller method shall return {@code false} without throwing exception. This is a
+     *       violation of {@link Collection#add(Object)} contract, but is required for unmarshalling of empty
+     *       XML elements (see SIS-139 and SIS-157).</li>
+     *   <li>If no unmarshalling process is under way, then this method returns a {@code String} containing the
+     *       error message to give to the exception to be thrown. The {@code add(E)} caller method is responsible
+     *       to thrown an exception with that message. We let the caller throw the exception for reducing the
+     *       stack trace depth, so the first element on the stack trace is the public {@code add(E)} method.</li>
+     * </ul>
+     *
+     * @param  collection   The collection in which the user attempted to add an invalid element.
+     * @param  element      The element that the user attempted to add (may be {@code null}).
+     * @param  expectedType The type of elements that the collection expected.
+     * @return The message to give to the exception to be thrown, or {@code null} if no message shall be thrown.
      *
      * @see <a href="https://issues.apache.org/jira/browse/SIS-139">SIS-139</a>
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-157">SIS-157</a>
      */
-    static boolean warning(final Collection<?> source, final Object element, final Class<?> type) {
-        final Context context = Context.current();
-        if (context == null) {
-            return false;
+    public static String illegalElement(final Collection<?> collection, final Object element, final Class<?> expectedType) {
+        final short key;
+        final Object[] arguments;
+        if (element == null) {
+            key = Errors.Keys.NullCollectionElement_1;
+            arguments = new Object[] {
+                Classes.getShortClassName(collection) + '<' + Classes.getShortName(expectedType) + '>'
+            };
+        } else {
+            key = Errors.Keys.IllegalArgumentClass_3;
+            arguments = new Object[] {"element", expectedType, element.getClass()};
         }
-        if (element != null) {
-            Context.warningOccured(context, source.getClass(), "add",
-                    Errors.class, Errors.Keys.IllegalArgumentClass_3, "element", type, element.getClass());
+        final Context context = Context.current();
+        if (context != null) {
+            Context.warningOccured(context, collection.getClass(), "add", Errors.class, key, arguments);
+            return null;
+        } else {
+            return Errors.format(key, arguments);
         }
-        return true;
     }
 
     /**
@@ -122,7 +151,8 @@ public final class CheckedArrayList<E> e
         if (type.isInstance(element)) {
             return true;
         }
-        if (warning(this, element, type)) {
+        final String message = illegalElement(this, element, type);
+        if (message == null) {
             /*
              * If a unmarshalling process is under way, silently discard null element.
              * This case happen when a XML element for a collection contains no child.
@@ -130,9 +160,11 @@ public final class CheckedArrayList<E> e
              */
             return false;
         }
-        ensureNonNull("element", element);
-        throw new IllegalArgumentException(Errors.format(
-                Errors.Keys.IllegalArgumentClass_3, "element", type, element.getClass()));
+        if (element == null) {
+            throw new NullArgumentException(message);
+        } else {
+            throw new IllegalArgumentException(message);
+        }
     }
 
     /**

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedHashSet.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedHashSet.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedHashSet.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedHashSet.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -19,7 +19,7 @@ package org.apache.sis.internal.util;
 import java.util.Set;
 import java.util.Collections;
 import java.util.LinkedHashSet;
-import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.NullArgumentException;
 import org.apache.sis.util.collection.CheckedContainer;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -97,20 +97,23 @@ public final class CheckedHashSet<E> ext
      */
     @Override
     public boolean add(final E element) throws IllegalArgumentException {
-        if (!type.isInstance(element)) {
-            if (CheckedArrayList.warning(this, element, type)) {
-                /*
-                 * If a unmarshalling process is under way, silently discard null element.
-                 * This case happen when a XML element for a collection contains no child.
-                 * See https://issues.apache.org/jira/browse/SIS-139
-                 */
-                return false;
-            }
-            ensureNonNull("element", element);
-            throw new IllegalArgumentException(Errors.format(
-                    Errors.Keys.IllegalArgumentClass_3, "element", type, element.getClass()));
+        if (type.isInstance(element)) {
+            return super.add(element);
+        }
+        final String message = CheckedArrayList.illegalElement(this, element, type);
+        if (message == null) {
+            /*
+             * If a unmarshalling process is under way, silently discard null element.
+             * This case happen when a XML element for a collection contains no child.
+             * See https://issues.apache.org/jira/browse/SIS-139
+             */
+            return false;
+        }
+        if (element == null) {
+            throw new NullArgumentException(message);
+        } else {
+            throw new IllegalArgumentException(message);
         }
-        return super.add(element);
     }
 
     /*

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -40,6 +40,53 @@ public final class Utilities extends Sta
     }
 
     /**
+     * Appends to the given buffer only the characters that are valid for a Unicode identifier.
+     * The given separator character is append before the given {@code text} only if the buffer
+     * is not empty and at least one {@code text} character is valid.
+     *
+     * {@section Relationship with <code>gml:id</code>}
+     * This method may be invoked for building {@code gml:id} values. Strictly speaking this is not appropriate
+     * since the {@code xsd:ID} type defines valid identifiers as containing only letters, digits, underscores,
+     * hyphens, and periods. This differ from Unicode identifier in two ways:
+     *
+     * <ul>
+     *   <li>Unicode identifiers accept Japanese or Chinese ideograms for instance, which are considered as letters.</li>
+     *   <li>Unicode identifiers do not accept the {@code '-'} and {@code ':'} characters. However this restriction
+     *       fits well our need, since those characters are typical values for the {@code separator} argument.</li>
+     *   <li>Note that {@code '_'} is valid both in {@code xsd:ID} and Unicode identifier.</li>
+     * </ul>
+     *
+     * @param  appendTo    The buffer where to append the valid characters.
+     * @param  separator   The separator to append before the valid characters, or 0 if none.
+     * @param  text        The text from which to get the valid character to append in the given buffer.
+     * @param  accepted    Additional characters to accept (e.g. {@code "-."}), or an empty string if none.
+     * @param  toLowerCase {@code true} for converting the characters to lower case.
+     * @return {@code true} if at least one character has been added to the buffer.
+     */
+    public static boolean appendUnicodeIdentifier(final StringBuilder appendTo, final char separator,
+            final String text, final String accepted, final boolean toLowerCase)
+    {
+        boolean added = false;
+        if (text != null) {
+            for (int i=0; i<text.length();) {
+                final int c = text.codePointAt(i);
+                final boolean isFirst = appendTo.length() == 0;
+                if ((isFirst ? Character.isUnicodeIdentifierStart(c)
+                             : Character.isUnicodeIdentifierPart(c)) || accepted.indexOf(c) >= 0)
+                {
+                    if (!isFirst && !added && separator != 0) {
+                        appendTo.append(separator);
+                    }
+                    appendTo.appendCodePoint(toLowerCase ? Character.toLowerCase(c) : c);
+                    added = true;
+                }
+                i += Character.charCount(c);
+            }
+        }
+        return added;
+    }
+
+    /**
      * Returns a string representation of an instance of the given class having the given properties.
      * This is a convenience method for implementation of {@link Object#toString()} methods that are
      * used mostly for debugging purpose.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/Appender.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/Appender.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/Appender.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/Appender.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.io;
 
 import java.io.IOException;
 import java.io.CharConversionException;
-import org.apache.sis.util.Decorator;
 import org.apache.sis.util.ArgumentChecks;
 
 import static org.apache.sis.util.Characters.isLineOrParagraphSeparator;
@@ -55,7 +54,6 @@ import org.apache.sis.internal.jdk7.JDK7
  *
  * @see java.io.FilterWriter
  */
-@Decorator(Appendable.class)
 abstract class Appender implements Appendable {
     /**
      * The underlying character output stream or buffer.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -20,19 +20,21 @@ import java.text.Format;
 import java.text.FieldPosition;
 import java.text.ParsePosition;
 import java.io.InvalidObjectException;
-import org.apache.sis.util.ThreadSafe;
 import org.apache.sis.util.Classes;
 
 
 /**
  * Used by {@link CompoundFormat} for formatting the names of object of type {@link Class}.
  *
+ * {@section Thread safety}
+ * The same {@link #INSTANCE} can be safely used by many threads without synchronization on the part of the caller.
+ * Note that this is specific to {@code ClassFormat} and generally not true for arbitrary {@code Format} classes.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
  * @version 0.3
  * @module
  */
-@ThreadSafe
 final class ClassFormat extends Format {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -22,7 +22,6 @@ import java.text.ParsePosition;
 import java.text.ParseException;
 import java.io.InvalidObjectException;
 import org.apache.sis.util.Numbers;
-import org.apache.sis.util.ThreadSafe;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.internal.util.LocalizedParseException;
 
@@ -33,12 +32,16 @@ import org.apache.sis.internal.util.Loca
  * than the {@link java.text} package because the former provide the best guarantees
  * to format all significant digits.
  *
+ * {@section Thread safety}
+ * The same {@linkplain #getInstance instance} can be safely used by many threads without synchronization
+ * on the part of the caller. Note that this is specific to {@code DefaultFormat} and generally not true
+ * for arbitrary {@code Format} classes.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
  * @version 0.3
  * @module
  */
-@ThreadSafe
 final class DefaultFormat extends Format {
     /**
      * For cross-version compatibility.

Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java?rev=1553457&r1=1553456&r2=1553457&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/LineAppender.java [UTF-8] Thu Dec 26 06:03:57 2013
@@ -18,7 +18,6 @@ package org.apache.sis.io;
 
 import java.io.Flushable;
 import java.io.IOException;
-import org.apache.sis.util.Decorator;
 import org.apache.sis.util.Characters;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArgumentChecks;
@@ -62,7 +61,6 @@ import org.apache.sis.internal.jdk7.JDK7
  * @version 0.4
  * @module
  */
-@Decorator(Appendable.class)
 public class LineAppender extends Appender implements Flushable {
     /**
      * The line separator, or {@code null} if not yet determined. If {@code null}, then the



Mime
View raw message