You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/05/28 18:51:06 UTC

svn commit: r1682276 [1/3] - in /sis/branches/JDK8: core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/ core/si...

Author: desruisseaux
Date: Thu May 28 16:51:05 2015
New Revision: 1682276

URL: http://svn.apache.org/r1682276
Log:
fix(Referencing): try to solve the ambiguity between EPSG and IOGP codespace (SIS-199).
The "authority" citation should be EPSG, not IOGP. But IOGP should be declared a the responsibly party of EPSG.

To reduce more the risk of confusion, we should go further and remove all constants in the Citations class
which stand for an organisation, and keep only the constants which stand for a resources (SIS-200).

Added:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java   (with props)
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/CitationConstant.java
      - copied, changed from r1682275, sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Authority.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/MetadataServices.java   (with props)
Removed:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Authority.java
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/CodeTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterValueTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterBuilderTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterFormatTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/BuilderTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/NamedIdentifierTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultProjectedCRSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCartesianCSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultEllipsoidalCSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultTemporalDatumTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultOperationMethodTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultTransformationTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/ReferencingAssert.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ReferencingInMetadataTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifier.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/SystemListener.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/Types.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/simple/SimpleIdentifierTest.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationsTest.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java
    sis/branches/JDK8/profiles/sis-french-profile/src/test/java/org/apache/sis/internal/profile/fra/DirectReferenceSystemTest.java
    sis/branches/JDK8/profiles/sis-french-profile/src/test/resources/org/apache/sis/internal/profile/fra/DirectReferenceSystem.xml

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Thu May 28 16:51:05 2015
@@ -79,6 +79,7 @@ public abstract class ReferencingService
     @Override
     protected final void classpathChanged() {
         synchronized (ReferencingServices.class) {
+            SystemListener.remove(this);
             instance = null;
         }
     }
@@ -95,14 +96,22 @@ public abstract class ReferencingService
         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 (ReflectiveOperationException exception) {
-                    // Should never happen if we didn't broke our helper class.
-                    throw new AssertionError(exception);
+                if (c == null) {
+                    /*
+                     * Double-checked locking: okay since Java 5 provided that the 'instance' field is volatile.
+                     * In the particular case of this class, the intend is to ensure that SystemListener.add(…)
+                     * is invoked only once.
+                     */
+                    try {
+                        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 (ReflectiveOperationException exception) {
+                        // Should never happen if we didn't broke our helper class.
+                        throw new AssertionError(exception);
+                    }
+                    instance = c;
                 }
             }
         }

Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java?rev=1682276&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java (added)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java [UTF-8] Thu May 28 16:51:05 2015
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.metadata;
+
+import java.util.Arrays;
+import org.opengis.metadata.citation.Role;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.citation.PresentationForm;
+import org.apache.sis.internal.simple.SimpleCitation;
+import org.apache.sis.internal.simple.SimpleIdentifier;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.util.MetadataServices;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.metadata.iso.citation.DefaultCitation;
+import org.apache.sis.metadata.iso.citation.DefaultOrganisation;
+import org.apache.sis.metadata.iso.citation.DefaultResponsibility;
+import org.apache.sis.util.iso.SimpleInternationalString;
+
+
+/**
+ * Implements the metadata services needed by the {@code "sis-utility"} module.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.6
+ * @version 0.6
+ * @module
+ */
+public final class ServicesForUtility extends MetadataServices {
+    /**
+     * Creates a new instance. This constructor is invoked by reflection only.
+     */
+    public ServicesForUtility() {
+    }
+
+    /**
+     * Returns the constant defined in the {@link Citations} class for the given name.
+     *
+     * @param  name The name of one of the citation constants defined in the {@code Citations} class.
+     * @return The requested citation, or {@code null} if there is no constant for the given name.
+     */
+    @Override
+    public Citation getCitationConstant(final String name) {
+        final Citation c = Citations.fromName(name);
+        /*
+         * The fact that the following line uses the citation class as a non-public criterion for identifying
+         * when the Citations.fromName(String) method found no match is documented in that Citations.fromName
+         * method body. If we do not rely anymore on this criterion, please update the Citations.fromName(…)
+         * comment accordingly.
+         */
+        return (c.getClass() != SimpleCitation.class) ? c : null;
+    }
+
+    /**
+     * Returns the build-in citation for the given primary key, or {@code null}.
+     *
+     * @param  key The primary key of the desired citation.
+     * @return The requested citation, or {@code null} if unknown.
+     *
+     * @todo The content is hard-coded for now. But the plan for a future version is to fetch richer information
+     *       from a database, including for example the responsible party and the URL. However that method would
+     *       need to make sure that the given key is present in the alternate titles, since we rely on that when
+     *       checking for code spaces.
+     */
+    @Override
+    public Citation createCitation(final String key) {
+        String   title;              // Title of the Citation to create.
+        int      storeKeyAs = 1;     // 0 to not store the key, 1 to store as alternate title, 2 to store as identifier.
+        Citation authority  = null;  // If the key is stored as an identifier (storeKeyAs = 2), the authority to use.
+        switch (key) {
+            case "ISO"          : title = "International Organization for Standardization"; break;
+            case Constants.OGC  : title = "Open Geospatial Consortium"; break;
+            case Constants.IOGP : title = "International Association of Oil & Gas producers"; break;
+            case Constants.EPSG : title = "EPSG Geodetic Parameter Dataset"; storeKeyAs = 2; authority = Citations.OGP; break;
+            case Constants.SIS  : title = "Apache Spatial Information System"; storeKeyAs = 2; break;
+            case "ISBN"         : title = "International Standard Book Number"; break;
+            case "ISSN"         : title = "International Standard Serial Number"; break;
+            case "Proj4"        : title = "Proj.4"; storeKeyAs = 0; break;
+            case "S57"          : title = "S-57"; storeKeyAs = 0; break;
+            default: return super.createCitation(key);
+        }
+        final DefaultCitation c = new DefaultCitation(title);
+        switch (storeKeyAs) {
+            case 1: c.getAlternateTitles().add(new SimpleInternationalString(key)); break;
+            case 2: c.getIdentifiers().add(new SimpleIdentifier(authority, key, false)); break;
+        }
+        /*
+         * Additional information other than the given 'key' argument. All identifiers added here shall also be
+         * understood by Citations.fromName(String) method. Constants are declared below this method for making
+         * easier to track those special cases.
+         */
+        switch (key) {
+            /*
+             * More complete information is provided as an ISO 19115 structure
+             * in EPSG Surveying and Positioning Guidance Note Number 7, part 1.
+             */
+            case Constants.EPSG: {
+                final DefaultOrganisation organisation = new DefaultOrganisation();
+                organisation.setName(Citations.OGP.getTitle());
+                c.getCitedResponsibleParties().add(new DefaultResponsibility(Role.PRINCIPAL_INVESTIGATOR, null, organisation));
+                c.getPresentationForms().add(PresentationForm.TABLE_DIGITAL);
+                break;
+            }
+            /*
+             * "OGP" and "IOGP" are used as value in the GML 'codeSpace' attribute.
+             * From this point of view, we can see them as identifiers.
+             */
+            case Constants.IOGP: {
+                c.setIdentifiers(Arrays.asList(new SimpleIdentifier[] {
+                    new SimpleIdentifier(null, Constants.IOGP, false),
+                    new SimpleIdentifier(null, OGP, true)   // Existed before "IOGP".
+                }));
+                break;
+            }
+        }
+        c.freeze();
+        return c;
+    }
+
+    /**
+     * The legacy name of {@linkplain org.apache.sis.metadata.iso.citation.Citations#IOGP},
+     * to be declared as an additional identifier by {@link #createCitation(String)}.
+     *
+     * <p>Search for usages of this constant in order to locate where a special processing
+     * is done for managing the relationship between OGP, IOGP and EPSG identifiers.</p>
+     */
+    public static final String OGP = "OGP";
+}

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ServicesForUtility.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyInformation.java [UTF-8] Thu May 28 16:51:05 2015
@@ -128,7 +128,7 @@ final class PropertyInformation<E> exten
     PropertyInformation(final Citation standard, final String property, final Method getter,
             final Class<E> elementType, final ValueRange range)
     {
-        super(standard, property);
+        super(standard, property, getter.isAnnotationPresent(Deprecated.class));
         parent = getter.getDeclaringClass();
         this.elementType = elementType;
         final UML uml = getter.getAnnotation(UML.class);

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] Thu May 28 16:51:05 2015
@@ -23,8 +23,15 @@ import org.apache.sis.util.CharSequences
 import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.simple.SimpleCitation;
