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/10/08 18:10:06 UTC

svn commit: r1707577 [1/2] - in /sis/branches/JDK6: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/ ...

Author: desruisseaux
Date: Thu Oct  8 16:10:05 2015
New Revision: 1707577

URL: http://svn.apache.org/viewvc?rev=1707577&view=rev
Log:
Merge the support of xlink:href from the JDK7 branch.

Added:
    sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/citation/
      - copied from r1707575, sis/branches/JDK7/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/citation/
    sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/parameter/DuplicatedParameters.xml
      - copied unchanged from r1707575, sis/branches/JDK7/core/sis-referencing/src/test/resources/org/apache/sis/parameter/DuplicatedParameters.xml
Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/package-info.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java
    sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml
    sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy.xml
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/parameter/ParameterValueGroup.xml
    sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/crs/ProjectedCRS.xml
    sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Conversion.xml
    sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Transformation.xml
    sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/GMLAdapter.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/package-info.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/iso/RecordDefinition.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/logging/package-info.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/xml/XLink.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/xml/package-info.java
    sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/jaxb/gco/StringAdapterTest.java

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Oct  8 16:10:05 2015
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
-/sis/branches/JDK7:1394913-1707296
-/sis/branches/JDK8:1584960-1707295
+/sis/branches/JDK7:1394913-1707575
+/sis/branches/JDK8:1584960-1707574
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataUtilities.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -18,11 +18,15 @@ package org.apache.sis.internal.metadata
 
 import java.util.Date;
 import org.apache.sis.xml.NilReason;
+import org.apache.sis.xml.IdentifierSpace;
+import org.apache.sis.xml.IdentifiedObject;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.metadata.InvalidMetadataException;
 import org.apache.sis.internal.jaxb.PrimitiveTypeProperties;
 import org.apache.sis.internal.jaxb.Context;
+import org.apache.sis.internal.util.Utilities;
 
 
 /**
@@ -30,7 +34,7 @@ import org.apache.sis.internal.jaxb.Cont
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.6
+ * @version 0.7
  * @module
  */
 public final class MetadataUtilities extends Static {
@@ -170,4 +174,58 @@ public final class MetadataUtilities ext
             return null;
         }
     }
