sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1569932 [1/5] - in /sis/trunk: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/io/ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-metadata/src/main/java...
Date Wed, 19 Feb 2014 21:41:02 GMT
Author: desruisseaux
Date: Wed Feb 19 21:40:59 2014
New Revision: 1569932

URL: http://svn.apache.org/r1569932
Log:
Merge from the JDK6 branch. Main topic is: migration from WKT 1 to WKT 2 formatting.

Added:
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingUtilities.java
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingUtilities.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/io/
      - copied from r1569927, sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/ReferencingUtilitiesTest.java
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/ReferencingUtilitiesTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/io/
      - copied from r1569927, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/io/
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/mock/
      - copied from r1569927, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/mock/
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/package-info.txt
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/package-info.txt
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/
      - copied from r1569927, sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/parameter/
      - copied from r1569927, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeocentricCRSTest.java
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeocentricCRSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultVerticalCRSTest.java
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultVerticalCRSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultSphericalCSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/mock/
      - copied from r1569927, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/mock/
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/package-info.txt
      - copied unchanged from r1569927, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/package-info.txt
Removed:
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ReferencingUtilitiesTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/io/
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/Assert.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/mock/GeodeticDatumMock.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/mock/PrimeMeridianMock.java
Modified:
    sis/trunk/   (props changed)
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyInformationTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultBrowseGraphicTest.java
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/Properties.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultEngineeringCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultImageCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultTemporalCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultVerticalCRS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/package-info.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/CoordinateSystems.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultAffineCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCartesianCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCylindricalCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultLinearCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultPolarCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultSphericalCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultUserDefinedCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultVerticalCS.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DirectionAlongMeridian.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/Normalizer.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/package-info.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/TimeDependentBWP.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/geometry/AbstractEnvelopeTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/geometry/Envelope2DTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/geometry/GeneralEnvelopeTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/geometry/ImmutableEnvelopeTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/AxisDirectionsTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/IdentifiedObjectsTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/NamedIdentifierTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/AbstractCRSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeodeticCRSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultGeographicCRSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRS.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/SubTypesTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/AbstractCSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CoordinateSystemsTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCompoundCSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DirectionAlongMeridianTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedAxes.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedCS.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/HardCodedCSTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/NormalizerTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/TimeDependentBWPTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2DTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/Column.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/converter/SystemConverter.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleReferenceIdentifier.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/ClassFormat.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/DefaultFormat.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/setup/OptionKey.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/Containers.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/RangeSet.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractInternationalString.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/GlobalNameSpace.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/xml/NilInternationalString.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/converter/ConverterRegistryTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/simple/SimpleReferenceIdentifierTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/test/AssertTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/io/AppenderTestCase.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/io/TableAppenderTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsFormatTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/SexagesimalConverterTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/TestStep.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/logging/MonolineFormatterTest.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/xml/ValueConverterTest.java
    sis/trunk/pom.xml
    sis/trunk/src/main/javadoc/stylesheet.css
    sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/AttributeNames.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreRegistry.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStores.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/ProbeResult.java
    sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java

Propchange: sis/trunk/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK7:r1562999-1569916
  Merged /sis/branches/JDK6:r1563002-1569927

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -96,6 +96,32 @@ public final class MetadataUtilities ext
     }
 
     /**
+     * Ensures that the given argument value is {@code false}. This method is invoked by private setter methods,
+     * which are themselves invoked by JAXB at unmarshalling time. Invoking this method from those setter methods
+     * serves two purposes:
+     *
+     * <ul>
+     *   <li>Make sure that a singleton property is not defined twice in the XML document.</li>
+     *   <li>Protect ourselves against changes in immutable objects outside unmarshalling. It should
+     *       not be necessary since the setter methods shall not be public, but we are paranoiac.</li>
+     *   <li>Be a central point where we can trace all setter methods, in case we want to improve
+     *       warning or error messages in future SIS versions.</li>
+     * </ul>
+     *
+     * @param  name The property name, used only in case of error message to format.
+     * @param  isDefined Whether the property in the caller object is current defined.
+     * @return {@code true} if the caller can set the property.
+     * @throws IllegalStateException If {@code isDefined} is {@code true}.
+     */
+    public static boolean canSetProperty(final String name, final boolean isDefined) throws IllegalStateException {
+        if (isDefined) {
+            // Future SIS version could log a warning instead if a unmarshalling is in progress.
+            throw new IllegalStateException(Errors.format(Errors.Keys.ElementAlreadyPresent_1, name));
+        }
+        return true;
+    }
+
+    /**
      * Convenience method for logging a warning to the {@code ISOMetadata} logger.
      * The message will be produced using the {@link Messages} resources bundle.
      *

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -17,6 +17,9 @@
 package org.apache.sis.internal.metadata;
 
 import org.opengis.geometry.Envelope;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.metadata.iso.extent.DefaultExtent;
 import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent;
@@ -34,7 +37,7 @@ import org.apache.sis.util.resources.Err
  * implementation using Java reflection.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @since   0.3 (derived from geotk-3.18)
+ * @since   0.4 (derived from geotk-3.18)
  * @version 0.3
  * @module
  */
@@ -52,7 +55,7 @@ public abstract class ReferencingService
     /**
      * The services, fetched when first needed.
      */
-    private static ReferencingServices instance;
+    private static volatile ReferencingServices instance;
 
     /**
      * For subclass only. This constructor registers this instance as a {@link SystemListener}
@@ -73,7 +76,6 @@ public abstract class ReferencingService
         synchronized (ReferencingServices.class) {
             instance = null;
         }
-        SystemListener.remove(this);
     }
 
     /**
@@ -83,20 +85,50 @@ public abstract class ReferencingService
      * @throws UnsupportedOperationException If the {@code "sis-referencing"} module has not
      *         been found on the classpath.
      */