+import org.apache.sis.internal.simple.CitationConstant;
+import org.apache.sis.internal.jaxb.NonMarshalledAuthority;
+import org.apache.sis.internal.metadata.ServicesForUtility;
+import org.apache.sis.internal.system.Modules;
+import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.metadata.iso.DefaultIdentifier;   // For javadoc
 
+import static org.apache.sis.internal.util.Citations.equalsFiltered;
+
 
 /**
  * A set of pre-defined constants and static methods working on {@linkplain Citation citations}.
@@ -53,47 +60,52 @@ public final class Citations extends Sta
      *
      * @category Organization
      */
-    public static final Citation ISO = new SimpleCitation("ISO");
+    public static final Citation ISO = new CitationConstant("ISO");
 
     /**
      * The <a href="http://www.opengeospatial.org">Open Geospatial Consortium</a> organization.
-     * "Open Geospatial Consortium" is the new name for "OpenGIS consortium".
+     * <cite>"Open Geospatial Consortium"</cite> is the new name for <cite>"OpenGIS consortium"</cite>.
+     * An {@linkplain DefaultCitation#getAlternateTitles() alternate title} for this citation is "OGC"
+     * (according ISO 19115, alternate titles often contain abbreviations).
      *
      * @category Organization
      */
-    public static final Citation OGC = new SimpleCitation(Constants.OGC);
+    public static final Citation OGC = new CitationConstant(Constants.OGC);
 
     /**
      * The <a href="http://www.ogp.org.uk">International Association of Oil &amp; Gas Producers</a> organization.
      * This organization is responsible for maintainance of {@link #EPSG} database.
      *
-     * @see #EPSG
-     * @category Organization
-     *
      * @since 0.4
      *
      * @deprecated The OGP organization is now known as IOGP. This citation will be removed in SIS 0.7
      *             because of this name change and for avoiding confusion with {@link #EPSG} citation.
      */
     @Deprecated
-    public static final Citation OGP = new SimpleCitation("OGP"); // TODO: after removal, forName("OGP") should map to EPSG.
+    public static final Citation OGP = new CitationConstant(Constants.IOGP);
 
     /**
-     * The <a href="http://www.epsg.org">EPSG</a> dataset. This citation is used as an authority for
-     * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}
-     * identifiers.
+     * The <a href="http://www.epsg.org">EPSG Geodetic Parameter Dataset</a> identifier space.
+     * EPSG is not an organization by itself, but is the <em>identifier space</em> managed by the
+     * <a href="http://www.iogp.org">International Association of Oil &amp; Gas producers</a> (IOGP) organization
+     * for {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system} identifiers.
      *
      * <div class="note"><b>Historical note:</b>
      * The EPSG acronym meaning was <cite>European Petroleum Survey Group</cite>.
      * But this meaning does not apply anymore since the European and American associations merged into
-     * the <a href="http://www.iogp.org">International Association of Oil &amp; Gas producers</a> (IOGP).
+     * the <cite>Association of Oil &amp; Gas producers</cite> (OGP), later renamed as IOGP.
      * The legacy acronym now applies only to the database Coordinate Reference System definitions,
-     * known as <cite>EPSG dataset</cite>.</div>
+     * known as <cite>EPSG Geodetic Parameter Dataset</cite>.</div>
      *
-     * The citation {@linkplain DefaultCitation#getTitle() title} and contact information reference
+     * The citation {@linkplain DefaultCitation#getCitedResponsibleParties() responsible party} is
      * the IOGP organization, but the {@link IdentifierSpace#getName() namespace} is {@code "EPSG"}.
-     * Note that both the new "IOGP" and the legacy "OGP" abbreviations may be used as a code space
-     * in GML files.
+     * The {@code "EPSG"} name shall be used in URN, but the {@code codeSpace} attribute value in
+     * GML files can be “EPSG” or the authority abbreviation, either “IOGP” or the older “OGP”.
+     * Example:
+     *
+     * {@preformat xml
+     *   <gml:identifier codeSpace="IOGP">urn:ogc:def:crs:EPSG::4326</gml:identifier>
+     * }
      *
      * @see #AUTO
      * @see #AUTO2
@@ -102,14 +114,14 @@ public final class Citations extends Sta
      *
      * @since 0.4
      */
-    public static final IdentifierSpace<Integer> EPSG = new Authority<>(Constants.IOGP, Constants.EPSG);
+    public static final IdentifierSpace<Integer> EPSG = new CitationConstant.Authority<>(Constants.EPSG);
 
     /**
      * The <a href="http://sis.apache.org">Apache SIS</a> project.
      *
      * @since 0.4
      */
-    public static final Citation SIS = new SimpleCitation(Constants.SIS);
+    public static final Citation SIS = new CitationConstant(Constants.SIS);
 
     /**
      * The <a href="http://www.esri.com">ESRI</a> organization.
@@ -119,7 +131,7 @@ public final class Citations extends Sta
      *
      * @since 0.4
      */
-    public static final Citation ESRI = new SimpleCitation("ESRI");
+    public static final Citation ESRI = new CitationConstant("ESRI");
 
     /**
      * The <a href="http://www.oracle.com">Oracle</a> organization.
@@ -128,7 +140,7 @@ public final class Citations extends Sta
      *
      * @since 0.4
      */
-    public static final Citation ORACLE = new SimpleCitation("Oracle");
+    public static final Citation ORACLE = new CitationConstant("Oracle");
 
     /**
      * The <a href="http://www.unidata.ucar.edu/software/netcdf-java">NetCDF</a> specification.
@@ -137,17 +149,17 @@ public final class Citations extends Sta
      *
      * @since 0.4
      */
-    public static final Citation NETCDF = new SimpleCitation("NetCDF");
+    public static final Citation NETCDF = new CitationConstant("NetCDF");
 
     /**
-     * The <a href="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</a> specification.
+     * The <a href="http://trac.osgeo.org/geotiff/">GeoTIFF</a> specification.
      * This specification identifies some map projections by their own numerical codes.
      *
      * @category Code space
      *
      * @since 0.4
      */
-    public static final IdentifierSpace<Integer> GEOTIFF = new Authority<>("GeoTIFF", "GeoTIFF");
+    public static final IdentifierSpace<Integer> GEOTIFF = new CitationConstant.Authority<>("GeoTIFF");
 
     /**
      * The <a href="http://trac.osgeo.org/proj/">Proj.4</a> project.
@@ -156,7 +168,7 @@ public final class Citations extends Sta
      *
      * @since 0.4
      */
-    public static final IdentifierSpace<String> PROJ4 = new Authority<>("Proj.4", "Proj4");
+    public static final IdentifierSpace<String> PROJ4 = new CitationConstant.Authority<>("Proj4");
 
     /**
      * The MapInfo software. This software defines its own projection codes.
@@ -165,7 +177,7 @@ public final class Citations extends Sta
      *
      * @since 0.6
      */
-    public static final IdentifierSpace<Integer> MAP_INFO = new Authority<>("MapInfo", "MapInfo");
+    public static final IdentifierSpace<Integer> MAP_INFO = new CitationConstant.Authority<>("MapInfo");
 
     /**
      * The <a href="http://www.iho.int/iho_pubs/standard/S-57Ed3.1/31Main.pdf">IHO transfer standard
@@ -175,10 +187,10 @@ public final class Citations extends Sta
      *
      * @since 0.6
      */
-    public static final IdentifierSpace<Integer> S57 = new Authority<>("S-57", "S57");
+    public static final IdentifierSpace<Integer> S57 = new CitationConstant.Authority<>("S57");
 
     /**
-     * <cite>International Standard Book Number</cite> (ISBN) defined by ISO-2108.
+     * The <cite>International Standard Book Number</cite> (ISBN) defined by ISO-2108.
      * The ISO-19115 metadata standard defines a specific attribute for this information,
      * but the SIS library handles it like any other identifier.
      *
@@ -186,10 +198,10 @@ public final class Citations extends Sta
      *
      * @category Code space
      */