+
+    /**
+     * Returns the {@code gco:id} or {@code gml:id} value to use for the given object.
+     * The returned identifier will be unique in the current XML document.
+     *
+     * @param  object The object for which to get the unique identifier.
+     * @return The unique XML identifier, or {@code null} if none.
+     *
+     * @since 0.7
+     */
+    public static String getObjectID(final IdentifiedObject object) {
+        final Context context = Context.current();
+        String id = Context.getObjectID(context, object);
+        if (id == null) {
+            id = object.getIdentifierMap().getSpecialized(IdentifierSpace.ID);
+            if (id != null) {
+                final StringBuilder buffer = new StringBuilder();
+                if (!Utilities.appendUnicodeIdentifier(buffer, (char) 0, id, ":-", false)) {
+                    return null;
+                }
+                id = buffer.toString();
+                if (!Context.setObjectForID(context, object, id)) {
+                    final int s = buffer.append('-').length();
+                    int n = 0;
+                    do {
+                        if (++n == 100) return null;    //  Arbitrary limit.
+                        id = buffer.append(n).toString();
+                        buffer.setLength(s);
+                    } while (!Context.setObjectForID(context, object, id));
+                }
+            }
+        }
+        return id;
+    }
+
+    /**
+     * Invoked by {@code setID(String)} method implementations for assigning an identifier to an object
+     * at unmarshalling time.
+     *
+     * @param object The object for which to assign an identifier.
+     * @param id The {@code gco:id} or {@code gml:id} value.
+     *
+     * @since 0.7
+     */
+    public static void setObjectID(final IdentifiedObject object, String id) {
+        id = CharSequences.trimWhitespaces(id);
+        if (id != null && !id.isEmpty()) {
+            object.getIdentifierMap().putSpecialized(IdentifierSpace.ID, id);
+            final Context context = Context.current();
+            if (!Context.setObjectForID(context, object, id)) {
+                Context.warningOccured(context, object.getClass(), "setID", Errors.class, Errors.Keys.DuplicatedIdentifier_1, id);
+            }
+        }
+    }
 }

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/OtherLocales.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -147,28 +147,6 @@ public final class OtherLocales extends
     }
 
     /**
-     * Returns the first element of the given collection, or {@code null} if none.
-     * This method does not emit warning if more than one element is found.
-     * Consequently, this method should be used only when multi-occurrence is not ambiguous.
-     *
-     * <p><b>Note:</b> while defined in {@code OtherLocales} because the primary use for this method is to
-     * get the default locale, this method is also opportunistically used for other legacy properties.</p>
-     *
-     * @param  <T>    The type of elements in the collection.
-     * @param  values The collection from which to get the first element, or {@code null}.
-     * @return The first element found in the given collection, or {@code null}.
-     */
-    public static <T> T getFirst(final Collection<T> values) {
-        if (values != null) {
-            final Iterator<T> it = values.iterator();
-            if (it.hasNext()) {
-                return it.next();
-            }
-        }
-        return null;
-    }
-
-    /**
      * Sets the first element in the given collection to the given value.
      * Special cases:
      *
@@ -185,6 +163,8 @@ public final class OtherLocales extends
      * @param  values   The collection where to add the new value, or {@code null}.
      * @param  newValue The new value to set, or {@code null} for instead removing the first element.
      * @return The collection (may or may not be the given {@code values} collection).
+     *
+     * @see org.apache.sis.internal.util.CollectionsExt#first(Iterable)
      */
     public static <T> Collection<T> setFirst(Collection<T> values, final T newValue) {
         if (values == null) {

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -64,6 +64,7 @@ import org.apache.sis.metadata.iso.ident
 import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
 import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
 import org.apache.sis.internal.metadata.OtherLocales;
+import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.jaxb.code.PT_Locale;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.xml.Namespaces;
@@ -455,7 +456,7 @@ public class DefaultMetadata extends ISO
     @Deprecated
     @XmlElement(name = "language")
     public Locale getLanguage() {
-        return OtherLocales.getFirst(getLanguages());
+        return CollectionsExt.first(getLanguages());
         // No warning if the collection contains more than one locale, because
         // this is allowed by the "getLanguage() + getLocales()" contract.
     }
@@ -504,7 +505,7 @@ public class DefaultMetadata extends ISO
     @Deprecated
     public void setLocales(final Collection<? extends Locale> newValues) {
         checkWritePermission();
-        setLanguages(OtherLocales.merge(OtherLocales.getFirst(languages), newValues)); // See "Note about deprecated methods implementation"
+        setLanguages(OtherLocales.merge(CollectionsExt.first(languages), newValues)); // See "Note about deprecated methods implementation"
     }
 
     /**
@@ -1129,7 +1130,7 @@ public class DefaultMetadata extends ISO
         final URI uri = new URI(newValue);
         checkWritePermission();
         Collection<Identification> info = identificationInfo; // See "Note about deprecated methods implementation"
-        AbstractIdentification firstId = AbstractIdentification.castOrCopy(OtherLocales.getFirst(info));
+        AbstractIdentification firstId = AbstractIdentification.castOrCopy(CollectionsExt.first(info));
         if (firstId == null) {
             firstId = new DefaultDataIdentification();
         }
@@ -1138,7 +1139,7 @@ public class DefaultMetadata extends ISO
             citation = new DefaultCitation();
         }
         Collection<OnlineResource> onlineResources = citation.getOnlineResources();
-        DefaultOnlineResource firstOnline = DefaultOnlineResource.castOrCopy(OtherLocales.getFirst(onlineResources));
+        DefaultOnlineResource firstOnline = DefaultOnlineResource.castOrCopy(CollectionsExt.first(onlineResources));
         if (firstOnline == null) {
             firstOnline = new DefaultOnlineResource();
         }
@@ -1435,7 +1436,7 @@ public class DefaultMetadata extends ISO
      * This method sets the locale to be used for XML marshalling to the metadata language.
      */
     private void beforeMarshal(final Marshaller marshaller) {
-        Context.push(OtherLocales.getFirst(languages));
+        Context.push(CollectionsExt.first(languages));
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -31,9 +31,9 @@ import org.apache.sis.metadata.MetadataS
 import org.apache.sis.metadata.ModifiableMetadata;
 import org.apache.sis.internal.jaxb.IdentifierMapAdapter;
 import org.apache.sis.internal.jaxb.ModifiableIdentifierMap;
+import org.apache.sis.internal.metadata.MetadataUtilities;
 import org.apache.sis.internal.util.Utilities;
 import org.apache.sis.util.collection.Containers;
-import org.apache.sis.util.CharSequences;
 
 import static org.apache.sis.util.collection.Containers.isNullOrEmpty;
 
@@ -184,18 +184,15 @@ public class ISOMetadata extends Modifia
     @XmlAttribute  // Defined in "gco" as unqualified attribute.
     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
     private String getID() {
-        return isNullOrEmpty(identifiers) ? null : getIdentifierMap().getSpecialized(IdentifierSpace.ID);
+        return isNullOrEmpty(identifiers) ? null : MetadataUtilities.getObjectID(this);
     }
 
     /**
      * Sets an identifier unique for the XML document.
      * This method is invoked automatically by JAXB and should never be invoked explicitely.
      */
-    private void setID(String id) {
-        id = CharSequences.trimWhitespaces(id);
-        if (id != null && !id.isEmpty()) {
-            getIdentifierMap().putSpecialized(IdentifierSpace.ID, id);
-        }
+    private void setID(final String id) {
+        MetadataUtilities.setObjectID(this, id);
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/package-info.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/package-info.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/package-info.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -87,7 +87,7 @@
  * @author  Touraïvane (IRD)
  * @author  Cédric Briançon (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.7
  * @module
  */
 @XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED, namespace = Namespaces.GMD, xmlns = {

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultRepresentativeFraction.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -30,12 +30,12 @@ import org.apache.sis.metadata.Unmodifia
 import org.apache.sis.internal.jaxb.ModifiableIdentifierMap;
 import org.apache.sis.internal.jaxb.IdentifierMapAdapter;
 import org.apache.sis.internal.jaxb.gco.GO_Integer64;
+import org.apache.sis.internal.metadata.MetadataUtilities;
 import org.apache.sis.internal.util.CheckedArrayList;
 import org.apache.sis.measure.ValueRange;
 import org.apache.sis.xml.IdentifierMap;
 import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.xml.IdentifiedObject;
-import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Emptiable;
 import org.apache.sis.util.resources.Errors;
@@ -396,7 +396,7 @@ public class DefaultRepresentativeFracti
     @XmlAttribute  // Defined in "gco" as unqualified attribute.
     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
     private String getID() {
-        return isNullOrEmpty(identifiers) ? null : getIdentifierMap().getSpecialized(IdentifierSpace.ID);
+        return isNullOrEmpty(identifiers) ? null : MetadataUtilities.getObjectID(this);
     }
 
     /**
@@ -405,10 +405,7 @@ public class DefaultRepresentativeFracti
      * @see org.apache.sis.metadata.iso.ISOMetadata#setID(String)
      */
     private void setID(String id) {
-        id = CharSequences.trimWhitespaces(id);
-        if (id != null && !id.isEmpty()) {
-            getIdentifierMap().putSpecialized(IdentifierSpace.ID, id);
-        }
+        MetadataUtilities.setObjectID(this, id);
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -46,17 +46,10 @@ import static org.apache.sis.test.TestUt
 
 
 /**
- * Tests XML (un)marshalling of various metadata objects.
- * For every metadata objects tested by this class, the expected XML representation
- * is provided by {@code *.xml} files in the following directory:
+ * Tests {@link DefaultMetadata}, without Coordinate Reference System (CRS) information.
  *
- * <ul>
- *   <li>{@code "core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso"}</li>
- * </ul>
- *
- * Metadata tested by this class do not include Coordinate Reference System (CRS) information. A metadata
- * object with CRS information is tested by {@code org.apache.sis.test.integration.DefaultMetadataTest}
- * in the {@code sis-referencing} module.
+ * <p><b>Note:</b> a metadata object with CRS information is tested by a different
+ * {@code org.apache.sis.test.integration.DefaultMetadataTest} class in the {@code sis-referencing} module.</p>
  *
  * @author  Cédric Briançon (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)

Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -19,22 +19,30 @@ package org.apache.sis.metadata.iso.cita
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.Locale;
+import javax.xml.bind.JAXBException;
 import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.CitationDate;
+import org.opengis.metadata.citation.Contact;
+import org.opengis.metadata.citation.DateType;
+import org.opengis.metadata.citation.Party;
 import org.opengis.metadata.citation.Role;
 import org.opengis.metadata.citation.Responsibility;
 import org.opengis.metadata.citation.PresentationForm;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.xml.IdentifierMap;
+import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.metadata.iso.extent.Extents;
 import org.apache.sis.metadata.iso.DefaultIdentifier;
 import org.apache.sis.util.iso.SimpleInternationalString;
 import org.apache.sis.util.iso.DefaultInternationalString;
-import org.apache.sis.test.TestCase;
+import org.apache.sis.test.TestUtilities;
+import org.apache.sis.test.XMLTestCase;
 import org.junit.Test;
 
 import static org.apache.sis.test.TestUtilities.getSingleton;
-import static org.junit.Assert.*;
+import static org.apache.sis.test.MetadataAssert.*;
 
 
 /**
@@ -45,7 +53,12 @@ import static org.junit.Assert.*;
  * @version 0.7
  * @module
  */
-public final strictfp class DefaultCitationTest extends TestCase {
+public final strictfp class DefaultCitationTest extends XMLTestCase {
+    /**
+     * An XML file in this package containing a citation.
+     */
+    private static final String XML_FILE = "Citation.xml";
+
     /**
      * Creates a citation with an arbitrary title, presentation form and other properties.
      *
@@ -159,4 +172,62 @@ public final strictfp class DefaultCitat
             // This is the expected exception.
         }
     }
+
+    /**
+     * Tests XML marshalling using the format derived form ISO 19115:2003 model.
+     * This method also tests usage of {@code gml:id} and {@code xlink:href}.
+     *
+     * @throws JAXBException if an error occurred during marshalling.
+     *
+     * @since 0.7
+     */
+    @Test
+    public void testMarshalling() throws JAXBException {
+        final DefaultContact contact = new DefaultContact();
+        contact.setContactInstructions(new SimpleInternationalString("Send carrier pigeon."));
+        contact.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "ip-protocol");
+        final DefaultCitation c = new DefaultCitation("Fight against poverty");
+        c.setCitedResponsibleParties(Arrays.asList(
+                new DefaultResponsibility(Role.ORIGINATOR, null, new DefaultIndividual("Maid Marian", null, contact)),
+                new DefaultResponsibility(Role.FUNDER,     null, new DefaultIndividual("Robin Hood",  null, contact))
+        ));
+        c.getDates().add(new DefaultCitationDate(TestUtilities.date("2015-10-17 00:00:00"), DateType.ADOPTED));
+        assertMarshalEqualsFile(XML_FILE, c, "xlmns:*", "xsi:schemaLocation");
+    }
+
+    /**
+     * Tests XML unmarshalling using the format derived form ISO 19115:2003 model.
+     * This method also tests usage of {@code gml:id} and {@code xlink:href}.
+     *
+     * @throws JAXBException if an error occurred during unmarshalling.
+     *
+     * @since 0.7
+     */
+    @Test
+    public void testUnmarshalling() throws JAXBException {
+        final DefaultCitation c = unmarshalFile(DefaultCitation.class, XML_FILE);
+        assertTitleEquals("title", "Fight against poverty", c);
+
+        final CitationDate date = getSingleton(c.getDates());
+        assertEquals("date", date.getDate(), TestUtilities.date("2015-10-17 00:00:00"));
+        assertEquals("dateType", date.getDateType(), DateType.ADOPTED);
+
+        final Iterator<Responsibility> it = c.getCitedResponsibleParties().iterator();
+        final Contact contact = assertResponsibilityEquals(Role.ORIGINATOR, "Maid Marian", it.next());
+        assertEquals("Contact instruction", "Send carrier pigeon.", contact.getContactInstructions().toString());
+
+        // Thanks to xlink:href, the Contact shall be the same instance than above.
+        assertSame("contact", contact, assertResponsibilityEquals(Role.FUNDER, "Robin Hood", it.next()));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * Asserts that the given responsibility has the expected properties, then returns its contact info.
+     */
+    private static Contact assertResponsibilityEquals(final Role role, final String name, final Responsibility actual) {
+        assertEquals("role", role, actual.getRole());
+        final Party p = getSingleton(actual.getParties());
+        assertEquals("name", name, p.getName().toString());
+        return getSingleton(p.getContactInfo());
+    }
 }

Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -62,6 +62,7 @@ public final strictfp class DefaultGeogr
     /**
      * Tests construction with an invalid range of latitudes.
      */
+    @SuppressWarnings("ResultOfObjectAllocationIgnored")
     @Test(expected = IllegalArgumentException.class)
     public void testInvalidLatitudeRange() {
         new DefaultGeographicBoundingBox(-1, +1, 12, 10);

Modified: sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml Thu Oct  8 16:10:05 2015
@@ -25,9 +25,10 @@
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation = "http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd">
 
-  <!-- As of February 2011, there is not yet any XSD schema for the "gmi" namespace on the
-       OGC web site. Consequently the validation of this file does not work fully yet. -->
-
+  <!--
+    As of February 2011, there is not yet any XSD schema for the "gmi" namespace on the
+    OGC web site. Consequently the validation of this file does not work fully yet.
+  -->
   <gmd:description>
     <gco:CharacterString>Some process step.</gco:CharacterString>
   </gmd:description>

Modified: sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy.xml?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy.xml (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy.xml Thu Oct  8 16:10:05 2015
@@ -24,10 +24,11 @@
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation = "http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd">
 
-  <!-- The <nameOfMeasure> element below is the main purpose of MetadataMarshallingTest.testPositionalAccuracy().
-       The <result> element was added only in order to allow validation of this XML file, with the addition of an
-       opportunist check of xsi:type declaration. -->
-
+  <!--
+    The <nameOfMeasure> element below is the main purpose of MetadataMarshallingTest.testPositionalAccuracy().
+    The <result> element was added only in order to allow validation of this XML file, with the addition of an
+    opportunist check of xsi:type declaration.
+  -->
   <gmd:nameOfMeasure xsi:type="gmd:PT_FreeText_PropertyType">
     <gco:CharacterString>Quantitative quality measure focusing on the effective class percent regarded to the total surface size</gco:CharacterString>
     <gmd:PT_FreeText>
@@ -37,8 +38,10 @@
     </gmd:PT_FreeText>
   </gmd:nameOfMeasure>
   <gmd:result>
-    <!-- The xsi:type declaration below is useless, but we put it
-         in order to test that it does not break unmarshalling. -->
+    <!--
+      The xsi:type declaration below is useless, but we put it
+      in order to test that it does not break unmarshalling.
+    -->
     <gmd:DQ_ConformanceResult xsi:type="gmd:DQ_ConformanceResult_Type">
       <gmd:specification>
         <gmd:CI_Citation>

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -41,6 +41,7 @@ import org.opengis.referencing.ObjectFac
 import org.opengis.referencing.AuthorityFactory;
 import org.opengis.referencing.IdentifiedObject;
 import org.apache.sis.internal.metadata.NameMeaning;
+import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.jaxb.referencing.Code;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
@@ -121,7 +122,7 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  */
 @XmlType(name="IdentifiedObjectType", propOrder={
@@ -472,58 +473,6 @@ public class AbstractIdentifiedObject ex
     }
 
     /**
-     * The {@code gml:id}, which is mandatory. The current implementation searches for the first identifier,
-     * regardless its authority. If no identifier is found, then the name is used.
-     * If no name is found (which should not occur for valid objects), then this method returns {@code null}.
-     *
-     * <p>If an identifier has been found, this method returns the concatenation of the following elements
-     * separated by hyphens:</p>
-     * <ul>
-     *   <li>The code space in lower case, retaining only characters that are valid for Unicode identifiers.</li>
-     *   <li>The object type as defined in OGC's URN (see {@link org.apache.sis.internal.util.DefinitionURI})</li>
-     *   <li>The object code, retaining only characters that are valid for Unicode identifiers.</li>
-     * </ul>
-     *
-     * Example: {@code "epsg-crs-4326"}.
-     *
-     * <p>The returned ID needs to be unique only in the XML document being marshalled.
-     * Consecutive invocations of this method do not need to return the same value,
-     * since it may depends on the marshalling context.</p>
-     */
-    @XmlID
-    @XmlSchemaType(name = "ID")
-    @XmlAttribute(name = "id", namespace = Namespaces.GML, required = true)
-    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
-    final String getID() {
-        final StringBuilder id = new StringBuilder();
-        /*
-         * We will iterate over the identifiers first. Only after the iteration is over,
-         * if we found no suitable ID, then we will use the primary name as a last resort.
-         */
-        if (identifiers != null) {
-            for (final Identifier identifier : identifiers) {
-                if (appendUnicodeIdentifier(id, '-', identifier.getCodeSpace(), ":", true) | // Really |, not ||
-                    appendUnicodeIdentifier(id, '-', NameMeaning.toObjectType(getClass()), ":", false) |
-                    appendUnicodeIdentifier(id, '-', identifier.getCode(), ":", true))
-                {
-                    /*
-                     * TODO: If we want to check for ID uniqueness or any other condition before to accept the ID,
-                     * we would do that here. If the ID is rejected, then we just need to clear the buffer and let
-                     * the iteration continue the search for an other ID.
-                     */
-                    return id.toString();
-                }
-                id.setLength(0); // Clear the buffer for an other try.
-            }
-        }
-        // In last ressort, append code without codespace since the name are often verbose.
-        if (name != null && appendUnicodeIdentifier(id, '-', name.getCode(), ":", false)) {
-            return id.toString();
-        }
-        return null;
-    }
-
-    /**
      * Returns the primary name by which this object is identified.
      *
      * @return The primary name.
@@ -946,6 +895,99 @@ public class AbstractIdentifiedObject ex
     }
 
     /**
+     * The {@code gml:id}, which is mandatory. The current implementation searches for the first identifier,
+     * regardless its authority. If no identifier is found, then the name is used.
+     * If no name is found (which should not occur for valid objects), then this method returns {@code null}.
+     *
+     * <p>If an identifier has been found, this method returns the concatenation of the following elements
+     * separated by hyphens:</p>
+     * <ul>
+     *   <li>The code space in lower case, retaining only characters that are valid for Unicode identifiers.</li>
+     *   <li>The object type as defined in OGC's URN (see {@link org.apache.sis.internal.util.DefinitionURI})</li>
+     *   <li>The object code, retaining only characters that are valid for Unicode identifiers.</li>
+     * </ul>
+     *
+     * Example: {@code "epsg-crs-4326"}.
+     *
+     * <p>The returned ID needs to be unique only in the XML document being marshalled.
+     * Consecutive invocations of this method do not need to return the same value,
+     * since it may depends on the marshalling context.</p>
+     */
+    @XmlID
+    @XmlSchemaType(name = "ID")
+    @XmlAttribute(name = "id", namespace = Namespaces.GML, required = true)
+    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+    final String getID() {
+        final Context context = Context.current();
+        String candidate = Context.getObjectID(context, this);
+        if (candidate == null) {
+            final StringBuilder id = new StringBuilder();
+            /*
+             * We will iterate over the identifiers first. Only after the iteration is over,
+             * if we found no suitable ID, then we will use the primary name as a last resort.
+             */
+            if (identifiers != null) {
+                for (final Identifier identifier : identifiers) {
+                    if (appendUnicodeIdentifier(id, '-', identifier.getCodeSpace(), ":", true) | // Really |, not ||
+                        appendUnicodeIdentifier(id, '-', NameMeaning.toObjectType(getClass()), ":", false) |
+                        appendUnicodeIdentifier(id, '-', identifier.getCode(), ":", true))
+                    {
+                        /*
+                         * Check for ID uniqueness. If the ID is rejected, then we just need to clear
+                         * the buffer and let the iteration continue the search for another ID.
+                         */
+                        candidate = id.toString();
+                        if (Context.setObjectForID(context, this, candidate)) {
+                            return candidate;
+                        }
+                    }
+                    id.setLength(0);    // Clear the buffer for another try.
+                }
+            }
+            /*
+             * In last ressort, use the name or an alias. The name will be used without codespace since
+             * names are often verbose. If that name is also used, append a number until we find a free ID.
+             */
+            if (name == null || !appendUnicodeIdentifier(id, '-', name.getCode(), ":", false)) {
+                if (alias != null) {
+                    for (final GenericName a : alias) {
+                        if (appendUnicodeIdentifier(id, '-', a.toString(), ":", false)) {
+                            break;
+                        }
+                    }
+                }
+            }
+            if (id.length() != 0) {
+                candidate = id.toString();
+                if (!Context.setObjectForID(context, this, candidate)) {
+                    final int s = id.append('-').length();
+                    int n = 0;
+                    do {
+                        if (++n == 100) return null;    //  Arbitrary limit.
+                        candidate = id.append(n).toString();
+                        id.setLength(s);
+                    } while (!Context.setObjectForID(context, this, candidate));
+                }
+            }
+        }
+        return candidate;
+    }
+
+    /**
+     * Invoked by JAXB at unmarhalling time for specifying the value of the {@code gml:id} attribute.
+     * That GML identifier is not actually stored in this {@code AbstractIdentifiedObject}
+     * since we rather generate it dynamically from the ISO 19111 identifiers. But we still
+     * need to declare that identifier to our unmarshaller context, in case it is referenced
+     * from elsewhere in the XML document.
+     */
+    private void setID(final String id) {
+        final Context context = Context.current();
+        if (!Context.setObjectForID(context, this, id)) {
+            Context.warningOccured(context, getClass(), "setID", Errors.class, Errors.Keys.DuplicatedIdentifier_1, id);
+        }
+    }
+
+    /**
      * Returns a single element from the {@code Set<Identifier>} collection, or {@code null} if none.
      * We have to define this method because ISO 19111 defines the {@code identifiers} property as a collection
      * while GML 3.2 defines it as a singleton.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -152,7 +152,8 @@ public class DefaultOperationMethod exte
      * contains the procedure, not an analytic formula.
      *
      * <p><b>Consider this field as final!</b>
-     * This field is modified only at unmarshalling time by {@link #setFormula(Object)}</p>
+     * This field is modified only at unmarshalling time by {@link #setFormulaCitation(Citation)}
+     * or {@link #setFormulaDescription(String)}.</p>
      */
     private Formula formula;
 

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterMarshallingTest.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -50,7 +50,7 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  */
 @DependsOn({
@@ -361,23 +361,48 @@ public final strictfp class ParameterMar
     }
 
     /**
-     * Tests (un)marshalling of a parameter value group.
+     * Tests marshalling of a parameter value group.
      *
-     * @throws JAXBException if an error occurred during marshalling or unmarshalling.
+     * @throws JAXBException if an error occurred during marshalling.
      */
     @Test
     @DependsOnMethod("testDescriptorGroup")
-    public void testValueGroup() throws JAXBException {
-        // Test marshalling.
+    public void testValueGroupMmarshalling() throws JAXBException {
         assertMarshalEqualsFile("ParameterValueGroup.xml",
                 ParameterFormatTest.createMercatorParameters().createValue(),
-                "xmlns:*", "xsi:schemaLocation", "gml:id");
+                "xmlns:*", "xsi:schemaLocation");
+    }
 
-        // Test unmarshalling.
-        final DefaultParameterValueGroup group = unmarshalFile(
-                DefaultParameterValueGroup.class, "ParameterValueGroup.xml");
+    /**
+     * Tests unmarshalling of a parameter value group. The XML file use {@code xlink:href} attributes
+     * for avoiding to repeat the full definition of descriptors.
+     *
+     * @throws JAXBException if an error occurred during unmarshalling.
+     */
+    @Test
+    @DependsOnMethod("testDescriptorGroup")
+    public void testValueGroupUnmarshalling() throws JAXBException {
+        testValueGroupUnmarshalling("ParameterValueGroup.xml");
+    }
 
-        // Verify the ParameterValues properties.
+    /**
+     * Tests unmarshalling of a parameter value group. The XML file does not use {@code xlink:href} attributes;
+     * descriptor definitions are repeated. The intend of this test is to test Apache SIS capability to replace
+     * duplicates instances by unique instances.
+     *
+     * @throws JAXBException if an error occurred during unmarshalling.
+     */
+    @Test
+    @DependsOnMethod("testValueGroupUnmarshalling")
+    public void testDuplicatedParametersUnmarshalling() throws JAXBException {
+        testValueGroupUnmarshalling("DuplicatedParameters.xml");
+    }
+
+    /**
+     * Tests unmarshalling of the given file.
+     */
+    private void testValueGroupUnmarshalling(final String file) throws JAXBException {
+        final DefaultParameterValueGroup group = unmarshalFile(DefaultParameterValueGroup.class, file);
         verifyDescriptorGroup(group.getDescriptor());
         final Iterator<GeneralParameterValue> it = group.values().iterator();
         final Iterator<GeneralParameterDescriptor> itd = group.getDescriptor().descriptors().iterator();

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -27,6 +27,7 @@ import org.opengis.metadata.Identifier;
 import org.apache.sis.metadata.iso.ImmutableIdentifier;
 import org.apache.sis.referencing.datum.AbstractDatum;
 import org.apache.sis.internal.jaxb.referencing.Code;
+import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -42,7 +43,7 @@ import static org.apache.sis.metadata.is
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 @DependsOn({
@@ -99,6 +100,7 @@ public final strictfp class AbstractIden
      * This is invalid and should thrown an exception.
      */
     @Test
+    @SuppressWarnings("ResultOfObjectAllocationIgnored")
     public void testMissingName() {
         final Map<String,Object> properties = new HashMap<String,Object>(4);
         assertNull(properties.put(AbstractIdentifiedObject.REMARKS_KEY, "Not a name."));
@@ -194,6 +196,38 @@ public final strictfp class AbstractIden
     }
 
     /**
+     * Tests two {@code AbstractIdentifiedObject} declaring the same identifier in the same XML document.
+     * The {@code getID()} method should detect the collision and select different identifier.
+     *
+     * @since 0.7
+     */
+    @Test
+    @DependsOnMethod("testWithManyIdentifiers")
+    public void testIdentifierCollision() {
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        assertNull(properties.put("name", "GRS 1980"));
+        assertNull(properties.put("identifiers", new NamedIdentifier(EPSG, "7019")));
+        final AbstractIdentifiedObject o1 = new AbstractIdentifiedObject(properties);
+        final AbstractIdentifiedObject o2 = new AbstractIdentifiedObject(properties);
+        final AbstractIdentifiedObject o3 = new AbstractIdentifiedObject(properties);
+        final AbstractIdentifiedObject o4 = new AbstractIdentifiedObject(properties);
+        final Context context = new Context(0, null, null, null, null, null, null, null);
+        try {
+            final String c1, c2, c3, c4;
+            assertEquals("o1", "epsg-7019", c1 = o1.getID());
+            assertEquals("o2", "GRS1980",   c2 = o2.getID());
+            assertEquals("o3", "GRS1980-1", c3 = o3.getID());
+            assertEquals("o4", "GRS1980-2", c4 = o4.getID());
+            assertSame  ("o1", c1, o1.getID());  // Verify that values are remembered.
+            assertSame  ("o2", c2, o2.getID());
+            assertSame  ("o3", c3, o3.getID());
+            assertSame  ("o4", c4, o4.getID());
+        } finally {
+            context.finish();
+        }
+    }
+
+    /**
      * Tests serialization.
      */
     @Test

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DefaultMetadataTest.java [UTF-8] Thu Oct  8 16:10:05 2015
@@ -20,6 +20,7 @@ import java.net.URI;
 import java.net.URL;
 import java.util.Arrays;
 import java.util.Locale;
+import java.util.Collections;
 import java.io.StringWriter;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
@@ -54,6 +55,7 @@ import org.apache.sis.util.iso.SimpleInt
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.xml.MarshallerPool;
+import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.XMLComparator;
 import org.apache.sis.test.XMLTestCase;
@@ -75,7 +77,7 @@ import org.apache.sis.internal.jdk7.Stan
  * @author  Guilhem Legal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.7
  * @module
  *
  * @see org.apache.sis.metadata.iso.DefaultMetadataTest
@@ -121,6 +123,7 @@ public strictfp class DefaultMetadataTes
             final DefaultOnlineResource online = new DefaultOnlineResource(URI.create("http://www.ifremer.fr/sismer/"));
             online.setProtocol("http");
             final DefaultContact contact = new DefaultContact(online);
+            contact.getIdentifierMap().putSpecialized(IdentifierSpace.ID, "IFREMER");
             contact.setPhones(Arrays.asList(
                     new DefaultTelephone("+33 (0)2 xx.xx.xx.x6", TelephoneType.VOICE),
                     new DefaultTelephone("+33 (0)2 xx.xx.xx.x4", TelephoneType.FACSIMILE)
@@ -132,7 +135,7 @@ public strictfp class DefaultMetadataTes
             address.setCountry(country);
             address.setElectronicMailAddresses(singleton("xx@xx.fr"));
             contact.setAddresses(singleton(address));
-            author.setParties(Arrays.asList(
+            author.setParties(Collections.singleton(
                     new DefaultOrganisation("Marine institutes", null, null, contact)
             ));
             metadata.setContacts(singleton(author));
@@ -162,7 +165,7 @@ public strictfp class DefaultMetadataTes
                 address.setPostalCode("13288");
                 address.setCountry(country);
                 contact.setAddresses(singleton(address));
-                originator.setParties(Arrays.asList(
+                originator.setParties(Collections.singleton(
                         new DefaultOrganisation("Oceanology laboratory", null, null, contact)
                 ));
                 citation.setCitedResponsibleParties(singleton(originator));
@@ -199,7 +202,7 @@ public strictfp class DefaultMetadataTes
             {
                 final DefaultBrowseGraphic g = new DefaultBrowseGraphic(URI.create("file:///thumbnail.png"));
                 g.setFileDescription(new SimpleInternationalString("Arbitrary thumbnail for this test only."));
-                identification.setGraphicOverviews(Arrays.asList(g));
+                identification.setGraphicOverviews(Collections.singleton(g));
             }
             /*
              * Data indentification / Resource constraint.

Modified: sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/parameter/ParameterValueGroup.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/parameter/ParameterValueGroup.xml?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/parameter/ParameterValueGroup.xml (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/parameter/ParameterValueGroup.xml Thu Oct  8 16:10:05 2015
@@ -20,6 +20,7 @@
 
 <gml:ParameterValueGroup xsi:schemaLocation = "http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/coordinateOperations.xsd"
                          xmlns:gml          = "http://www.opengis.net/gml/3.2"
+                         xmlns:xlink        = "http://www.w3.org/1999/xlink"
                          xmlns:xsi          = "http://www.w3.org/2001/XMLSchema-instance">
 
   <gml:parameterValue>
@@ -65,34 +66,14 @@
       <gml:name codeSpace="EPSG">Mercator (variant A)</gml:name>
       <gml:name codeSpace="OGC">Mercator_1SP</gml:name>
       <gml:minimumOccurs>0</gml:minimumOccurs>
-
-      <!-- All parameters below this point are duplication of the parameters already defined above.
-           For now we do not yet use the XML references, but this is something that we will need to
-           support in a future SIS version. See https://issues.apache.org/jira/browse/SIS-173 issue.
-           In the meantime, we have to change the gml:id attribute values used below for avoiding
-           collisions with the gml:id attribute used in above parameters. -->
-      <gml:parameter>
-        <gml:OperationParameter gml:id="epsg-8801">
-          <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8801</gml:identifier>
-          <gml:name codeSpace="EPSG">Latitude of natural origin</gml:name>
-          <gml:name codeSpace="OGC">latitude_of_origin</gml:name>
-          <gml:remarks>This parameter is shown for completeness, but should never have a value different than 0 for this projection.</gml:remarks>
-        </gml:OperationParameter>
-      </gml:parameter>
-      <gml:parameter>
-        <gml:OperationParameter gml:id="epsg-8802">
-          <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8802</gml:identifier>
-          <gml:name codeSpace="EPSG">Longitude of natural origin</gml:name>
-          <gml:name codeSpace="OGC">central_meridian</gml:name>
-        </gml:OperationParameter>
-      </gml:parameter>
-      <gml:parameter>
-        <gml:OperationParameter gml:id="epsg-8805">
-          <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8805</gml:identifier>
-          <gml:name codeSpace="EPSG">Scale factor at natural origin</gml:name>
-          <gml:name codeSpace="OGC">scale_factor</gml:name>
-        </gml:OperationParameter>
-      </gml:parameter>
+      <!--
+        The first three parameters below this point are the same than the parameters defined above.
+        The xlink:href attribute allows to reference existing instances instead than repeating them.
+        Repetition will be tested with another file: DuplicatedParameters.xml
+      -->
+      <gml:parameter xlink:href="#epsg-parameter-8801"/>
+      <gml:parameter xlink:href="#epsg-parameter-8802"/>
+      <gml:parameter xlink:href="#epsg-parameter-8805"/>
       <gml:parameter>
         <gml:OperationParameter gml:id="epsg-parameter-8806">
           <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8806</gml:identifier>

Modified: sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/crs/ProjectedCRS.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/crs/ProjectedCRS.xml?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/crs/ProjectedCRS.xml (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/crs/ProjectedCRS.xml Thu Oct  8 16:10:05 2015
@@ -20,6 +20,7 @@
 
 <gml:ProjectedCRS xsi:schemaLocation = "http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/coordinateReferenceSystems.xsd"
                   xmlns:gml          = "http://www.opengis.net/gml/3.2"
+                  xmlns:xlink        = "http://www.w3.org/1999/xlink"
                   xmlns:xsi          = "http://www.w3.org/2001/XMLSchema-instance"
                   gml:id             = "epsg-crs-27572">
 
@@ -70,68 +71,34 @@
           </gml:parameter>
         </gml:OperationMethod>
       </gml:method>
-
-      <!--
-        All parameters below this point are duplication of the parameters already defined above.
-        For now we do not yet use the XML references, but this is something that we will need to
-        support in a future SIS version. See https://issues.apache.org/jira/browse/SIS-173 issue.
-        In the meantime, we have to change the gml:id attribute values used below for avoiding
-        collisions with the gml:id attribute used in above parameters.
-      -->
-
       <gml:parameterValue>
         <gml:ParameterValue>
           <gml:value uom="urn:ogc:def:uom:EPSG::9105">52</gml:value>
-          <gml:operationParameter>
-            <gml:OperationParameter gml:id="t-8801">
-              <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8801</gml:identifier>
-              <gml:name>Latitude of natural origin</gml:name>
-            </gml:OperationParameter>
-          </gml:operationParameter>
+          <gml:operationParameter xlink:href="#epsg-param-8801"/>
         </gml:ParameterValue>
       </gml:parameterValue>
       <gml:parameterValue>
         <gml:ParameterValue>
           <gml:value uom="urn:ogc:def:uom:EPSG::9105">0</gml:value>
-          <gml:operationParameter>
-            <gml:OperationParameter gml:id="t-8802">
-              <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8802</gml:identifier>
-              <gml:name>Longitude of natural origin</gml:name>
-            </gml:OperationParameter>
-          </gml:operationParameter>
+          <gml:operationParameter xlink:href="#epsg-param-8802"/>
         </gml:ParameterValue>
       </gml:parameterValue>
       <gml:parameterValue>
         <gml:ParameterValue>
           <gml:value uom="urn:ogc:def:uom:EPSG::9201">0.99987742</gml:value>
-          <gml:operationParameter>
-            <gml:OperationParameter gml:id="t-8805">
-              <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8805</gml:identifier>
-              <gml:name>Scale factor at natural origin</gml:name>
-            </gml:OperationParameter>
-          </gml:operationParameter>
+          <gml:operationParameter xlink:href="#epsg-param-8805"/>
         </gml:ParameterValue>
       </gml:parameterValue>
       <gml:parameterValue>
         <gml:ParameterValue>
           <gml:value uom="urn:ogc:def:uom:EPSG::9001">600000</gml:value>
-          <gml:operationParameter>
-            <gml:OperationParameter gml:id="t-8806">
-              <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8806</gml:identifier>
-              <gml:name>False easting</gml:name>
-            </gml:OperationParameter>
-          </gml:operationParameter>
+          <gml:operationParameter xlink:href="#epsg-param-8806"/>
         </gml:ParameterValue>
       </gml:parameterValue>
       <gml:parameterValue>
         <gml:ParameterValue>
           <gml:value uom="urn:ogc:def:uom:EPSG::9001">2200000</gml:value>
-          <gml:operationParameter>
-            <gml:OperationParameter gml:id="t-8807">
-              <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8807</gml:identifier>
-              <gml:name>False northing</gml:name>
-            </gml:OperationParameter>
-          </gml:operationParameter>
+          <gml:operationParameter xlink:href="#epsg-param-8807"/>
         </gml:ParameterValue>
       </gml:parameterValue>
     </gml:Conversion>

Modified: sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Conversion.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Conversion.xml?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Conversion.xml (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Conversion.xml Thu Oct  8 16:10:05 2015
@@ -91,13 +91,13 @@
   <gml:parameterValue>
     <gml:ParameterValue>
       <gml:value uom="urn:ogc:def:uom:EPSG::9102">-0</gml:value>    <!-- Intentionally negative for testing purpose. -->
-
-      <!-- All descriptors below this point are duplication of the descriptors already defined above.
-           For now we do not yet use the XML references, but this is something that we will need to
-           support in a future SIS version. See https://issues.apache.org/jira/browse/SIS-173 issue.
-           In the meantime, we have to change the gml:id attribute values used below for avoiding
-           collisions with the gml:id attribute used in above descriptors. -->
-
+      <!--
+        All descriptors below this point are duplications of the descriptors already defined above.
+        We could use the xlink:href attribute, but we rather repeat the descriptors in this file in
+        order to test SIS capability to replace duplicated instances by unique instances. Note that
+        we have to use different gml:id attribute values for avoiding collisions with the values in
+        above descriptors.
+      -->
       <gml:operationParameter>
         <gml:OperationParameter gml:id="LatitudeOfNaturalOrigin">
           <gml:identifier codeSpace="IOGP">urn:ogc:def:parameter:EPSG::8801</gml:identifier>

Modified: sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Transformation.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Transformation.xml?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Transformation.xml (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/referencing/operation/Transformation.xml Thu Oct  8 16:10:05 2015
@@ -68,14 +68,14 @@
           <gml:name>Nouvelle Triangulation Française (Paris)</gml:name>
           <gml:scope>Topographic mapping.</gml:scope>
           <gml:primeMeridian>
-            <gml:PrimeMeridian gml:id = "ParisMeridian">
+            <gml:PrimeMeridian gml:id="ParisMeridian">
               <gml:identifier codeSpace="IOGP">urn:ogc:def:meridian:EPSG::8901</gml:identifier>
               <gml:name>Greenwich</gml:name>
               <gml:greenwichLongitude uom="urn:ogc:def:uom:EPSG::9105">2.5969213</gml:greenwichLongitude>
             </gml:PrimeMeridian>
           </gml:primeMeridian>
           <gml:ellipsoid>
-            <gml:Ellipsoid gml:id = "Ellipsoid">
+            <gml:Ellipsoid gml:id="Ellipsoid">
               <gml:identifier codeSpace="IOGP">urn:ogc:def:ellipsoid:EPSG::7030</gml:identifier>
               <gml:name>Clarke 1880 (IGN)</gml:name>
               <gml:semiMajorAxis uom="urn:ogc:def:uom:EPSG::9001">6378249.2</gml:semiMajorAxis>
@@ -94,65 +94,27 @@
   <!--
     Following CRS definition contains a lot of information identical to the source CRS.
     The only difference are the datum and the prime meridian.
-
-    See https://issues.apache.org/jira/browse/SIS-173 issue.
-    Duplicated value have the "-copy" suffix in gml:id.
+    We reuse the above definitions with xlink:href attributes.
   -->
   <gml:targetCRS>
     <gml:GeodeticCRS gml:id="Greenwich">
       <gml:identifier codeSpace="IOGP">urn:ogc:def:crs:EPSG::4275</gml:identifier>
       <gml:name>NTF</gml:name>
       <gml:scope>Geodetic survey.</gml:scope>
-      <gml:ellipsoidalCS>
-        <!-- TODO (SIS-173): replace following element by IDREF -->
-        <gml:EllipsoidalCS gml:id="CoordinateSystem-copy">
-          <gml:identifier codeSpace="IOGP">urn:ogc:def:cs:EPSG::6422</gml:identifier>
-          <gml:name>Latitude (north), Longitude (east)</gml:name>
-          <gml:axis>
-            <gml:CoordinateSystemAxis gml:id="φ-copy" uom="urn:ogc:def:uom:EPSG::9122">
-              <gml:identifier codeSpace="IOGP">urn:ogc:def:axis:EPSG::106</gml:identifier>
-              <gml:name>Geodetic latitude</gml:name>
-              <gml:axisAbbrev>φ</gml:axisAbbrev>
-              <gml:axisDirection codeSpace="EPSG">north</gml:axisDirection>
-              <gml:rangeMeaning codeSpace="EPSG">exact</gml:rangeMeaning>
-            </gml:CoordinateSystemAxis>
-          </gml:axis>
-          <gml:axis>
-            <gml:CoordinateSystemAxis gml:id="λ-copy" uom="urn:ogc:def:uom:EPSG::9122">
-              <gml:identifier codeSpace="IOGP">urn:ogc:def:axis:EPSG::107</gml:identifier>
-              <gml:name>Geodetic longitude</gml:name>
-              <gml:axisAbbrev>λ</gml:axisAbbrev>
-              <gml:axisDirection codeSpace="EPSG">east</gml:axisDirection>
-              <gml:rangeMeaning codeSpace="EPSG">wraparound</gml:rangeMeaning>
-            </gml:CoordinateSystemAxis>
-          </gml:axis>
-        </gml:EllipsoidalCS>
-      </gml:ellipsoidalCS>
+      <gml:ellipsoidalCS xlink:href="#CoordinateSystem"/>
       <gml:geodeticDatum>
         <gml:GeodeticDatum gml:id="GreenwichDatum">
           <gml:identifier codeSpace="IOGP">urn:ogc:def:datum:EPSG::6275</gml:identifier>
           <gml:name>Nouvelle Triangulation Française</gml:name>
           <gml:scope>Topographic mapping.</gml:scope>
           <gml:primeMeridian>
-            <gml:PrimeMeridian gml:id = "GreenwichMeridian">
+            <gml:PrimeMeridian gml:id="GreenwichMeridian">
               <gml:identifier codeSpace="IOGP">urn:ogc:def:meridian:EPSG::8901</gml:identifier>
               <gml:name>Greenwich</gml:name>
               <gml:greenwichLongitude uom="urn:ogc:def:uom:EPSG::9102">0</gml:greenwichLongitude>
             </gml:PrimeMeridian>
           </gml:primeMeridian>
-          <!-- TODO (SIS-173): replace following element by IDREF -->
-          <gml:ellipsoid>
-            <gml:Ellipsoid gml:id = "Ellipsoid-copy">
-              <gml:identifier codeSpace="IOGP">urn:ogc:def:ellipsoid:EPSG::7011</gml:identifier>
-              <gml:name>Clarke 1880 (IGN)</gml:name>
-              <gml:semiMajorAxis uom="urn:ogc:def:uom:EPSG::9001">6378249.2</gml:semiMajorAxis>
-              <gml:secondDefiningParameter>
-                <gml:SecondDefiningParameter>
-                  <gml:semiMinorAxis uom="urn:ogc:def:uom:EPSG::9001">6356515</gml:semiMinorAxis>
-                </gml:SecondDefiningParameter>
-              </gml:secondDefiningParameter>
-            </gml:Ellipsoid>
-          </gml:ellipsoid>
+          <gml:ellipsoid xlink:href="#Ellipsoid"/>
         </gml:GeodeticDatum>
       </gml:geodeticDatum>
     </gml:GeodeticCRS>
@@ -179,7 +141,7 @@
       <gml:value uom="urn:ogc:def:uom:EPSG::9105">2.5969213</gml:value>
       <!--
         The following duplicates the descriptor defined in above <gml:method>, so we could replace the definition
-        by a gml:idref="ParameterDescriptor" attribute (http://issues.apache.org/jira/browse/SIS-173).  But we do
+        by xlink:href="#ParameterDescriptor" attribute (http://issues.apache.org/jira/browse/SIS-173).  But we do
         not apply this simplification because we want to opportunistically test SIS capability to consolidate the
         various descriptors into canonical instances based on the parameter name.
       -->

Modified: sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml?rev=1707577&r1=1707576&r2=1707577&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/resources/org/apache/sis/test/integration/Metadata.xml Thu Oct  8 16:10:05 2015
@@ -49,7 +49,7 @@
         <gco:CharacterString>Marine institutes</gco:CharacterString>
       </gmd:organisationName>
       <gmd:contactInfo>
-        <gmd:CI_Contact>
+        <gmd:CI_Contact id="IFREMER">
           <gmd:phone>
             <gmd:CI_Telephone>
               <gmd:voice>
@@ -254,49 +254,7 @@
           <gmd:organisationName>
             <gco:CharacterString>Marine institutes</gco:CharacterString>
           </gmd:organisationName>
-          <gmd:contactInfo>
-            <gmd:CI_Contact>
-              <gmd:phone>
-                <gmd:CI_Telephone>
-                  <gmd:voice>
-                    <gco:CharacterString>+33 (0)2 xx.xx.xx.x6</gco:CharacterString>
-                  </gmd:voice>
-                  <gmd:facsimile>
-                    <gco:CharacterString>+33 (0)2 xx.xx.xx.x4</gco:CharacterString>
-                  </gmd:facsimile>
-                </gmd:CI_Telephone>
-              </gmd:phone>
-              <gmd:address>
-                <gmd:CI_Address>
-                  <gmd:deliveryPoint>
-                    <gco:CharacterString>Brest institute</gco:CharacterString>
-                  </gmd:deliveryPoint>
-                  <gmd:city>
-                    <gco:CharacterString>Plouzane</gco:CharacterString>
-                  </gmd:city>
-                  <gmd:postalCode>
-                    <gco:CharacterString>29280</gco:CharacterString>
-                  </gmd:postalCode>
-                  <gmd:country>
-                    <gmx:Anchor xlink:href="SDN:C320:2:FR">France</gmx:Anchor>
-                  </gmd:country>
-                  <gmd:electronicMailAddress>
-                    <gco:CharacterString>xx@xx.fr</gco:CharacterString>
-                  </gmd:electronicMailAddress>
-                </gmd:CI_Address>
-              </gmd:address>
-              <gmd:onlineResource>
-                <gmd:CI_OnlineResource>
-                  <gmd:linkage>
-                    <gmd:URL>http://www.ifremer.fr/sismer/</gmd:URL>
-                  </gmd:linkage>
-                  <gmd:protocol>
-                    <gco:CharacterString>http</gco:CharacterString>
-                  </gmd:protocol>
-                </gmd:CI_OnlineResource>
-              </gmd:onlineResource>
-            </gmd:CI_Contact>
-          </gmd:contactInfo>
+          <gmd:contactInfo xlink:href="#IFREMER"/>
           <gmd:role>
             <gmd:CI_RoleCode codeListValue="custodian" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode">Custodian</gmd:CI_RoleCode>
           </gmd:role>
@@ -482,49 +440,7 @@
               <gmd:organisationName>
                 <gco:CharacterString>Marine institutes</gco:CharacterString>
               </gmd:organisationName>
-              <gmd:contactInfo>
-                <gmd:CI_Contact>
-                  <gmd:phone>
-                    <gmd:CI_Telephone>
-                      <gmd:voice>
-                        <gco:CharacterString>+33 (0)2 xx.xx.xx.x6</gco:CharacterString>
-                      </gmd:voice>
-                      <gmd:facsimile>
-                        <gco:CharacterString>+33 (0)2 xx.xx.xx.x4</gco:CharacterString>
-                      </gmd:facsimile>
-                    </gmd:CI_Telephone>
-                  </gmd:phone>
-                  <gmd:address>
-                    <gmd:CI_Address>
-                      <gmd:deliveryPoint>
-                        <gco:CharacterString>Brest institute</gco:CharacterString>
-                      </gmd:deliveryPoint>
-                      <gmd:city>
-                        <gco:CharacterString>Plouzane</gco:CharacterString>
-                      </gmd:city>
-                      <gmd:postalCode>
-                        <gco:CharacterString>29280</gco:CharacterString>
-                      </gmd:postalCode>
-                      <gmd:country>
-                        <gmx:Anchor xlink:href="SDN:C320:2:FR">France</gmx:Anchor>
-                      </gmd:country>
-                      <gmd:electronicMailAddress>
-                        <gco:CharacterString>xx@xx.fr</gco:CharacterString>
-                      </gmd:electronicMailAddress>
-                    </gmd:CI_Address>
-                  </gmd:address>
-                  <gmd:onlineResource>
-                    <gmd:CI_OnlineResource>
-                      <gmd:linkage>
-                        <gmd:URL>http://www.ifremer.fr/sismer/</gmd:URL>
-                      </gmd:linkage>
-                      <gmd:protocol>
-                        <gco:CharacterString>http</gco:CharacterString>
-                      </gmd:protocol>
-                    </gmd:CI_OnlineResource>
-                  </gmd:onlineResource>
-                </gmd:CI_Contact>
-              </gmd:contactInfo>
+              <gmd:contactInfo xlink:href="#IFREMER"/>
               <gmd:role>
                 <gmd:CI_RoleCode codeListValue="distributor" codeList="http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#CI_RoleCode">Distributor</gmd:CI_RoleCode>
               </gmd:role>