-    public static synchronized ReferencingServices getInstance() throws UnsupportedOperationException {
-        if (instance == null) try {
-            instance = (ReferencingServices) Class.forName("org.apache.sis.internal.referencing.ServicesForMetadata").newInstance();
-        } catch (ClassNotFoundException exception) {
-            throw new UnsupportedOperationException(Errors.format(
-                    Errors.Keys.MissingRequiredModule_1, "sis-referencing"), exception);
-        } catch (Exception exception) { // (ReflectiveOperationException) on JDK7 branch.
-            // Should never happen if we didn't broke our helper class.
-            throw new AssertionError(exception);
+    public static ReferencingServices getInstance() throws UnsupportedOperationException {
+        ReferencingServices c = instance;
+        if (c == null) {
+            synchronized (ReferencingServices.class) {
+                c = instance;
+                if (c == null) try {
+                    instance = c = (ReferencingServices) Class.forName("org.apache.sis.internal.referencing.ServicesForMetadata").newInstance();
+                } catch (ClassNotFoundException exception) {
+                    throw new UnsupportedOperationException(Errors.format(
+                            Errors.Keys.MissingRequiredModule_1, "sis-referencing"), exception);
+                } catch (Exception exception) { // (ReflectiveOperationException) on JDK7 branch.
+                    // Should never happen if we didn't broke our helper class.
+                    throw new AssertionError(exception);
+                }
+            }
         }
-        return instance;
+        return c;
     }
 
     /**
+     * Returns the matrix for the given transform, or {@code null} if none.
+     *
+     * @param  tr The transform for which to get the matrix.
+     * @return The matrix, or {@code null} if none.
+     *
+     * @see org.apache.sis.referencing.operation.transform.LinearTransform#getMatrix()
+     *
+     * @since 0.4
+     */
+    public abstract Matrix getMatrix(MathTransform tr);
+
+    /**
+     * Converts the given object in a {@link org.apache.sis.io.wkt.FormattableObject} instance.
+     *
+     * @param  object The object to wrap.
+     * @return The given object converted to a {@code FormattableObject} instance.
+     *
+     * @see org.apache.sis.referencing.AbstractIdentifiedObject#castOrCopy(IdentifiedObject)
+     *
+     * @since 0.4
+     */
+    public abstract IdentifiedObject toFormattableObject(IdentifiedObject object);
+
+    /**
      * Sets a geographic bounding box from the specified envelope. If the envelope contains
      * a CRS, then the bounding box will be projected to a geographic CRS. Otherwise, the envelope
      * is assumed already in appropriate CRS.

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -18,7 +18,6 @@ package org.apache.sis.metadata;
 
 import java.util.Map;
 import java.util.IdentityHashMap;
-import java.io.ObjectStreamException;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.logging.Logging;
 
@@ -161,7 +160,7 @@ final class StandardImplementation exten
     /**
      * Invoked on deserialization. Returns one of the pre-existing constants if possible.
      */
-    Object readResolve() throws ObjectStreamException {
+    Object readResolve() {
         if (ISO_19111.citation.equals(citation)) return ISO_19111;
         if (ISO_19115.citation.equals(citation)) return ISO_19115;
         /*

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -21,17 +21,20 @@ import java.util.Locale;
 import java.io.Serializable;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
-import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.parameter.InvalidParameterValueException;
 import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.util.InternationalString;
-import org.apache.sis.util.Debug;
 import org.apache.sis.util.Deprecable;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.internal.simple.SimpleIdentifiedObject;
+import org.apache.sis.internal.metadata.ReferencingUtilities;
+import org.apache.sis.internal.util.DefinitionURI;
+import org.apache.sis.io.wkt.FormattableObject;
+import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.io.wkt.Convention;
+import org.apache.sis.io.wkt.ElementKind;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.util.CharSequences.trimWhitespaces;
@@ -73,9 +76,10 @@ import org.apache.sis.internal.jdk7.Obje
  * }
  *
  * </li><li><p><b><cite>Well Known Text</cite> (WKT) version 2</b></p>
- * The WKT 2 format contains the {@linkplain #getCodeSpace() code space}, the {@linkplain #getCode() code} and
- * the {@linkplain #getVersion() version} if available. The WKT can optionally provides a {@code URI} element,
- * which expresses the same information in a different way (the URN syntax is described in the next item below).
+ * The WKT 2 format contains the {@linkplain #getCodeSpace() code space}, the {@linkplain #getCode() code},
+ * the {@linkplain #getVersion() version} and the {@linkplain #getAuthority() authority} citation if available.
+ * The WKT can optionally provides a {@code URI} element, which expresses the same information in a different way
+ * (the URN syntax is described in the next item below).
  * Example:
  *
  * {@preformat wkt
@@ -125,7 +129,7 @@ import org.apache.sis.internal.jdk7.Obje
  * @see DefaultIdentifier
  */
 @XmlRootElement(name = "RS_Identifier")
-public class ImmutableIdentifier implements ReferenceIdentifier, Deprecable, Serializable {
+public class ImmutableIdentifier extends FormattableObject implements ReferenceIdentifier, Deprecable, Serializable {
     /**
      * For cross-version compatibility.
      */
@@ -205,7 +209,7 @@ public class ImmutableIdentifier impleme
         } else {
             remarks = null;
         }
-        validate();
+        validate(null);
     }
 
     /**
@@ -252,7 +256,7 @@ public class ImmutableIdentifier impleme
         this.authority = authority;
         this.version   = version;
         this.remarks   = remarks;
-        validate();
+        validate(null);
     }
 
     /**
@@ -292,13 +296,23 @@ public class ImmutableIdentifier impleme
      *     <td>{@link String} or {@link InternationalString}</td>
      *     <td>{@link #getRemarks()}</td>
      *   </tr>
+     *   <tr>
+     *     <td>{@value org.apache.sis.referencing.AbstractIdentifiedObject#LOCALE_KEY}</td>
+     *     <td>{@link Locale}</td>
+     *     <td>(none)</td>
+     *   </tr>
      * </table>
      *
+     * {@section Localization}
      * {@code "remarks"} is a localizable attributes which may have a language and country
      * code suffix. For example the {@code "remarks_fr"} property stands for remarks in
      * {@linkplain Locale#FRENCH French} and the {@code "remarks_fr_CA"} property stands
      * for remarks in {@linkplain Locale#CANADA_FRENCH French Canadian}.
      *
+     * <p>The {@code "locale"} property applies only to exception messages, if any.
+     * After successful construction, {@code ImmutableIdentifier} instances do not keep the locale
+     * since localizations are deferred to the {@link InternationalString#toString(Locale)} method.</p>
+     *
      * @param  properties The properties to be given to this identifier.
      * @throws InvalidParameterValueException if a property has an invalid value.
      * @throws IllegalArgumentException if a property is invalid for some other reason.
@@ -317,7 +331,7 @@ public class ImmutableIdentifier impleme
         } else if (value == null || value instanceof Citation) {
             authority = (Citation) value;
         } else {
-            throw illegalPropertyType(AUTHORITY_KEY, value);
+            throw illegalPropertyType(properties, AUTHORITY_KEY, value);
         }
         /*
          * Complete the code space if it was not explicitly set. We take a short identifier (preferred) or title
@@ -331,27 +345,30 @@ public class ImmutableIdentifier impleme
         } else if (value instanceof String) {
             codeSpace = trimWhitespaces((String) value);
         } else {
-            throw illegalPropertyType(CODESPACE_KEY, value);
+            throw illegalPropertyType(properties, CODESPACE_KEY, value);
         }
-        validate();
+        validate(properties);
     }
 
     /**
      * Ensures that the properties of this {@code ImmutableIdentifier} are valid.
      */
-    private void validate() {
+    private void validate(final Map<String,?> properties) {
         if (code == null || code.isEmpty()) {
-            throw new IllegalArgumentException(Errors.format((code == null)
-                    ? Errors.Keys.MissingValueForProperty_1
-                    : Errors.Keys.EmptyProperty_1, CODE_KEY));
+            throw new IllegalArgumentException(Errors.getResources(properties)
+                    .getString((code == null) ? Errors.Keys.MissingValueForProperty_1
+                                              : Errors.Keys.EmptyProperty_1, CODE_KEY));
         }
     }
 
     /**
      * Returns the exception to be thrown when a property if of illegal type.
      */
-    private static IllegalArgumentException illegalPropertyType(final String key, final Object value) {
-        return new IllegalArgumentException(Errors.format(Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
+    private static IllegalArgumentException illegalPropertyType(
+            final Map<String,?> properties, final String key, final Object value)
+    {
+        return new IllegalArgumentException(Errors.getResources(properties)
+                .getString(Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
     }
 
     /**
@@ -524,19 +541,125 @@ public class ImmutableIdentifier impleme
     }
 
     /**
-     * Returns a string representation of this identifier.
-     * The string representation is mostly for debugging purpose and may change in any future SIS version.
-     * The default implementation returns a pseudo-WKT format.
-     *
-     * {@note The <code>NamedIdentifier</code> subclass overrides this method with a different behavior,
-     *        in order to be compliant with the contract of the <code>GenericName</code> interface.}
+     * Formats this identifier as a <cite>Well Known Text</cite> {@code Id[…]} element.
+     * See class javadoc for more information on the WKT format.
      *
-     * @see org.apache.sis.referencing.IdentifiedObjects#toString(Identifier)
-     * @see org.apache.sis.referencing.NamedIdentifier#toString()
+     * @param  formatter The formatter where to format the inner content of this WKT element.
+     * @return {@code "Id"} (WKT 2) or {@code "Authority"} (WKT 1).
      */
-    @Debug
     @Override
-    public String toString() {
-        return SimpleIdentifiedObject.toString("IDENTIFIER", authority, codeSpace, code, isDeprecated());
+    protected String formatTo(final Formatter formatter) {
+        String keyword = null;
+        if (code != null) {
+            String citation = Citations.getIdentifier(authority);
+            String cs = codeSpace;
+            if (cs == null) {
+                cs = citation;
+                citation  = null;
+            }
+            if (cs != null) {
+                final Convention convention = formatter.getConvention();
+                if (convention.majorVersion() == 1) {
+                    keyword = "Authority";
+                    formatter.append(cs, null);
+                    formatter.append(code, null);
+                } else {
+                    keyword = "Id";
+                    formatter.append(cs, null);
+                    appendCode(formatter, code);
+                    if (version != null) {
+                        appendCode(formatter, version);
+                    }
+                    if (citation != null && !citation.equals(cs)) {
+                        formatter.append(new Cite(citation));
+                    }
+                    /*
+                     * Do not format the optional URI element for internal convention,
+                     * because this property is currently computed rather than stored.
+                     * Other conventions format only for the ID[…] of root element.
+                     */
+                    if (convention != Convention.INTERNAL && formatter.getEnclosingElement(2) == null) {
+                        final FormattableObject parent = formatter.getEnclosingElement(1);
+                        if (parent != null && ReferencingUtilities.usesURN(cs)) {
+                            final String type = ReferencingUtilities.toURNType(parent.getClass());
+                            if (type != null) {
+                                formatter.append(new URI(type, cs, version, code));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return keyword;
+    }
+
+    /**
+     * Appends the given code or version number as an integer if possible, or as a text otherwise.
+     *
+     * {@note ISO 19162 specifies "number or text". In Apache SIS, we restrict the numbers to integers
+     *        because handling version numbers like "8.2" as floating point numbers can be confusing.}
+     */
+    private static void appendCode(final Formatter formatter, final String text) {
+        if (text != null) {
+            final long n;
+            try {
+                n = Long.parseLong(text);
+            } catch (NumberFormatException e) {
+                formatter.append(text, null);
+                return;
+            }
+            formatter.append(n);
+        }
+    }
+
+    /**
+     * The {@code CITATION[…]} element inside an {@code ID[…]}.
+     */
+    private static final class Cite extends FormattableObject {
+        /** The component of the citation to format. */
+        private final String identifier;
+
+        /** Creates a new citation with the given component. */
+        Cite(final String identifier) {
+            this.identifier = identifier;
+        }
+
+        /** Formats the citation. */
+        @Override
+        protected String formatTo(final Formatter formatter) {
+            formatter.append(identifier, ElementKind.CITATION);
+            return "Citation";
+        }
+    }
+
+    /**
+     * The {@code URI[…]} element inside an {@code ID[…]}.
+     */
+    private static final class URI extends FormattableObject {
+        /** The components of the URI to format. */
+        private final String type, codeSpace, version, code;
+
+        /** Creates a new URI with the given components. */
+        URI(final String type, final String codeSpace, final String version, final String code) {
+            this.type      = type;
+            this.codeSpace = codeSpace;
+            this.version   = version;
+            this.code      = code;
+        }
+
+        /** Formats the URI. */
+        @Override
+        protected String formatTo(final Formatter formatter) {
+            final StringBuilder buffer = new StringBuilder(DefinitionURI.PREFIX)
+                    .append(DefinitionURI.SEPARATOR).append(type)
+                    .append(DefinitionURI.SEPARATOR).append(codeSpace)
+                    .append(DefinitionURI.SEPARATOR);
+            if (version != null) {
+                buffer.append(version);
+            }
+            buffer.append(DefinitionURI.SEPARATOR).append(code);
+            formatter.append(buffer.toString(), null);
+            return "URI";
+        }
     }
 }

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -52,7 +52,6 @@ public final class Citations extends Sta
      * The <a href="http://www.opengeospatial.org">Open Geospatial Consortium</a> organization.
      * "Open Geospatial Consortium" is the new name for "OpenGIS consortium".
      *
-     * @see org.apache.sis.io.wkt.Convention#OGC
      * @category Organization
      */
     public static final Citation OGC = new SimpleCitation("OGC");
@@ -79,7 +78,6 @@ public final class Citations extends Sta
      * The <a href="http://www.esri.com">ESRI</a> organization.
      * This company defines many Coordinate Reference Systems in addition to the {@linkplain #EPSG} ones.
      *
-     * @see org.apache.sis.io.wkt.Convention#ESRI
      * @category Organization
      *
      * @since 0.4
@@ -89,7 +87,6 @@ public final class Citations extends Sta
     /**
      * The <a href="http://www.oracle.com">Oracle</a> organization.
      *
-     * @see org.apache.sis.io.wkt.Convention#ORACLE
      * @category Organization
      *
      * @since 0.4
@@ -99,7 +96,6 @@ public final class Citations extends Sta
     /**
      * The <a href="http://www.unidata.ucar.edu/software/netcdf-java">NetCDF</a> specification.
      *
-     * @see org.apache.sis.io.wkt.Convention#NETCDF
      * @category Specification
      *
      * @since 0.4
@@ -109,7 +105,6 @@ public final class Citations extends Sta
     /**
      * The <a href="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</a> specification.
      *
-     * @see org.apache.sis.io.wkt.Convention#GEOTIFF
      * @category Specification
      *
      * @since 0.4
@@ -119,7 +114,6 @@ public final class Citations extends Sta
     /**
      * The <a href="http://trac.osgeo.org/proj/">Proj.4</a> project.
      *
-     * @see org.apache.sis.io.wkt.Convention#PROJ4
      * @category Code space
      *
      * @since 0.4
@@ -136,7 +130,6 @@ public final class Citations extends Sta
      * @see #AUTO
      * @see #AUTO2
      * @see #CRS
-     * @see org.apache.sis.io.wkt.Convention#EPSG
      * @category Code space
      *
      * @since 0.4

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -17,13 +17,20 @@
 package org.apache.sis.metadata.iso.extent;
 
 import java.util.Date;
+import javax.measure.unit.Unit;
 import org.opengis.temporal.TemporalPrimitive;
 import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.extent.VerticalExtent;
 import org.opengis.metadata.extent.TemporalExtent;
 import org.opengis.metadata.extent.BoundingPolygon;
 import org.opengis.metadata.extent.GeographicExtent;
 import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.crs.VerticalCRS;
 import org.apache.sis.measure.Longitude;
+import org.apache.sis.measure.MeasurementRange;
+import org.apache.sis.measure.Range;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Static;
@@ -38,7 +45,8 @@ import static org.apache.sis.internal.me
  * This class provides methods for:
  *
  * <ul>
- *   <li>{@link #getGeographicBoundingBox(Extent)} and {@link #getDate(Extent, double)}
+ *   <li>{@link #getGeographicBoundingBox(Extent)}, {@link #getVerticalRange(Extent)}
+ *       and {@link #getDate(Extent, double)}
  *       for fetching geographic or temporal components in a convenient form.</li>
  *   <li>Methods for computing {@linkplain #intersection intersection} of bounding boxes
  *       and {@linkplain #area area} estimations.</li>
@@ -80,8 +88,7 @@ public final class Extents extends Stati
      * {@linkplain DefaultGeographicBoundingBox#add added} together.
      *
      * @param  extent The extent to convert to a geographic bounding box, or {@code null}.
-     * @return A geographic bounding box extracted from the given extent, or {@code null}
-     *         if the given extent was {@code null}.
+     * @return A geographic bounding box extracted from the given extent, or {@code null} in none.
      */
     public static GeographicBoundingBox getGeographicBoundingBox(final Extent extent) {
         GeographicBoundingBox candidate = null;
@@ -125,6 +132,115 @@ public final class Extents extends Stati
     }
 
     /**
+     * Returns the union of all vertical ranges found in the given extent, or {@code null} if none.
+     * Depths have negative height values: if the {@linkplain CoordinateSystemAxis#getDirection() axis direction}
+     * is toward down, then this method reverses the sign of minimum and maximum values.
+     *
+     * {@section Multi-occurrences}
+     * If the given {@code Extent} object contains more than one vertical extent, then this method
+     * performs the following choices:
+     *
+     * <ul>
+     *   <li>If no range specify a unit of measurement, return the first range and ignore all others.</li>
+     *   <li>Otherwise take the first range having a unit of measurement. Then:<ul>
+     *     <li>All other ranges having an incompatible unit of measurement will be ignored.</li>
+     *     <li>All other ranges having a compatible unit of measurement will be converted to
+     *         the unit of the first retained range, and their union will be computed.</li>
+     *   </ul></li>
+     * </ul>
+     *
+     * {@example Heights or depths are often measured using some pressure units, for example hectopascals (hPa).
+     *           An <code>Extent</code> could contain two vertical elements: one with the height measurements
+     *           in hPa, and the other element with heights transformed to metres using an empirical formula.
+     *           In such case this method will select the first vertical element on the assumption that it is
+     *           the "main" one that the metadata producer intended to show. Then this method will search for
+     *           other vertical elements using pressure unit. In our example there is none. But if any were
+     *           found, this method would compute their union.}
+     *
+     * @param  extent The extent to convert to a vertical measurement range, or {@code null}.
+     * @return A vertical measurement range created from the given extent, or {@code null} if none.
+     *
+     * @since 0.4
+     */
+    public static MeasurementRange<Double> getVerticalRange(final Extent extent) {
+        MeasurementRange<Double> range = null;
+        if (extent != null) {
+            for (final VerticalExtent element : extent.getVerticalElements()) {
+                double min = element.getMinimumValue();
+                double max = element.getMaximumValue();
+                final VerticalCRS crs = element.getVerticalCRS();
+                Unit<?> unit = null;
+                if (crs != null) {
+                    final CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis(0);
+                    unit = axis.getUnit();
+                    if (AxisDirection.DOWN.equals(axis.getDirection())) {
+                        final double tmp = min;
+                        min = -max;
+                        max = -tmp;
+                    }
+                }
+                if (range != null) {
+                    /*
+                     * If the new range does not specify any unit, then we do not know how to convert
+                     * the values before to perform the union operation. Conservatively do nothing.
+                     */
+                    if (unit == null) {
+                        continue;
+                    }
+                    /*
+                     * If previous range did not specify any unit, then unconditionally replace it by
+                     * the new range since it provides more information. If both ranges specify units,
+                     * then we will compute the union if we can, or ignore the new range otherwise.
+                     */
+                    final Unit<?> previous = range.unit();
+                    if (previous != null) {
+                        if (previous.isCompatible(unit)) {
+                            range = (MeasurementRange<Double>) range.union(
+                                    MeasurementRange.create(min, true, max, true, unit));
+                        }
+                        continue;
+                    }
+                }
+                range = MeasurementRange.create(min, true, max, true, unit);
+            }
+        }
+        return range;
+    }
+
+    /**
+     * Returns the union of all time ranges found in the given extent, or {@code null} if none.
+     *
+     * @param  extent The extent to convert to a time range, or {@code null}.
+     * @return A time range created from the given extent, or {@code null} if none.
+     *
+     * @since 0.4
+     */
+    public static Range<Date> getTimeRange(final Extent extent) {
+        Date min = null;
+        Date max = null;
+        if (extent != null) {
+            for (final TemporalExtent t : extent.getTemporalElements()) {
+                final Date startTime, endTime;
+                if (t instanceof DefaultTemporalExtent) {
+                    final DefaultTemporalExtent dt = (DefaultTemporalExtent) t;
+                    startTime = dt.getStartTime(); // Maybe user has overridden those methods.
+                    endTime   = dt.getEndTime();
+                } else {
+                    final TemporalPrimitive p = t.getExtent();
+                    startTime = DefaultTemporalExtent.getTime(p, true);
+                    endTime   = DefaultTemporalExtent.getTime(p, false);
+                }
+                if (startTime != null && (min == null || startTime.before(min))) min = startTime;
+                if (  endTime != null && (max == null ||   endTime.after (max))) max =   endTime;
+            }
+        }
+        if (min == null && max == null) {
+            return null;
+        }
+        return new Range<Date>(Date.class, min, true, max, true);
+    }
+
+    /**
      * Returns an instant in the {@linkplain Extent#getTemporalElements() temporal elements} of the given extent,
      * or {@code null} if none. First, this method computes the union of all temporal elements. Then this method
      * computes the linear interpolation between the start and end time as in the following pseudo-code:

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyInformationTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyInformationTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyInformationTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyInformationTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -39,7 +39,7 @@ import static org.apache.sis.test.TestUt
 
 
 /**
- * Tests {@link PropertyInformation}.
+ * Tests the {@link PropertyInformation} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -33,7 +33,7 @@ import static org.apache.sis.test.Assert
 
 
 /**
- * Tests {@link SpecialCases}.
+ * Test the {@link SpecialCases} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -22,14 +22,16 @@ import java.util.Locale;
 import javax.xml.bind.JAXBException;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
+import org.apache.sis.metadata.iso.citation.HardCodedCitations;
 import org.apache.sis.util.iso.SimpleInternationalString;
+import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
 import org.opengis.test.Validators;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.apache.sis.test.MetadataAssert.*;
 import static org.opengis.referencing.ReferenceIdentifier.*;
 
 
@@ -167,4 +169,14 @@ public final strictfp class ImmutableIde
         final ImmutableIdentifier identifier = new ImmutableIdentifier(new DefaultCitation("EPSG"), null, "4326");
         new DefaultIdentifierTest().testMarshal("RS_Identifier", identifier);
     }
+
+    /**
+     * Tests WKT formatting.
+     */
+    @Test
+    public void testWKT() {
+        final ImmutableIdentifier id = new ImmutableIdentifier(HardCodedCitations.OGP, "EPSG", "4326", "8.2", null);
+        assertWktEquals(Convention.WKT2, "Id[“EPSG”, 4326, “8.2”, Citation[“OGP”]]", id);
+        assertWktEquals(Convention.WKT1, "AUTHORITY[“EPSG”, “4326”]", id);
+    }
 }

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -16,7 +16,11 @@
  */
 package org.apache.sis.metadata.iso.extent;
 
+import java.util.Arrays;
+import javax.measure.unit.SI;
 import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.apache.sis.measure.MeasurementRange;
+import org.apache.sis.test.mock.VerticalCRSMock;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -41,6 +45,26 @@ public final strictfp class ExtentsTest 
     private static final double MINUTE = 1./60;
 
     /**
+     * Tests {@link Extents#getVerticalRange(Extent)}.
+     */
+    @Test
+    public void testGetVerticalRange() {
+        final DefaultExtent extent = new DefaultExtent();
+        extent.setVerticalElements(Arrays.asList(
+                new DefaultVerticalExtent( -200,  -100, VerticalCRSMock.HEIGHT),
+                new DefaultVerticalExtent(  150,   300, VerticalCRSMock.DEPTH),
+                new DefaultVerticalExtent(  0.1,   0.2, VerticalCRSMock.SIGMA_LEVEL),
+                new DefaultVerticalExtent( -600,  -300, VerticalCRSMock.HEIGHT_ft), // [91.44 182.88] metres
+                new DefaultVerticalExtent(10130, 20260, VerticalCRSMock.BAROMETRIC_HEIGHT)
+        ));
+        final MeasurementRange<Double> range = Extents.getVerticalRange(extent);
+        assertNotNull("getVerticalRange", range);
+        assertEquals("unit", SI.METRE,  range.unit());
+        assertEquals("minimum", -300,   range.getMinDouble(), 0.001);
+        assertEquals("maximum", -91.44, range.getMaxDouble(), 0.001);
+    }
+
+    /**
      * Tests {@link Extents#intersection(GeographicBoundingBox, GeographicBoundingBox)}.
      */
     @Test

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultBrowseGraphicTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultBrowseGraphicTest.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultBrowseGraphicTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultBrowseGraphicTest.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -36,7 +36,7 @@ import static java.util.Collections.sing
 
 
 /**
- * Test {@link DefaultBrowseGraphic}.
+ * Tests {@link DefaultBrowseGraphic}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4

Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -31,6 +31,7 @@ import org.junit.BeforeClass;
  */
 @Suite.SuiteClasses({
     org.apache.sis.internal.metadata.MetadataUtilitiesTest.class,
+    org.apache.sis.internal.metadata.ReferencingUtilitiesTest.class,
 
     // Classes using Java reflection.
     org.apache.sis.metadata.PropertyInformationTest.class,
@@ -80,7 +81,12 @@ import org.junit.BeforeClass;
     org.apache.sis.metadata.iso.ImmutableIdentifierTest.class,
     org.apache.sis.metadata.iso.DefaultMetadataTest.class,
     org.apache.sis.metadata.iso.CustomMetadataTest.class,
-    org.apache.sis.metadata.iso.AllMetadataTest.class
+    org.apache.sis.metadata.iso.AllMetadataTest.class,
+
+    org.apache.sis.io.wkt.ConventionTest.class,
+    org.apache.sis.io.wkt.SymbolsTest.class,
+    org.apache.sis.io.wkt.ColorsTest.class,
+    org.apache.sis.io.wkt.FormatterTest.class
 })
 public final strictfp class MetadataTestSuite extends TestSuite {
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -74,8 +74,8 @@ import org.apache.sis.internal.jdk7.Obje
  * The default implementation of methods listed in the right column can handle such cases.
  *
  * <table class="compact" align="center"><tr><td>
- *   <img src="doc-files/AntiMeridian.png">
- * </td><td>
+ *   <img style="vertical-align: middle" src="doc-files/AntiMeridian.png">
+ * </td><td style="vertical-align: middle">
  * Supported methods:
  * <ul>
  *   <li>{@link #getMinimum(int)}</li>

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -71,8 +71,8 @@ import static org.apache.sis.math.MathFu
  * The default implementation of methods listed in the right column can handle such cases.
  *
  * <table class="compact" align="center"><tr><td>
- *   <img src="doc-files/AntiMeridian.png">
- * </td><td>
+ *   <img style="vertical-align: middle" src="doc-files/AntiMeridian.png">
+ * </td><td style="vertical-align: middle">
  * Supported methods:
  * <ul>
  *   <li>{@link #getMinimum(int)}</li>

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -25,7 +25,7 @@ import org.apache.sis.internal.util.Defi
 import org.apache.sis.referencing.NamedIdentifier;
 import org.apache.sis.metadata.iso.citation.Citations;
 
-import static org.apache.sis.internal.referencing.ReferencingUtilities.toURNType;
+import static org.apache.sis.internal.metadata.ReferencingUtilities.toURNType;
 
 
 /**
@@ -148,7 +148,7 @@ public final class Code {
                 }
             }
             /*
-             * If no "urn:" or "http:" form has been found, try to create a "urn:" form from the first identifier.
+             * If no "urn:" or "http:" form has been found, try to create a "urn:" form the first identifier.
              * For example "EPSG:4326" may be converted to "urn:ogc:def:crs:EPSG:8.2:4326". If the first identifier
              * can not be converted to a "urn:" form, then it will be returned as-is.
              */

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/AxisDirections.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -83,6 +83,12 @@ public final class AxisDirections extend
     }
 
     /**
+     * Ordinal of the last element in the {@link AxisDirection} code list.
+     * This is used for differentiating the standard codes from the user-defined ones.
+     */
+    private static final int LAST_ORDINAL = DISPLAY_DOWN.ordinal();
+
+    /**
      * Do not allow instantiation of this class.
      */
     private AxisDirections() {
@@ -208,6 +214,19 @@ public final class AxisDirections extend
     }
 
     /**
+     * Returns {@code true} if the given direction is {@code GEOCENTRIC_X}, {@code GEOCENTRIC_Y}
+     * or {@code GEOCENTRIC_Z}.
+     *
+     * @param  dir The direction to test, or {@code null}.
+     * @return {@code true} if the given direction is one of geocentric directions.
+     */
+    public static boolean isGeocentric(final AxisDirection dir) {
+        if (dir == null) return false;
+        final int ordinal = dir.ordinal();
+        return ordinal >= GEOCENTRIC_X.ordinal() && ordinal <= GEOCENTRIC_Z.ordinal();
+    }
+
+    /**
      * Returns {@code true} if the given direction is a spatial axis direction (including vertical and geocentric axes).
      * The current implementation conservatively returns {@code true} for every non-null directions except a hard-coded
      * set of directions which are known to be non-spatial. We conservatively accept unknown axis directions because
@@ -222,13 +241,23 @@ public final class AxisDirections extend
      * @param  image {@code true} for accepting grid and image axis directions in addition to spatial ones.
      * @return {@code true} if the given direction is presumed for spatial CS.
      */
-    public static boolean isSpatialOrCustom(final AxisDirection dir, final boolean image) {
+    public static boolean isSpatialOrUserDefined(final AxisDirection dir, final boolean image) {
         if (dir == null) return false;
         final int ordinal = dir.ordinal();
         return ordinal < FUTURE.ordinal() || ordinal > (image ? PAST : DISPLAY_DOWN).ordinal();
     }
 
     /**
+     * Returns {@code true} if the given direction is a user-defined direction (i.e. is not defined by GeoAPI).
+     *
+     * @param  dir The direction to test, or {@code null}.
+     * @return {@code true} if the given direction is user-defined.
+     */
+    public static boolean isUserDefined(final AxisDirection dir) {
+        return (dir != null) && dir.ordinal() > LAST_ORDINAL;
+    }
+
+    /**
      * Returns {@code true} if the given direction is {@code COLUMN_POSITIVE}, {@code COLUMN_NEGATICE},
      * {@code ROW_POSITIVE} or {@code ROW_NEGATIVE}.
      *

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -38,11 +38,14 @@ import org.opengis.referencing.ObjectFac
 import org.opengis.referencing.AuthorityFactory;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.ReferenceIdentifier;
-import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.metadata.ReferencingUtilities;
 import org.apache.sis.internal.jaxb.referencing.Code;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
+import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.io.wkt.FormattableObject;
+import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.io.wkt.ElementKind;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.util.Deprecable;
 import org.apache.sis.util.ComparisonMode;
@@ -57,7 +60,7 @@ import static org.apache.sis.internal.ut
 import static org.apache.sis.internal.util.CollectionsExt.nonEmpty;
 import static org.apache.sis.internal.util.CollectionsExt.immutableSet;
 import static org.apache.sis.internal.util.Utilities.appendUnicodeIdentifier;
-import static org.apache.sis.internal.referencing.ReferencingUtilities.canSetProperty;
+import static org.apache.sis.internal.metadata.MetadataUtilities.canSetProperty;
 
 // Related to JDK7
 import org.apache.sis.internal.jdk7.Objects;
@@ -135,6 +138,19 @@ public class AbstractIdentifiedObject ex
     private static final long serialVersionUID = -5173281694258483264L;
 
     /**
+     * Optional key which can be given to the {@linkplain #AbstractIdentifiedObject(Map) constructor} for specifying
+     * the locale to use for producing error messages. Notes:
+     *
+     * <ul>
+     *   <li>The locale is not stored in any {@code AbstractIdentifiedObject} property;
+     *       its value is ignored if no error occurred at construction time.</li>
+     *   <li>The locale is used on a <cite>best effort</cite> basis;
+     *       not all error messages may be localized.</li>
+     * </ul>
+     */
+    public static final String LOCALE_KEY = Errors.LOCALE_KEY;
+
+    /**
      * The name for this object or code. Shall never be {@code null}.
      *
      * <p><b>Consider this field as final!</b>
@@ -193,8 +209,12 @@ public class AbstractIdentifiedObject ex
     /**
      * Constructs an object from the given properties. Keys are strings from the table below.
      * The map given in argument shall contain an entry at least for the
-     * {@value org.opengis.referencing.IdentifiedObject#NAME_KEY} key.
+     * {@value org.opengis.referencing.IdentifiedObject#NAME_KEY} or
+     * {@value org.opengis.metadata.Identifier#CODE_KEY} key.
      * Other properties listed in the table below are optional.
+     * In particular, {@code "authority"}, {@code "code"}, {@code "codespace"} and {@code "version"}
+     * are convenience properties for building a name, and are ignored if the {@code "name"} property
+     * is already a {@link ReferenceIdentifier} object instead than a {@link String}.
      *
      * <table class="sis">
      *   <tr>
@@ -242,14 +262,27 @@ public class AbstractIdentifiedObject ex
      *     <td>{@link InternationalString} or {@link String}</td>
      *     <td>{@link #getRemarks()}</td>
      *   </tr>
+     *   <tr>
+     *     <td>{@value #LOCALE_KEY}</td>
+     *     <td>{@link Locale}</td>
+     *     <td>(none)</td>
+     *   </tr>
      * </table>
      *
-     * Additionally, all localizable attributes like {@code "remarks"} may have a language and country code suffix.
+     * {@section Localization}
+     * All localizable attributes like {@code "remarks"} may have a language and country code suffix.
      * For example the {@code "remarks_fr"} property stands for remarks in {@linkplain Locale#FRENCH French} and
      * the {@code "remarks_fr_CA"} property stands for remarks in {@linkplain Locale#CANADA_FRENCH French Canadian}.
+     * They are convenience properties for building the {@code InternationalString} value.
      *
-     * <p>Note that the {@code "authority"} and {@code "version"} properties are ignored if the {@code "name"}
-     * property is already a {@link ReferenceIdentifier} object instead than a {@link String}.</p>
+     * <p>The {@code "locale"} property applies only in case of exception for formatting the error message, and
+     * is used only on a <cite>best effort</cite> basis. The locale is discarded after successful construction
+     * since localizations are applied by the {@link InternationalString#toString(Locale)} method.</p>
+     *
+     * {@section Properties map versus explicit arguments}
+     * Generally speaking, information provided in the {@code properties} map are considered ignorable metadata
+     * while information provided in explicit arguments to the sub-class constructors have an impact on coordinate
+     * transformation results. See {@link #equals(Object, ComparisonMode)} for more information.
      *
      * @param  properties The properties to be given to this identified object.
      * @throws IllegalArgumentException if a property has an invalid value.
@@ -266,7 +299,7 @@ public class AbstractIdentifiedObject ex
         } else if (value instanceof ReferenceIdentifier) {
             name = (ReferenceIdentifier) value;
         } else {
-            throw illegalPropertyType(NAME_KEY, value);
+            throw illegalPropertyType(properties, NAME_KEY, value);
         }
 
         // -------------------------------------------------------------------
@@ -276,7 +309,7 @@ public class AbstractIdentifiedObject ex
         try {
             alias = immutableSet(true, Types.toGenericNames(value, null));
         } catch (ClassCastException e) {
-            throw (IllegalArgumentException) illegalPropertyType(ALIAS_KEY, value).initCause(e);
+            throw (IllegalArgumentException) illegalPropertyType(properties, ALIAS_KEY, value).initCause(e);
         }
 
         // -----------------------------------------------------------
@@ -290,7 +323,7 @@ public class AbstractIdentifiedObject ex
         } else if (value instanceof ReferenceIdentifier[]) {
             identifiers = immutableSet(true, (ReferenceIdentifier[]) value);
         } else {
-            throw illegalPropertyType(IDENTIFIERS_KEY, value);
+            throw illegalPropertyType(properties, IDENTIFIERS_KEY, value);
         }
 
         // ----------------------------------------
@@ -300,10 +333,13 @@ public class AbstractIdentifiedObject ex
     }
 
     /**
-     * Returns the exception to be thrown when a property if of illegal type.
+     * Returns the exception to be thrown when a property is of illegal type.
      */
-    private static IllegalArgumentException illegalPropertyType(final String key, final Object value) {
-        return new IllegalArgumentException(Errors.format(Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
+    private static IllegalArgumentException illegalPropertyType(
+            final Map<String,?> properties, final String key, final Object value)
+    {
+        return new IllegalArgumentException(Errors.getResources(properties)
+                .getString(Errors.Keys.IllegalPropertyClass_2, key, value.getClass()));
     }
 
     /**
@@ -678,7 +714,7 @@ public class AbstractIdentifiedObject ex
      * two objects that can be differentiated only by some identifier (name or alias), like
      * {@linkplain org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis coordinate system axes},
      * {@linkplain org.apache.sis.referencing.datum.AbstractDatum datum},
-     * {@linkplain org.apache.sis.parameter.AbstractParameterDescriptor parameters} and
+     * {@linkplain org.apache.sis.parameter.DefaultParameterDescriptor parameters} and
      * {@linkplain org.apache.sis.referencing.operation.DefaultOperationMethod operation methods}.
      * See {@link #equals(Object, ComparisonMode)} for more information.
      *
@@ -713,38 +749,56 @@ public class AbstractIdentifiedObject ex
     }
 
     /**
-     * Compares this object with the specified object for equality.
-     * The strictness level is controlled by the second argument:
-     *
-     * <ul>
-     *   <li>If {@code mode} is {@link ComparisonMode#STRICT STRICT}, then this method verifies if the two
-     *       objects are of the same {@linkplain #getClass() class} and compares all public properties,
-     *       including SIS-specific (non standard) properties.</li>
-     *   <li>If {@code mode} is {@link ComparisonMode#BY_CONTRACT BY_CONTRACT}, then this method verifies if the two
-     *       objects implement the same {@linkplain #getInterface() GeoAPI interface} and compares all properties
-     *       defined by that interface ({@linkplain #getName() name}, {@linkplain #getRemarks() remarks},
-     *       {@linkplain #getIdentifiers() identifiers}, <i>etc</i>).</li>
-     *   <li>If {@code mode} is {@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA},
-     *       then this method compares only the properties needed for computing transformations.
-     *       In other words, {@code sourceCRS.equals(targetCRS, IGNORE_METADATA)} returns {@code true}
-     *       if the transformation from {@code sourceCRS} to {@code targetCRS} would be the
-     *       identity transform, no matter what {@link #getName()} said.</li>
-     * </ul>
+     * Compares this object with the given object for equality.
+     * The strictness level is controlled by the second argument,
+     * from stricter to more permissive values:
+     *
+     * <p><table class="compact">
+     *   <tr><td>{@link ComparisonMode#STRICT STRICT}:</td>
+     *        <td>Verifies if the two objects are of the same {@linkplain #getClass() class}
+     *            and compares all public properties, including SIS-specific (non standard) properties.</td></tr>
+     *   <tr><td>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT}:</td>
+     *       <td>Verifies if the two objects implement the same {@linkplain #getInterface() GeoAPI interface}
+     *           and compares all properties defined by that interface ({@linkplain #getName() name},
+     *           {@linkplain #getIdentifiers() identifiers}, {@linkplain #getRemarks() remarks}, <i>etc</i>).
+     *           The two objects do not need to be instances of the same implementation class
+     *           and SIS-specific properties are ignored.</td></tr>
+     *   <tr><td>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA}:</td>
+     *       <td>Compares only the properties relevant to coordinate transformations. Generally speaking, the content
+     *           of the {@code properties} map given at {@linkplain #AbstractIdentifiedObject(Map) construction time}
+     *           is considered ignorable metadata while the explicit arguments given to the constructor (if any) are
+     *           considered non-ignorable. Note that there is some exceptions to this rule of thumb — see
+     *           <cite>When object name matter</cite> below.</td></tr>
+     *   <tr><td>{@link ComparisonMode#APPROXIMATIVE APPROXIMATIVE}:</td>
+     *       <td>Same as {@code IGNORE_METADATA}, with some tolerance threshold on numerical values.</td></tr>
+     *   <tr><td>{@link ComparisonMode#DEBUG DEBUG}:</td>
+     *        <td>Special mode for figuring out why two objects expected to be equal are not.</td></tr>
+     * </table></p>
+     *
+     * The main guideline is that if {@code sourceCRS.equals(targetCRS, IGNORE_METADATA)} returns {@code true},
+     * then the transformation from {@code sourceCRS} to {@code targetCRS} should be the identity transform
+     * even if the two CRS do not have the same name.
      *
-     * {@section Exceptions to the above rules}
+     * {@section When object name matter}
      * Some subclasses (especially
      * {@link org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis},
      * {@link org.apache.sis.referencing.datum.AbstractDatum} and
-     * {@link org.apache.sis.parameter.AbstractParameterDescriptor}) will compare the
+     * {@link org.apache.sis.parameter.DefaultParameterDescriptor}) will compare the
      * {@linkplain #getName() name} even in {@code IGNORE_METADATA} mode,
      * because objects of those types with different names have completely different meaning.
      * For example nothing differentiate the {@code "semi_major"} and {@code "semi_minor"} parameters except the name.
      * The name comparison may be lenient however, i.e. the rules may accept a name matching an alias.
      * See {@link #isHeuristicMatchForName(String)} for more information.
      *
+     * {@section Conformance to the <code>equals(Object)</code> method contract}
+     * {@link ComparisonMode#STRICT} is the only mode compliant with the {@link Object#equals(Object)} contract.
+     * For all other modes, the comparison is not guaranteed to be <cite>symmetric</cite> neither
+     * <cite>transitive</cite>. See {@link LenientComparable#equals(Object, ComparisonMode) LenientComparable}
+     * for more information.
+     *
      * @param  object The object to compare to {@code this}.
      * @param  mode The strictness level of the comparison.
-     * @return {@code true} if both objects are equal.
+     * @return {@code true} if both objects are equal according the given comparison mode.
      *
      * @see #computeHashCode()
      * @see org.apache.sis.util.Utilities#deepEquals(Object, Object, ComparisonMode)
@@ -892,4 +946,53 @@ public class AbstractIdentifiedObject ex
     protected long computeHashCode() {
         return Objects.hash(name, nonNull(alias), nonNull(identifiers), remarks) ^ getInterface().hashCode();
     }
+
+    /**
+     * Formats the inner part of this <cite>Well Known Text</cite> (WKT) object into the given formatter.
+     * The default implementation writes the following elements:
+     *
+     * <ul>
+     *   <li>The object {@linkplain #getName() name}.</li>
+     * </ul>
+     *
+     * Keywords and metadata (scope, extent, identifier and remarks) shall not be formatted here.
+     * For example if this formattable element is for a {@code GeodeticCRS[…]} element,
+     * then subclasses shall write the content starting at the insertion point shown below:
+     *
+     * <p><table class="compact">
+     * <tr>
+     *   <th>WKT example</th>
+     *   <th>Java code example</th>
+     * </tr><tr><td>
+     * {@preformat text
+     *   GeodeticCRS["WGS 84", ID["EPSG", 4326]]
+     *                       ↑
+     *               (insertion point)
+     * }
+     * </td><td>
+     * {@preformat java
+     *     super.formatTo(formatter);
+     *     // ... write the elements at the insertion point ...
+     *     return "GeodeticCRS";
+     * }
+     * </td></tr></table></p>
+     *
+     * {@section Formatting non-standard WKT}
+     * If the implementation can not represent this object without violating some WKT constraints,
+     * it can uses its own (non-standard) keywords but shall declare that it did so by invoking one
+     * of the {@link Formatter#setInvalidWKT(IdentifiedObject, Exception) Formatter.setInvalidWKT(…)}
+     * methods.
+     *
+     * <p>Alternatively, the implementation may also have no WKT keyword for this object.
+     * In such case, this method shall return {@code null}.</p>
+     *
+     * @param  formatter The formatter where to format the inner content of this WKT element.
+     * @return The {@linkplain org.apache.sis.io.wkt.KeywordCase#CAMEL_CASE CamelCase} keyword
+     *         for the WKT element, or {@code null} if unknown.
+     */
+    @Override
+    protected String formatTo(final Formatter formatter) {
+        WKTUtilities.appendName(this, formatter, ElementKind.forType(getClass()));
+        return null;
+    }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -36,9 +36,13 @@ import org.apache.sis.internal.jdk7.Obje
 
 /**
  * Description of a spatial and temporal reference system used by a dataset.
- * This class inherits the {@linkplain #getName() name}, {@linkplain #getAlias() aliases},
+ * Reference systems do not necessarily use coordinates. For example a reference system could use postal codes.
+ * The specialized case of referencing by coordinates is handled by the
+ * {@link org.apache.sis.referencing.crs.AbstractCRS} subclass.
+ *
+ * <p>This class inherits the {@linkplain #getName() name}, {@linkplain #getAlias() aliases},
  * {@linkplain #getIdentifiers() identifiers} and {@linkplain #getRemarks() remarks} from
- * the parent class, and adds the following information:
+ * the parent class, and adds the following information:</p>
  *
  * <ul>
  *   <li>a {@linkplain #getDomainOfValidity() domain of validity}, the area for which the reference system is valid,</li>

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1569932&r1=1569931&r2=1569932&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] Wed Feb 19 21:40:59 2014
@@ -39,7 +39,7 @@ import org.opengis.metadata.extent.Exten
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.internal.referencing.AxisDirections;
-import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.metadata.ReferencingUtilities;
 import org.apache.sis.referencing.cs.DefaultVerticalCS;
 import org.apache.sis.referencing.cs.DefaultEllipsoidalCS;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;



Mime
View raw message