-    public static final IdentifierSpace<String> ISBN = DefaultCitation.ISBN;
+    public static final IdentifierSpace<String> ISBN = new NonMarshalledAuthority<>("ISBN", NonMarshalledAuthority.ISBN);
 
     /**
-     * <cite>International Standard Serial Number</cite> (ISSN) defined by ISO-3297.
+     * The <cite>International Standard Serial Number</cite> (ISSN) defined by ISO-3297.
      * The ISO-19115 metadata standard defines a specific attribute for this information,
      * but the SIS library handles it like any other identifier.
      *
@@ -197,15 +209,36 @@ public final class Citations extends Sta
      *
      * @category Code space
      */
-    public static final IdentifierSpace<String> ISSN = DefaultCitation.ISSN;
+    public static final IdentifierSpace<String> ISSN = new NonMarshalledAuthority<>("ISSN", NonMarshalledAuthority.ISSN);
 
     /**
      * List of citations declared in this class.
+     * Most frequently used citations (at least in SIS) should be first.
      */
-    private static final Citation[] CITATIONS = {
-        ISO, OGC, OGP, EPSG, SIS, ESRI, ORACLE, NETCDF, GEOTIFF, PROJ4, MAP_INFO, S57, ISBN, ISSN
+    private static final CitationConstant[] CITATIONS = {
+        (CitationConstant) EPSG,
+        (CitationConstant) OGC,
+        (CitationConstant) ISO,
+        (CitationConstant) OGP,
+        (CitationConstant) NETCDF,
+        (CitationConstant) GEOTIFF,
+        (CitationConstant) ESRI,
+        (CitationConstant) ORACLE,
+        (CitationConstant) PROJ4,
+        (CitationConstant) MAP_INFO,
+        (CitationConstant) S57,
+        (CitationConstant) ISBN,
+        (CitationConstant) ISSN,
+        (CitationConstant) SIS
     };
 
+    static {  // Must be after CITATIONS array construction.
+        SystemListener.add(new SystemListener(Modules.METADATA) {
+            @Override protected void classpathChanged() {refresh();}
+            @Override protected void databaseChanged()  {refresh();}
+        });
+    }
+
     /**
      * Do not allows instantiation of this class.
      */
@@ -213,37 +246,50 @@ public final class Citations extends Sta
     }
 
     /**
-     * Returns a citation of the given name. The method makes the following choice:
+     * Invoked when the content of the citation constants (title, responsible party, URL, <i>etc.</i>)
+     * may have changed. This method notifies all citations that they will need to refresh their content.
+     */
+    static void refresh() {
+        for (final CitationConstant citation : CITATIONS) {
+            citation.refresh();
+        }
+    }
+
+    /**
+     * Returns a citation of the given identifier. The method makes the following choice:
      *
      * <ul>
      *   <li>If the given title is {@code null} or empty (ignoring spaces), then this method returns {@code null}.</li>
-     *   <li>Otherwise if the given name matches a {@linkplain DefaultCitation#getTitle() title} or an
-     *       {@linkplain DefaultCitation#getAlternateTitles() alternate titles} of one of the pre-defined
-     *       constants ({@link #EPSG}, {@link #GEOTIFF}, <i>etc.</i>), then that constant is returned.</li>
+     *   <li>Otherwise if the given string matches an {@linkplain DefaultCitation#getIdentifiers() identifier} of one of
+     *       the pre-defined constants ({@link #EPSG}, {@link #GEOTIFF}, <i>etc.</i>), then that constant is returned.</li>
      *   <li>Otherwise, a new citation is created with the specified name as the title.</li>
      * </ul>
      *
-     * @param  title The citation title (or alternate title), or {@code null}.
+     * @param  identifier The citation title (or alternate title), or {@code null}.
      * @return A citation using the specified name, or {@code null} if the given title is null or empty.
      */
-    public static Citation fromName(String title) {
-        if (title == null || ((title = CharSequences.trimWhitespaces(title)).isEmpty())) {
+    public static Citation fromName(String identifier) {
+        if (identifier == null || ((identifier = CharSequences.trimWhitespaces(identifier)).isEmpty())) {
             return null;
         }
-        /*
-         * We perform a special check because it is our only IdentifierSpace having an namespace ("EPSG")
-         * that can not be inferred from the authority abbreviation ("IOGP"). We test this special case
-         * first because it is usually to be the most frequently used citation.
-         */
-        if (title.equalsIgnoreCase(Constants.EPSG)) {
-            return EPSG;
-        }
-        for (final Citation citation : CITATIONS) {
-            if (titleMatches(citation, title)) {
+        for (final CitationConstant citation : CITATIONS) {
+            if (equalsFiltered(identifier, citation.title)) {
                 return citation;
             }
         }
-        return new SimpleCitation(title);
+        /*
+         * Additional identifiers other than the ones declared to CitationConstant constructors. Those identifiers
+         * shall be the same than the ones added by 'ServicesForUtility.createCitation(String)'.
+         */
+        if (equalsFiltered(identifier, ServicesForUtility.OGP)) {
+            return OGP;
+        }
+        /*
+         * If we found no match, org.apache.sis.internal.metadata.ServicesForUtility expects the default citation
+         * to be of this exact class: SimpleCitation (not a subclass). If the type of citation created below is
+         * modified, then we need to review ServicesForUtility.getCitationConstant(String) method body.
+         */
+        return new SimpleCitation(identifier);
     }
 
     /**
@@ -305,8 +351,10 @@ public final class Citations extends Sta
      *
      * <p>If (and <em>only</em> if) the citation does not contain any identifier, then this method
      * fallback on titles comparison using the {@link #titleMatches(Citation,String) titleMatches}
-     * method. This fallback exists for compatibility with client codes using citation
-     * {@linkplain DefaultCitation#getTitle() title} without identifiers.</p>
+     * method. This fallback exists for compatibility with citations using
+     * {@linkplain DefaultCitation#getTitle() title} and
+     * {@linkplain DefaultCitation#getAlternateTitles() alternate titles} (often abbreviations)
+     * without identifiers.</p>
      *
      * @param  citation The citation to check for, or {@code null}.
      * @param  identifier The identifier to compare, or {@code null}.
@@ -318,24 +366,30 @@ public final class Citations extends Sta
 
     /**
      * Infers an identifier from the given citation, or returns {@code null} if no identifier has been found.
-     * This method is useful for extracting a short designation of an authority (e.g. {@code "IOGP"})
+     * This method is useful for extracting a short designation of an authority (e.g. {@code "EPSG"})
      * for display purpose. This method performs the following choices:
      *
      * <ul>
      *   <li>If the given citation is {@code null}, then this method returns {@code null}.</li>
-     *   <li>Otherwise if the citation contains at least one {@linkplain DefaultCitation#getIdentifiers() identifier}, then:
+     *   <li>Otherwise if the citation contains at least one
+     *       non-{@linkplain org.apache.sis.util.Deprecable#isDeprecated() deprecated}
+     *       {@linkplain DefaultCitation#getIdentifiers() identifier}, then:
      *     <ul>
-     *       <li>If at least one identifier is a {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier
-     *           unicode identifier}, then the shortest of those identifiers is returned.</li>
-     *       <li>Otherwise the shortest identifier is returned, despite not being a Unicode identifier.</li>
-     *     </ul></li>
+     *       <li>If at least one non-deprecated identifier is a
+     *           {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier unicode identifier},
+     *           then the shortest of those identifiers is returned.</li>
+     *       <li>Otherwise the shortest non-deprecated identifier is returned,
+     *           despite not being a Unicode identifier.</li>
+     *     </ul>
+     *   </li>
      *   <li>Otherwise if the citation contains at least one {@linkplain DefaultCitation#getTitle() title} or
      *       {@linkplain DefaultCitation#getAlternateTitles() alternate title}, then:
      *     <ul>
      *       <li>If at least one title is a {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier
      *           unicode identifier}, then the shortest of those titles is returned.</li>
      *       <li>Otherwise the shortest title is returned, despite not being a Unicode identifier.</li>
-     *     </ul></li>
+     *     </ul>
+     *   </li>
      *   <li>Otherwise this method returns {@code null}.</li>
      * </ul>
      *
@@ -361,7 +415,7 @@ public final class Citations extends Sta
 
     /**
      * Infers a valid Unicode identifier from the given citation, or returns {@code null} if none.
-     * This method is useful for extracting a short designation of an authority (e.g. {@code "IOGP"})
+     * This method is useful for extracting a short designation of an authority (e.g. {@code "EPSG"})
      * for processing purpose. This method performs the following actions:
      *
      * <ul>

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java [UTF-8] Thu May 28 16:51:05 2015
@@ -91,26 +91,6 @@ public class DefaultCitation extends ISO
     private static final long serialVersionUID = -7343644724857519090L;
 
     /**
-     * The authority for International Standard Book Number.
-     *
-     * <div class="note"><b>Implementation note:</b> This field is read by reflection in
-     * {@link org.apache.sis.internal.jaxb.NonMarshalledAuthority#getCitation(String)}.
-     * If this field is renamed or moved, then {@code NonMarshalledAuthority} needs
-     * to be updated.</div>
-     */
-    static final IdentifierSpace<String> ISBN = new NonMarshalledAuthority<>("ISBN", NonMarshalledAuthority.ISBN);
-
-    /**
-     * The authority for International Standard Serial Number.
-     *
-     * <div class="note"><b>Implementation note:</b> This field is read by reflection in
-     * {@link org.apache.sis.internal.jaxb.NonMarshalledAuthority#getCitation(String)}.
-     * If this field is renamed or moved, then {@code NonMarshalledAuthority} needs
-     * to be updated.</div>
-     */
-    static final IdentifierSpace<String> ISSN = new NonMarshalledAuthority<>("ISSN", NonMarshalledAuthority.ISSN);
-
-    /**
      * Name by which the cited resource is known.
      */
     private InternationalString title;
@@ -256,8 +236,8 @@ public class DefaultCitation extends ISO
             final String id2        = object.getISSN();
             if (id1 != null || id2 != null) {
                 final IdentifierMap map = super.getIdentifierMap();
-                if (id1 != null) map.putSpecialized(ISBN, id1);
-                if (id2 != null) map.putSpecialized(ISSN, id2);
+                if (id1 != null) map.putSpecialized(Citations.ISBN, id1);
+                if (id2 != null) map.putSpecialized(Citations.ISSN, id2);
             }
         }
     }
@@ -568,7 +548,7 @@ public class DefaultCitation extends ISO
     @Override
     @XmlElement(name = "ISBN")
     public String getISBN() {
-        return isNullOrEmpty(identifiers) ? null : getIdentifierMap().get(ISBN);
+        return isNullOrEmpty(identifiers) ? null : getIdentifierMap().get(Citations.ISBN);
     }
 
     /**
@@ -587,7 +567,7 @@ public class DefaultCitation extends ISO
     public void setISBN(final String newValue) {
         checkWritePermission();
         if (newValue != null || !isNullOrEmpty(identifiers)) {
-            getIdentifierMap().putSpecialized(ISBN, newValue);
+            getIdentifierMap().putSpecialized(Citations.ISBN, newValue);
         }
     }
 
@@ -607,7 +587,7 @@ public class DefaultCitation extends ISO
     @Override
     @XmlElement(name = "ISSN")
     public String getISSN() {
-        return isNullOrEmpty(identifiers) ? null : getIdentifierMap().get(ISSN);
+        return isNullOrEmpty(identifiers) ? null : getIdentifierMap().get(Citations.ISSN);
     }
 
     /**
@@ -626,7 +606,7 @@ public class DefaultCitation extends ISO
     public void setISSN(final String newValue) {
         checkWritePermission();
         if (newValue != null || !isNullOrEmpty(identifiers)) {
-            getIdentifierMap().putSpecialized(ISSN, newValue);
+            getIdentifierMap().putSpecialized(Citations.ISSN, newValue);
         }
     }
 

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -227,7 +227,7 @@ public final strictfp class MetadataStan
         final Map<String,Object> map = MetadataStandard.ISO_19115.asValueMap(instance,
                 KeyNamePolicy.JAVABEANS_PROPERTY, ValueExistencePolicy.NON_EMPTY);
         assertFalse("The properties map shall not be empty.", map.isEmpty());
-        assertEquals("Unexpected number of properties.", 5, map.size());
+        assertEquals("Unexpected number of properties.", 4, map.size());
         /*
          * Verify the set of keys in the ValueMap.
          *
@@ -236,7 +236,7 @@ public final strictfp class MetadataStan
          * PropertyAccessorTest.testConstructor().
          */
         final Set<String> keys = map.keySet();
-        assertEquals("[title, alternateTitles, identifiers, citedResponsibleParties, presentationForms]", keys.toString());
+        assertEquals("[title, identifiers, citedResponsibleParties, presentationForms]", keys.toString());
         assertTrue  ("Shall exist and be defined.",   keys.contains("title"));
         assertTrue  ("Shall exist and be defined.",   keys.contains("getTitle"));
         assertTrue  ("Shall exist and be defined.",   keys.contains("identifier"));
@@ -249,8 +249,8 @@ public final strictfp class MetadataStan
         /*
          * Verifies values.
          */
-        assertEquals("title", "European Petroleum Survey Group", map.get("title").toString());
-        assertEquals("title", "European Petroleum Survey Group", map.get("getTitle").toString());
+        assertEquals("title", "EPSG Geodetic Parameter Dataset", map.get("title").toString());
+        assertEquals("title", "EPSG Geodetic Parameter Dataset", map.get("getTitle").toString());
         final Object identifiers = map.get("identifiers");
         assertInstanceOf("identifiers", Collection.class, identifiers);
         assertContainsIdentifierCode("EPSG", (Collection<?>) identifiers);

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -114,7 +114,7 @@ public final strictfp class PrunerTest e
         /*
          * Set a non-empty metadata info.
          */
-        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "A file identifiers"));
+        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "A file identifiers", false));
         assertTrue ("GeographicBoundingBox", bbox.isEmpty());
         assertTrue ("Extent",                extent.isEmpty());
         assertTrue ("Scale",                 scale.isEmpty());
@@ -142,7 +142,7 @@ public final strictfp class PrunerTest e
          * Set an empty string in an element.
          */
         scale.setScale(Double.NaN);
-        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "   "));
+        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "   ", false));
         assertTrue("Scale",                 scale.isEmpty());
         assertTrue("DataIdentification",    identification.isEmpty());
         assertTrue("Metadata",              metadata.isEmpty());
@@ -176,7 +176,7 @@ public final strictfp class PrunerTest e
     @Test
     @DependsOnMethod("testIsEmpty")
     public void testPrune() {
-        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "A file identifiers"));
+        metadata.setMetadataIdentifier(new SimpleIdentifier(null, "A file identifiers", false));
         identification.setCitation(new DefaultCitation("A citation title"));
         assertFalse(isNullOrEmpty(metadata.getMetadataIdentifier()));
         assertFalse(isNullOrEmpty(identification.getCitation()));
@@ -193,7 +193,7 @@ public final strictfp class PrunerTest e
         assertEquals(0, extent.getGeographicElements().size());
         assertFalse(metadata.isEmpty());
 
-        metadata.setMetadataIdentifier(new SimpleIdentifier(null, " "));
+        metadata.setMetadataIdentifier(new SimpleIdentifier(null, " ", false));
         identification.setCitation(new DefaultCitation(" "));
         assertNotNull(metadata.getMetadataIdentifier());
         metadata.prune();

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -110,7 +110,8 @@ public final strictfp class TreeTableFor
             "  ├─Identifier\n" +
             "  │   ├─Code……………………………………………………………… 9782505004509\n" +
             "  │   ├─Authority\n" +
-            "  │   │   └─Title………………………………………………… ISBN\n" +
+            "  │   │   ├─Title………………………………………………… International Standard Book Number\n" +
+            "  │   │   └─Alternate title……………………… ISBN\n" +
             "  │   └─Code space……………………………………………… ISBN\n"+
             "  ├─Cited responsible party (1 of 2)\n" +
             "  │   ├─Party\n" +

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/ImmutableIdentifierTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -22,8 +22,8 @@ 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.internal.simple.SimpleCitation;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.test.DependsOnMethod;
@@ -179,7 +179,14 @@ public final strictfp class ImmutableIde
      */
     @Test
     public void testWKT() {
-        final ImmutableIdentifier id = new ImmutableIdentifier(HardCodedCitations.IOGP, "EPSG", "4326", "8.2", null);
+        ImmutableIdentifier id = new ImmutableIdentifier(Citations.EPSG, "EPSG", "4326", "8.2", null);
+        assertWktEquals(Convention.WKT2, "Id[“EPSG”, 4326, “8.2”]", id);
+        assertWktEquals(Convention.WKT1, "AUTHORITY[“EPSG”, “4326”]", id);
+        /*
+         * Same identifier, but with an authority different than the EPSG one.
+         * The Citation element should then be visible in WKT 2.
+         */
+        id = new ImmutableIdentifier(new SimpleCitation("IOGP"), "EPSG", "4326", "8.2", null);
         assertWktEquals(Convention.WKT2, "Id[“EPSG”, 4326, “8.2”, Citation[“IOGP”]]", id);
         assertWktEquals(Convention.WKT1, "AUTHORITY[“EPSG”, “4326”]", id);
     }

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -16,12 +16,18 @@
  */
 package org.apache.sis.metadata.iso.citation;
 
+import java.util.Locale;
+import java.lang.reflect.Field;
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
 import org.apache.sis.internal.util.Constants;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.apache.sis.metadata.iso.citation.Citations.*;
-import static org.junit.Assert.assertSame;
+import static org.apache.sis.test.Assert.*;
 
 
 /**
@@ -35,13 +41,16 @@ import static org.junit.Assert.assertSam
 public final strictfp class CitationsTest extends TestCase {
     /**
      * Tests {@link Citations#fromName(String)}.
+     *
+     * @throws IllegalAccessException should never happen since we asked only for public fields.
      */
     @Test
-    public void testFromName() {
+    public void testFromName() throws IllegalAccessException {
         assertSame(ISO,      fromName("ISO"));
         assertSame(OGC,      fromName(Constants.OGC));
-        assertSame(EPSG,     fromName(Constants.EPSG));  // This one is important.
-        assertSame(EPSG,     fromName(Constants.IOGP));  // This one is not really needed (and maybe not strictly correct).
+        assertSame(EPSG,     fromName(Constants.EPSG));  // This one is most important.
+        assertSame(OGP,      fromName(Constants.IOGP));  // For parsing GML "codeSpace" attribute.
+        assertSame(OGP,      fromName("OGP"));           // Sometime seen in GML instead of "IOGP".
         assertSame(SIS,      fromName(Constants.SIS));
         assertSame(ESRI,     fromName("ESRI"));
         assertSame(ORACLE,   fromName("Oracle"));
@@ -54,5 +63,133 @@ public final strictfp class CitationsTes
         assertSame(S57,      fromName("S57"));
         assertSame(ISBN,     fromName("ISBN"));
         assertSame(ISSN,     fromName("ISSN"));
+        /*
+         * Verify again, but using reflection for making sure that the field names
+         * are consistent and that we did not forgot any citation constant.
+         */
+        for (final Field field : Citations.class.getFields()) {
+            if (Citation.class.isAssignableFrom(field.getType())) {
+                final String name = field.getName();
+                assertSame(name, field.get(null), Citations.fromName(name));
+            }
+        }
+    }
+
+    /**
+     * Tests {@link Citations#getIdentifier(Citation)} on the constants declared in the {@link Citations} class.
+     * The values do not need to be valid Unicode identifiers.
+     */
+    @Test
+    public void testGetIdentifier() {
+        assertEquals("ISO",     getIdentifier(ISO));
+        assertEquals("OGC",     getIdentifier(OGC));
+        assertEquals("IOGP",    getIdentifier(OGP));
+        assertEquals("EPSG",    getIdentifier(EPSG));
+        assertEquals("SIS",     getIdentifier(SIS));
+        assertEquals("ESRI",    getIdentifier(ESRI));
+        assertEquals("Oracle",  getIdentifier(ORACLE));
+        assertEquals("NetCDF",  getIdentifier(NETCDF));
+        assertEquals("GeoTIFF", getIdentifier(GEOTIFF));
+        assertEquals("MapInfo", getIdentifier(MAP_INFO));
+        assertEquals("ISBN",    getIdentifier(ISBN));
+        assertEquals("ISSN",    getIdentifier(ISSN));
+        assertEquals("Proj.4",  getIdentifier(PROJ4));  // Not a valid Unicode identifier.
+        assertEquals("S-57",    getIdentifier(S57));    // Not a valid Unicode identifier.
+    }
+
+    /**
+     * Tests {@link Citations#getUnicodeIdentifier(Citation)} on the constants declared in the {@link Citations} class.
+     * All values shall be valid Unicode identifiers or {@code null}.
+     */
+    @Test
+    @DependsOnMethod("testGetIdentifier")
+    public void testGetUnicodeIdentifier() {
+        assertEquals("ISO",     getUnicodeIdentifier(ISO));
+        assertEquals("OGC",     getUnicodeIdentifier(OGC));
+        assertEquals("IOGP",    getUnicodeIdentifier(OGP));
+        assertEquals("EPSG",    getUnicodeIdentifier(EPSG));
+        assertEquals("SIS",     getUnicodeIdentifier(SIS));
+        assertEquals("ESRI",    getUnicodeIdentifier(ESRI));
+        assertEquals("Oracle",  getUnicodeIdentifier(ORACLE));
+        assertEquals("NetCDF",  getUnicodeIdentifier(NETCDF));
+        assertEquals("GeoTIFF", getUnicodeIdentifier(GEOTIFF));
+        assertEquals("MapInfo", getUnicodeIdentifier(MAP_INFO));
+        assertEquals("ISBN",    getUnicodeIdentifier(ISBN));
+        assertEquals("ISSN",    getUnicodeIdentifier(ISSN));
+        assertNull  ("Proj4",   getUnicodeIdentifier(PROJ4));   // Not yet publicly declared as an identifier.
+        assertNull  ("S57",     getUnicodeIdentifier(S57));     // Not yet publicly declared as an identifier.
+    }
+
+    /**
+     * Tests {@link org.apache.sis.internal.util.Citations#getCodeSpace(Citation)} on the constants
+     * declared in the {@link Citations} class.
+     */
+    @Test
+    @DependsOnMethod("testGetUnicodeIdentifier")
+    public void testGetCodeSpace() {
+        assertEquals("ISO",     org.apache.sis.internal.util.Citations.getCodeSpace(ISO));
+        assertEquals("OGC",     org.apache.sis.internal.util.Citations.getCodeSpace(OGC));
+        assertEquals("IOGP",    org.apache.sis.internal.util.Citations.getCodeSpace(OGP));
+        assertEquals("EPSG",    org.apache.sis.internal.util.Citations.getCodeSpace(EPSG));
+        assertEquals("SIS",     org.apache.sis.internal.util.Citations.getCodeSpace(SIS));
+        assertEquals("ESRI",    org.apache.sis.internal.util.Citations.getCodeSpace(ESRI));
+        assertEquals("Oracle",  org.apache.sis.internal.util.Citations.getCodeSpace(ORACLE));
+        assertEquals("NetCDF",  org.apache.sis.internal.util.Citations.getCodeSpace(NETCDF));
+        assertEquals("GeoTIFF", org.apache.sis.internal.util.Citations.getCodeSpace(GEOTIFF));
+        assertEquals("MapInfo", org.apache.sis.internal.util.Citations.getCodeSpace(MAP_INFO));
+        assertEquals("ISBN",    org.apache.sis.internal.util.Citations.getCodeSpace(ISBN));
+        assertEquals("ISSN",    org.apache.sis.internal.util.Citations.getCodeSpace(ISSN));
+        assertEquals("Proj4",   org.apache.sis.internal.util.Citations.getCodeSpace(PROJ4));
+        assertEquals("S57",     org.apache.sis.internal.util.Citations.getCodeSpace(S57));
+    }
+
+    /**
+     * Tests {@code getTitle()} on some {@code Citation} constants.
+     */
+    @Test
+    public void testGetTitles() {
+        assertEquals("International Organization for Standardization",    ISO    .getTitle().toString(Locale.US));
+        assertEquals("Open Geospatial Consortium",                        OGC    .getTitle().toString(Locale.US));
+        assertEquals("International Association of Oil & Gas producers",  OGP    .getTitle().toString(Locale.US));
+        assertEquals("EPSG Geodetic Parameter Dataset",                   EPSG   .getTitle().toString(Locale.US));
+        assertEquals("Apache Spatial Information System",                 SIS    .getTitle().toString(Locale.US));
+        assertEquals("International Standard Book Number",                ISBN   .getTitle().toString(Locale.US));
+        assertEquals("International Standard Serial Number",              ISSN   .getTitle().toString(Locale.US));
+        assertEquals("GeoTIFF",                                           GEOTIFF.getTitle().toString(Locale.US));
+        assertEquals("NetCDF",                                            NETCDF .getTitle().toString(Locale.US));
+        assertEquals("Proj.4",                                            PROJ4  .getTitle().toString(Locale.US));
+        assertEquals("S-57",                                              S57    .getTitle().toString(Locale.US));
+    }
+
+    /**
+     * Special tests dedicated to the {@link Citations#EPSG} constant. This is maybe the most important
+     * citation declared in the {@link Citations} class, since it is declared as the authority of almost
+     * all Coordinate Reference System (CRS) objects typically used by SIS.
+     *
+     * <p>Apache SIS identifies the EPSG authority with {@link Identifier} {@code "IOGP:EPSG"}.</p>
+     */
+    @Test
+    public void testEPSG() {
+        final Identifier identifier = TestUtilities.getSingleton(EPSG.getIdentifiers());
+        assertEquals("IOGP", getUnicodeIdentifier(identifier.getAuthority()));
+        assertEquals("EPSG", getUnicodeIdentifier(EPSG));
+        assertEquals("IOGP", identifier.getCodeSpace());
+        assertEquals("EPSG", identifier.getCode());
+    }
+
+    /**
+     * Test serialization.
+     *
+     * @throws IllegalAccessException should never happen since we asked only for public fields.
+     */
+    @Test
+    @DependsOnMethod("testFromName")
+    public void testSerialization() throws IllegalAccessException {
+        for (final Field field : Citations.class.getFields()) {
+            if (Citation.class.isAssignableFrom(field.getType())) {
+                final Object c = field.get(null);
+                assertSame(field.getName(), c, assertSerializedEquals(c));
+            }
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -59,8 +59,8 @@ public final strictfp class DefaultCitat
          */
         assertNull("ISSN shall be initially null.", citation.getISSN());
         citation.setIdentifiers(Arrays.asList(
-                new DefaultIdentifier(HardCodedCitations.OGC,  "MyOGC"),
-                new DefaultIdentifier(HardCodedCitations.EPSG, "MyEPSG"),
+                new DefaultIdentifier(Citations.OGC,  "MyOGC"),
+                new DefaultIdentifier(Citations.EPSG, "MyEPSG"),
                 new DefaultIdentifier(Citations.ISBN, "MyIgnored"),
                 new DefaultIdentifier(Citations.ISSN, "MyISSN")));
 

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java [UTF-8] Thu May 28 16:51:05 2015
@@ -38,27 +38,11 @@ import static java.util.Collections.sing
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.6
  * @module
  */
 public final strictfp class HardCodedCitations extends Static {
     /**
-     * The <a href="http://www.opengeospatial.org">Open Geospatial consortium</a> organization.
-     * "Open Geospatial consortium" is the new name for "OpenGIS consortium".
-     * An {@linkplain Citation#getAlternateTitles() alternate title} for this citation is "OGC"
-     * (according ISO 19115, alternate titles often contain abbreviations).
-     */
-    public static final DefaultCitation OGC;
-    static {
-        final DefaultCitation c = new DefaultCitation("Open Geospatial consortium");
-        c.setAlternateTitles(singleton(new SimpleInternationalString(Constants.OGC)));
-        c.setPresentationForms(singleton(PresentationForm.DOCUMENT_DIGITAL));
-        c.setIdentifiers(singleton(new DefaultIdentifier(Constants.OGC)));
-        c.freeze();
-        OGC = c;
-    }
-
-    /**
      * The <a href="http://www.iso.org/">International Organization for Standardization</a>
      * organization. An {@linkplain Citation#getAlternateTitles() alternate title} for this
      * citation is "ISO" (according ISO 19115, alternate titles often contain abbreviations).
@@ -85,32 +69,14 @@ public final strictfp class HardCodedCit
     }
 
     /**
-     * The <a href="http://www.iogp.org">International Association of Oil &amp; Gas Producers</a> organization.
-     * This organization is responsible for maintainance of {@link #EPSG} database.
-     * An {@linkplain Citation#getAlternateTitles() alternate title} for this citation is "IOGP"
-     * (according ISO 19115, alternate titles often contain abbreviations).
-     */
-    public static final DefaultCitation IOGP;
-    static {
-        final DefaultCitation c = new DefaultCitation("International Association of Oil & Gas Producers");
-        c.setAlternateTitles(singleton(new SimpleInternationalString(Constants.IOGP)));
-        c.setIdentifiers(singleton(new DefaultIdentifier(Constants.IOGP)));
-        c.freeze();
-        IOGP = c;
-    }
-
-    /**
-     * The <a href="http://www.epsg.org">European Petroleum Survey Group</a> authority.
-     * An {@linkplain Citation#getAlternateTitles() alternate title} for this citation is "EPSG"
-     * (according ISO 19115, alternate titles often contain abbreviations). In addition,
-     * this citation contains the "EPSG" {@linkplain Citation#getIdentifiers() identifier}.
+     * The <a href="http://www.epsg.org">EPSG Geodetic Parameter Dataset</a> authority.
+     * This citation contains the "EPSG" {@linkplain Citation#getIdentifiers() identifier}.
      *
      * <p>String representation:</p>
      *
      * {@preformat text
      *   Citation
-     *     ├─Title………………………………………………………… European Petroleum Survey Group
-     *     ├─Alternate title……………………………… EPSG
+     *     ├─Title………………………………………………………… EPSG Geodetic Parameter Dataset
      *     ├─Identifier
      *     │   └─Code………………………………………………… EPSG
      *     ├─Cited responsible party
@@ -130,10 +96,9 @@ public final strictfp class HardCodedCit
         r.setFunction(OnLineFunction.INFORMATION);
 
         final DefaultResponsibility p = new DefaultResponsibility(Role.PRINCIPAL_INVESTIGATOR, null,
-                new DefaultOrganisation(IOGP.getTitle(), null, null, new DefaultContact(r)));
+                new DefaultOrganisation("International Association of Oil & Gas Producers", null, null, new DefaultContact(r)));
 
-        final DefaultCitation c = new DefaultCitation("European Petroleum Survey Group");
-        c.setAlternateTitles(singleton(new SimpleInternationalString("EPSG")));
+        final DefaultCitation c = new DefaultCitation("EPSG Geodetic Parameter Dataset");
         c.setPresentationForms(singleton(PresentationForm.TABLE_DIGITAL));
         c.setIdentifiers(singleton(new DefaultIdentifier(Constants.EPSG)));
         c.setCitedResponsibleParties(singleton(p));

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] Thu May 28 16:51:05 2015
@@ -21,12 +21,14 @@ import javax.xml.bind.annotation.XmlValu
 import javax.xml.bind.annotation.XmlAttribute;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
+import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.internal.metadata.NameMeaning;
+import org.apache.sis.internal.metadata.ServicesForUtility;
 import org.apache.sis.referencing.NamedIdentifier;
 import org.apache.sis.metadata.iso.citation.Citations;
 
-import static org.apache.sis.internal.util.Citations.getUnicodeIdentifier;
+import static org.apache.sis.internal.util.Citations.getCodeSpace;
 
 
 /**
@@ -36,7 +38,7 @@ import static org.apache.sis.internal.ut
  * @author  Cédric Briançon (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.6
  * @module
  */
 @XmlType(name = "CodeType")
@@ -103,11 +105,43 @@ public final class Code {
         String version = null, cs = codeSpace;
         final DefinitionURI parsed = DefinitionURI.parse(c);
         if (parsed != null) {
-            authority = Citations.fromName(cs); // May be null.
-            cs        = parsed.authority;
-            version   = parsed.version;
-            c         = parsed.code;
+            /*
+             * Case where the URN has been successfully parsed. The OGC's URN contains an "authority" component,
+             * which we take as the Identifier.codeSpace value (not Identifier.authority despite what the names
+             * would suggest).
+             *
+             * The GML document may also provide a 'codeSpace' attribute separated from the URN, which we take
+             * as the authority.  This is the opposite of what the names would suggest, but we can not map the
+             * 'codeSpace' attribute to Identifier.codeSpace  because the 'codeSpace' attribute value found in
+             * practice is often "IOGP" while the 'Identifier.description' example provided in ISO 19115-1 for
+             * an EPSG code has the "EPSG" codespace. Example:
+             *
+             *    - XML: <gml:identifier codeSpace="IOGP">urn:ogc:def:crs:EPSG::4326</gml:identifier>
+             *    - ISO: For "EPSG::4326", Identifier.codeSpace = "EPSG" and Identifier.code = "4326".
+             *
+             * Apache SIS attempts to organize this apparent contradiction by considering IOGP as the codespace of
+             * the EPSG codespace, but this interpretation is not likely to be widely used by libraries other than
+             * SIS. For now, a special handling is hard-coded below: if codeSpace = "IOGP" and authority = "EPSG",
+             * then we take the authority as the Citations.EPSG constant, which has a "IOGP:EPSG" identifier.
+             *
+             * A symmetrical special handling for EPSG is done in the 'forIdentifiedObject(…)' method of this class.
+             */
+            if (Constants.EPSG.equalsIgnoreCase(parsed.authority) &&
+               (Constants.IOGP.equalsIgnoreCase(cs) || ServicesForUtility.OGP.equalsIgnoreCase(cs)))
+            {
+                authority = Citations.EPSG;
+            } else {
+                authority = Citations.fromName(cs); // May be null.
+            }
+            cs      = parsed.authority;
+            version = parsed.version;
+            c       = parsed.code;
         } else if (cs != null) {
+            /*
+             * Case where the URN can not be parsed but a 'codeSpace' attribute exists. We take this 'codeSpace'
+             * as both the code space and the authority. As a special case, if there is a semi-colon, we take all
+             * text after that semi-color as the version number.
+             */
             final int s = cs.lastIndexOf(DefinitionURI.SEPARATOR);
             if (s >= 0) {
                 version = cs.substring(s+1);
@@ -124,7 +158,8 @@ public final class Code {
      * <ul>
      *   <li>The first identifier having a code that begin with {@code "urn:"}.</li>
      *   <li>The first identifier having a code that begin with {@code "http:"}.</li>
-     *   <li>The first identifier, converted to the {@code "urn:} syntax if possible.</li>
+     *   <li>The first identifier in the {@code "EPSG"} codespace, converted to the {@code "urn:} syntax.</li>
+     *   <li>The first identifier in other codespace, converted to the {@code "urn:} syntax if possible.</li>
      * </ul>
      *
      * @param  type The type of the identified object.
@@ -134,6 +169,7 @@ public final class Code {
     public static Code forIdentifiedObject(final Class<?> type, final Iterable<? extends Identifier> identifiers) {
         if (identifiers != null) {
             boolean isHTTP = false;
+            boolean isEPSG = false;
             Identifier fallback = null;
             for (final Identifier identifier : identifiers) {
                 final String code = identifier.getCode();
@@ -143,13 +179,18 @@ public final class Code {
                 }
                 if (!isHTTP) {
                     isHTTP = code.regionMatches(true, 0, "http:", 0, 5);
-                    if (isHTTP || fallback == null) {
+                    if (isHTTP) {
                         fallback = identifier;
+                    } else if (!isEPSG) {
+                        isEPSG = Constants.EPSG.equalsIgnoreCase(identifier.getCodeSpace());
+                        if (isEPSG || fallback == null) {
+                            fallback = identifier;
+                        }
                     }
                 }
             }
             /*
-             * If no "urn:" or "http:" form has been found, try to create a "urn:" form the first identifier.
+             * If no "urn:" or "http:" form has been found, try to create a "urn:" form from 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.
              */
@@ -159,15 +200,35 @@ public final class Code {
                     if (urn != null) {
                         final Code code = new Code();
                         /*
-                         * Really getUnicodeIdentifier(…) below, not getCodeSpace(…). The reason is that the
-                         * code space already appears in the URN string, and common usage found in GML files
-                         * is to use the "codeSpace" attribute for the authority ("OGP" or "IOGP" for objects
-                         * from the EPSG database). Consequently in the common case where the authority is our
-                         * Citations.EPSG constant, we really want the "IOGP" string rather than "EPSG".
+                         * Rational for EPSG special case below:
+                         * -------------------------------------
+                         * Apache SIS already formats the Identifier.getCodeSpace() value in the URN.
+                         * This value is "EPSG" for IdentifiedObject instances from the EPSG database.
+                         * But GML additionally have a "codeSpace" attribute, and common usage seems
+                         * to give the "OGP" or "IOGP" to that attribute as in the following example:
+                         *
+                         *     <gml:identifier codeSpace="IOGP">urn:ogc:def:crs:EPSG::4326</gml:identifier>
+                         *
+                         * A discussion can be found in the comments of https://issues.apache.org/jira/browse/SIS-196
+                         *
+                         * Where to take this "IOGP" value from? It is not the Identifier.getCodeSpace() String value
+                         * since ISO 19115-2 clearly uses the "EPSG" value in their example.  We could consider using
+                         * the Identifier.getAuthority() value, which is a Citation. But the "EPSG" part in above URN
+                         * is named "the authority" in URN specification, which suggest that Identifier.getAuthority()
+                         * should return a citation for the "EPSG Geodetic Parameter Dataset" rather than for the IOGP
+                         * organisation.
+                         *
+                         * Apache SIS declares IOGP as the codespace of the EPSG codespace. We could write below a code
+                         * which would go down to this deeper level in identifier hierarchy, but there is no indication
+                         * at this time that objects from other sources than SIS would follow such convention. For now
+                         * the relationship between EPSG and IOGP is hard-coded, but we could revisit this approach in
+                         * any future SIS version.
+                         *
+                         * A symmetrical special handling for EPSG is done in the 'getIdentifier()' method of this class.
                          *
-                         * See https://issues.apache.org/jira/browse/SIS-196
+                         * See https://issues.apache.org/jira/browse/SIS-199
                          */
-                        code.codeSpace = getUnicodeIdentifier(fallback.getAuthority());
+                        code.codeSpace = isEPSG ? Constants.IOGP : getCodeSpace(fallback.getAuthority());
                         code.code = urn;
                         return code;
                     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Thu May 28 16:51:05 2015
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.internal.referencing;
 
-import org.apache.sis.internal.metadata.WKTKeywords;
 import java.util.Iterator;
 import java.util.Collection;
 
@@ -50,6 +49,7 @@ import org.apache.sis.parameter.DefaultP
 import org.apache.sis.parameter.Parameterized;
 import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.io.wkt.FormattableObject;
+import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.metadata.iso.extent.DefaultExtent;
 import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent;
 import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/DeprecatedCode.java [UTF-8] Thu May 28 16:51:05 2015
@@ -24,9 +24,15 @@ import org.apache.sis.util.resources.Voc
 
 
 /**
- * An identifier for a deprecated identifier.
+ * An identifier which should not be used anymore.
  * This is used mostly for deprecated EPSG codes.
  *
+ * <div class="note"><b>Implementation note:</b>
+ * this class opportunistically recycle the {@linkplain #getDescription() description} property into a
+ * {@linkplain #getRemarks() remarks} property. This is a lazy way to inherit {@link #equals(Object)}
+ * and {@link #hashCode()} implementation without adding code in this class for taking in account a
+ * new field.</div>
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
  * @version 0.6
@@ -39,13 +45,6 @@ final class DeprecatedCode extends Immut
     private static final long serialVersionUID = 357222258307746767L;
 
     /**
-     * Information about the replacement for this identifier.
-     *
-     * @see #getRemarks()
-     */
-    private final InternationalString remarks;
-
-    /**
      * Creates a deprecated identifier.
      *
      * @param supersededBy The code that replace this one.
@@ -53,8 +52,8 @@ final class DeprecatedCode extends Immut
     DeprecatedCode(final Citation authority, final String codeSpace,
             final String code, final String version, final CharSequence supersededBy)
     {
-        super(authority, codeSpace, code, version, null);
-        remarks = Vocabulary.formatInternational(Vocabulary.Keys.SupersededBy_1, supersededBy);
+        super(authority, codeSpace, code, version,
+                Vocabulary.formatInternational(Vocabulary.Keys.SupersededBy_1, supersededBy));
     }
 
     /**
@@ -76,6 +75,17 @@ final class DeprecatedCode extends Immut
      */
     @Override
     public InternationalString getRemarks() {
-        return remarks;
+        return super.getDescription();
+    }
+
+    /**
+     * Returns {@code null}, since we used the description for the superseded information.
+     * See <cite>"Implementation note"</cite> in class javadoc.
+     *
+     * @return {@code null}.
+     */
+    @Override
+    public InternationalString getDescription() {
+        return null;
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/CodeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/CodeTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/CodeTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/CodeTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -20,9 +20,9 @@ import java.util.Collections;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.metadata.Identifier;
 import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.simple.SimpleCitation;
 import org.apache.sis.metadata.iso.ImmutableIdentifier;
 import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.metadata.iso.citation.HardCodedCitations;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -35,16 +35,20 @@ import static org.junit.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 public final strictfp class CodeTest extends TestCase {
     /**
      * Tests the {@link Code#Code(Identifier)} constructor with {@code "EPSG:4326"} identifier.
+     * This test intentionally uses an identifier with the {@code IOGP} authority instead than
+     * EPSG in order to make sure that the {@code codeSpace} attribute is set from
+     * {@link Identifier#getCodeSpace()}, not from {@link Identifier#getAuthority()}.
      */
     @Test
     public void testSimple() {
-        final Identifier id = new ImmutableIdentifier(HardCodedCitations.IOGP, "EPSG", "4326");
+        final SimpleCitation IOGP = new SimpleCitation("IOGP");
+        final Identifier id = new ImmutableIdentifier(IOGP, "EPSG", "4326");  // See above javadoc.
         final Code value = new Code(id);
         assertEquals("codeSpace", "EPSG", value.codeSpace);
         assertEquals("code",      "4326", value.code);
@@ -61,11 +65,14 @@ public final strictfp class CodeTest ext
 
     /**
      * Tests the {@link Code#Code(Identifier)} constructor with {@code "EPSG:8.3:4326"} identifier.
+     * This test intentionally uses an identifier with the {@code IOGP} authority instead than EPSG
+     * for the same reason than {@link #testSimple()}.
      */
     @Test
     @DependsOnMethod("testSimple")
     public void testWithVersion() {
-        final Identifier id = new ImmutableIdentifier(HardCodedCitations.IOGP, "EPSG", "4326", "8.2", null);
+        final SimpleCitation IOGP = new SimpleCitation("IOGP");
+        final Identifier id = new ImmutableIdentifier(IOGP, "EPSG", "4326", "8.2", null);  // See above javadoc.
         final Code value = new Code(id);
         assertEquals("codeSpace", "EPSG:8.2", value.codeSpace);
         assertEquals("code",      "4326",     value.code);
@@ -86,7 +93,7 @@ public final strictfp class CodeTest ext
     @Test
     @DependsOnMethod("testWithVersion")
     public void testForIdentifiedObject() {
-        final Identifier id = new ImmutableIdentifier(HardCodedCitations.IOGP, "EPSG", "4326", "8.2", null);
+        final Identifier id = new ImmutableIdentifier(Citations.EPSG, "EPSG", "4326", "8.2", null);
         final Code value = Code.forIdentifiedObject(GeographicCRS.class, Collections.singleton(id));
         assertNotNull(value);
         assertEquals("codeSpace", Constants.IOGP, value.codeSpace);
@@ -95,8 +102,8 @@ public final strictfp class CodeTest ext
 
     /**
      * Tests {@link Code#getIdentifier()} with {@code "urn:ogc:def:crs:EPSG:8.2:4326"}.
-     * This test simulate the {@code Code} object state that we get after
-     * XML unmarshalling of an object from the EPSG registry.
+     * This test simulates the {@code Code} object state that we get after XML unmarshalling
+     * of an object from the EPSG registry.
      */
     @Test
     @DependsOnMethod("testForIdentifiedObject")
@@ -105,7 +112,7 @@ public final strictfp class CodeTest ext
         value.codeSpace = "OGP";
         value.code = "urn:ogc:def:crs:EPSG:8.2:4326";
         final Identifier actual = value.getIdentifier();
-        assertSame  ("authority",  Citations.OGP, actual.getAuthority());
+        assertSame  ("authority",  Citations.EPSG, actual.getAuthority());
         assertEquals("codeSpace", "EPSG", actual.getCodeSpace());
         assertEquals("version",   "8.2",  actual.getVersion());
         assertEquals("code",      "4326", actual.getCode());

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AffineTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -83,7 +83,7 @@ public final strictfp class AffineTest e
         final Matrix matrix = Matrices.createDiagonal(3, 3);
         assertWktEquals(
                 "ParameterGroup[“Affine parametric transformation”," +
-                " Id[“EPSG”, 9624, Citation[“IOGP”]]]", Affine.parameters(matrix));
+                " Id[“EPSG”, 9624]]", Affine.parameters(matrix));
         /*
          * Try arbitrary values.
          */
@@ -95,7 +95,7 @@ public final strictfp class AffineTest e
                 "  Parameter[“A1”, 2.0, Id[“EPSG”, 8624]],\n"  +
                 "  Parameter[“B1”, 0.0, Id[“EPSG”, 8640]],\n" +
                 "  Parameter[“B2”, -1.0, Id[“EPSG”, 8641]],\n" +
-                "  Id[“EPSG”, 9624, Citation[“IOGP”]]]", Affine.parameters(matrix));
+                "  Id[“EPSG”, 9624]]", Affine.parameters(matrix));
         /*
          * Setting a value on the last row make the matrix non-affine.
          * So it should not be anymore EPSG:9624.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java?rev=1682276&r1=1682275&r2=1682276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java [UTF-8] Thu May 28 16:51:05 2015
@@ -203,7 +203,7 @@ public final strictfp class DefaultParam
          * but is reproduced here for easier comparison with the test following it.
          */
         final DefaultParameterDescriptor<Double> descriptor = DefaultParameterDescriptorTest.createEPSG("A0", Constants.A0);
-        assertWktEquals("Parameter[“A0”, Id[“EPSG”, 8623, Citation[“IOGP”], URI[“urn:ogc:def:parameter:EPSG::8623”]]]", descriptor);
+        assertWktEquals("Parameter[“A0”, Id[“EPSG”, 8623, URI[“urn:ogc:def:parameter:EPSG::8623”]]]", descriptor);
         /*
          * When the parameter is part of a larger element, we expect a simplification.
          * Here, the URI should be omitted because it is a long value which does not
@@ -212,7 +212,7 @@ public final strictfp class DefaultParam
         final DefaultParameterDescriptorGroup group = new DefaultParameterDescriptorGroup(
                 Collections.singletonMap(NAME_KEY, "Affine"), 1, 1, descriptor);
         assertWktEquals("ParameterGroup[“Affine”,\n" +
-                        "  Parameter[“A0”, Id[“EPSG”, 8623, Citation[“IOGP”]]]]", group);
+                        "  Parameter[“A0”, Id[“EPSG”, 8623]]]", group);
     }
 
     /**