sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1497820 - in /sis/branches/JDK7/core: sis-metadata/src/main/java/org/apache/sis/metadata/iso/ sis-metadata/src/test/java/org/apache/sis/test/suite/ sis-metadata/src/test/java/org/apache/sis/xml/ sis-utility/src/main/java/org/apache/sis/int...
Date Fri, 28 Jun 2013 15:50:32 GMT
Author: desruisseaux
Date: Fri Jun 28 15:50:31 2013
New Revision: 1497820

URL: http://svn.apache.org/r1497820
Log:
Ported ObjectReferenceMarshallingTest. Implied more work on gco:uuid support.

Added:
    sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/xml/ObjectReferenceMarshallingTest.java
  (with props)
Modified:
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
    sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/jaxb/gco/PropertyTypeTest.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/mock/ReferenceResolverMock.java

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java?rev=1497820&r1=1497819&r2=1497820&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -16,19 +16,30 @@
  */
 package org.apache.sis.metadata.iso;
 
+import java.util.UUID;
 import java.util.Collection;
 import java.util.logging.Logger;
 import java.io.Serializable;
+import javax.xml.bind.annotation.XmlID;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
 import org.opengis.metadata.Identifier;
 import org.apache.sis.xml.IdentifierMap;
+import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.xml.IdentifiedObject;
+import org.apache.sis.xml.ValueConverter;
 import org.apache.sis.metadata.MetadataStandard;
 import org.apache.sis.metadata.ModifiableMetadata;
 import org.apache.sis.internal.jaxb.IdentifierMapWithSpecialCases;
+import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ThreadSafe;
 
+import static org.apache.sis.util.collection.Containers.isNullOrEmpty;
+
 
 /**
  * The base class of ISO 19115 implementation classes. Each sub-classes implements one
@@ -124,4 +135,62 @@ public class ISOMetadata extends Modifia
          */
         return new IdentifierMapWithSpecialCases(identifiers);
     }
+
+    /**
+     * Returns an identifier unique for the XML document, or {@code null} if none.
+     * This method is invoked automatically by JAXB and should never be invoked explicitely.
+     */
+    @XmlID
+    @XmlAttribute  // Defined in "gco" as unqualified attribute.
+    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+    private String getID() {
+        return isNullOrEmpty(identifiers) ? null : getIdentifierMap().getSpecialized(IdentifierSpace.ID);
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * Returns an unique identifier, or {@code null} if none.
+     * This method is invoked automatically by JAXB and should never be invoked explicitely.
+     */
+    @XmlAttribute  // Defined in "gco" as unqualified attribute.
+    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
+    private String getUUID() {
+        return isNullOrEmpty(identifiers) ? null : getIdentifierMap().get(IdentifierSpace.UUID);
+    }
+
+    /**
+     * Sets an unique identifier.
+     * This method is invoked automatically by JAXB and should never be invoked explicitely.
+     *
+     * @throws IllegalArgumentException If the UUID is already assigned to an other object.
+     */
+    private void setUUID(String id) {
+        final Context context = Context.current();
+        final ValueConverter converter = Context.converter(context);
+        final UUID uuid;
+        try {
+            uuid = converter.toUUID(context, id);
+        } catch (IllegalArgumentException e) {
+            // IF we can not store the value as a UUID, store it as a String.
+            Context.warningOccured(context, this, ISOMetadata.class, "setUUID", e, false);
+            id = CharSequences.trimWhitespaces(id);
+            if (id != null && !id.isEmpty()) {
+                getIdentifierMap().put(IdentifierSpace.UUID, id);
+            }
+            return;
+        }
+        if (uuid != null) {
+            getIdentifierMap().putSpecialized(IdentifierSpace.UUID, uuid);
+        }
+    }
 }

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java?rev=1497820&r1=1497819&r2=1497820&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -351,7 +351,9 @@ public class ImmutableIdentifier impleme
             throw new InvalidParameterValueException(
                     Errors.format(Errors.Keys.IllegalArgumentValue_2, key, value), exception,
key, value);
         }
-        ensureNonNull(CODE_KEY, code);
+        if (code == null) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.MissingValueForProperty_1,
CODE_KEY));
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1497820&r1=1497819&r2=1497820&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -56,11 +56,12 @@ import org.junit.BeforeClass;
     org.apache.sis.metadata.iso.AllMetadataTest.class,
 
     // XML marshalling.
-    org.apache.sis.xml.NilReasonMarshallingTest.class,
-    org.apache.sis.xml.FreeTextMarshallingTest.class,
     org.apache.sis.internal.jaxb.code.CodeListMarshallingTest.class,
     org.apache.sis.internal.jaxb.gmd.LanguageMarshallingTest.class,
-    org.apache.sis.internal.jaxb.gml.TimePeriodTest.class
+    org.apache.sis.internal.jaxb.gml.TimePeriodTest.class,
+    org.apache.sis.xml.FreeTextMarshallingTest.class,
+    org.apache.sis.xml.NilReasonMarshallingTest.class,
+    org.apache.sis.xml.ObjectReferenceMarshallingTest.class
 })
 public final strictfp class MetadataTestSuite extends TestSuite {
     /**

Added: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/xml/ObjectReferenceMarshallingTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/xml/ObjectReferenceMarshallingTest.java?rev=1497820&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/xml/ObjectReferenceMarshallingTest.java
(added)
+++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/xml/ObjectReferenceMarshallingTest.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -0,0 +1,233 @@
+/*
+ * 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.xml;
+
+import java.lang.reflect.Proxy;
+import javax.xml.bind.JAXBException;
+import org.opengis.metadata.citation.Series;
+import org.opengis.metadata.citation.Citation;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.XMLTestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assert.*;
+
+
+/**
+ * Tests the XML marshalling of object having {@code xlink} or {@code uuid} attributes.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3 (derived from geotk-3.18)
+ * @version 0.3
+ * @module
+ *
+ * @see <a href="http://jira.geotoolkit.org/browse/GEOTK-165">GEOTK-165</a>
+ */
+@DependsOn(NilReasonMarshallingTest.class)
+public final strictfp class ObjectReferenceMarshallingTest extends XMLTestCase {
+    /**
+     * A random UUID for the tests in this class.
+     */
+    private static final String UUID_VALUE = "f8f5fcb1-d57b-4013-b3a4-4eaa40df6dcf";
+
+    /**
+     * A XML with a {@code uuid} identifier in the {@code <gmd:CI_Series>} element.
+     */
+    private static final String IDENTIFIED_XML =
+            "<gmd:CI_Citation xmlns:gmd=\""   + Namespaces.GMD + '"' +
+                            " xmlns:gco=\""   + Namespaces.GCO + '"' +
+                            " xmlns:xlink=\"" + Namespaces.XLINK + "\">\n" +
+            "  <gmd:title>\n" +
+            "    <gco:CharacterString>My data</gco:CharacterString>\n" +
+            "  </gmd:title>\n" +
+            "  <gmd:series>\n" +
+            "    <gmd:CI_Series uuid=\"" + UUID_VALUE + "\">\n" +
+            "      <gmd:name>\n" +
+            "        <gco:CharacterString>My aggregate dataset</gco:CharacterString>\n"
+
+            "      </gmd:name>\n" +
+            "    </gmd:CI_Series>\n" +
+            "  </gmd:series>\n" +
+            "</gmd:CI_Citation>";
+
+    /**
+     * A XML with a {@code uuidref} identifier in the {@code <gmd:series>} element.
+     * This XML declares the method body anyway, which is kind of contradictory with usage
of reference.
+     */
+    private static final String REFERENCED_XML_WITH_BODY =
+            "<gmd:CI_Citation xmlns:gmd=\""   + Namespaces.GMD   + '"' +
+                            " xmlns:gco=\""   + Namespaces.GCO   + '"' +
+                            " xmlns:xlink=\"" + Namespaces.XLINK + "\">\n" +
+            "  <gmd:title>\n" +
+            "    <gco:CharacterString>My data</gco:CharacterString>\n" +
+            "  </gmd:title>\n" +
+            "  <gmd:series uuidref=\"" + UUID_VALUE + "\">\n" +
+            "    <gmd:CI_Series>\n" +
+            "      <gmd:name>\n" +
+            "        <gco:CharacterString>My aggregate dataset</gco:CharacterString>\n"
+
+            "      </gmd:name>\n" +
+            "    </gmd:CI_Series>\n" +
+            "  </gmd:series>\n" +
+            "</gmd:CI_Citation>";
+
+    /**
+     * A XML with a {@code uuidref} identifier in the {@code <gmd:series>} element.
+     */
+    private static final String REFERENCED_XML =
+            "<gmd:CI_Citation xmlns:gmd=\""   + Namespaces.GMD   + '"' +
+                            " xmlns:gco=\""   + Namespaces.GCO   + '"' +
+                            " xmlns:xlink=\"" + Namespaces.XLINK + "\">\n" +
+            "  <gmd:title>\n" +
+            "    <gco:CharacterString>My data</gco:CharacterString>\n" +
+            "  </gmd:title>\n" +
+            "  <gmd:series uuidref=\"" + UUID_VALUE + "\"/>\n" +
+            "</gmd:CI_Citation>";
+
+    /**
+     * Tests (un)marshalling of an object identified by the {@code uuid} attribute.
+     * The element of interest for this test is the {@code "uuid"} attribute value
+     * in the {@code <gmd:CI_Series>} element of the following XML fragment:
+     *
+     * {@preformat xml
+     *   <gmd:CI_Citation>
+     *     <gmd:title>
+     *       <gco:CharacterString>My data</gco:CharacterString>
+     *     </gmd:title>
+     *     <gmd:series>
+     *       <gmd:CI_Series uuid="f8f5fcb1-d57b-4013-b3a4-4eaa40df6dcf">
+     *         <gmd:name>
+     *           <gco:CharacterString>My aggregate dataset</gco:CharacterString>
+     *         </gmd:name>
+     *       </gmd:CI_Series>
+     *     </gmd:series>
+     *   </gmd:CI_Citation>
+     * }
+     *
+     * On an implementation note, the {@code uuid} and other attributes of the {@code <gmd:CI_Series>}
+     * elements are handled by {@link org.apache.sis.internal.jaxb.gco.PropertyType}.
+     *
+     * @throws JAXBException Should never happen.
+     */
+    @Test
+    public void testIdentification() throws JAXBException {
+        final Citation citation = (Citation) XML.unmarshal(IDENTIFIED_XML);
+        assertEquals("title", "My data", citation.getTitle().toString());
+        /*
+         * Programmatic verification of the Series properties,
+         * which is the main object of interest in this test.
+         */
+        final Series series = citation.getSeries();
+        assertFalse("Unexpected proxy", Proxy.isProxyClass(series.getClass()));
+        assertInstanceOf("Expected IdentifiedObject", IdentifiedObject.class, series);
+        final IdentifierMap map = ((IdentifiedObject) series).getIdentifierMap();
+        assertEquals("series", "My aggregate dataset",  series.getName().toString());
+        assertNull  ("href", map.get(IdentifierSpace.HREF));
+        assertEquals(UUID_VALUE, String.valueOf(map.get(IdentifierSpace.UUID)));
+        /*
+         * Marshal the object back to XML and compare with the original string
+         * supplied to this method.
+         */
+        final String actual = XML.marshal(citation);
+        assertXmlEquals(IDENTIFIED_XML, actual, "xmlns:*");
+        assertEquals(citation, XML.unmarshal(actual));
+    }
+
+    /**
+     * Tests (un)marshalling of an object referenced by a {@code uuidref} attribute.
+     * This test does not try to resolve the reference, but only check that the identifier
is properly saved.
+     *
+     * <p>The element of interest for this test is the {@code "uuidref"} part
+     * in the {@code <gmd:series>} property of the following XML fragment:</p>
+     *
+     * {@preformat xml
+     *   <gmd:CI_Citation>
+     *     <gmd:title>
+     *       <gco:CharacterString>My data</gco:CharacterString>
+     *     </gmd:title>
+     *     <gmd:series uuidref="f8f5fcb1-d57b-4013-b3a4-4eaa40df6dcf">
+     *       <gmd:CI_Series>
+     *         <gmd:name>
+     *           <gco:CharacterString>My aggregate dataset</gco:CharacterString>
+     *         </gmd:name>
+     *       </gmd:CI_Series>
+     *     </gmd:series>
+     *   </gmd:CI_Citation>
+     * }
+     *
+     * On an implementation note, the {@code uuidref}, {@code xlink:href} and other attributes
of the
+     * {@code <gmd:series>} element are handled by {@link org.apache.sis.internal.jaxb.gco.PropertyType}.
+     *
+     * @throws JAXBException Should never happen.
+     */
+    @Test
+    public void testReference() throws JAXBException {
+        final Citation citation = (Citation) XML.unmarshal(REFERENCED_XML_WITH_BODY);
+        assertEquals("Citation.title",  "My data", citation.getTitle().toString());
+        /*
+         * Programmatic verification of the Series properties,
+         * which is the main object of interest in this test.
+         */
+        final Series series = citation.getSeries();
+        assertInstanceOf("Citation.series", IdentifiedObject.class, series);
+        assertFalse     ("Citation.series.isProxy", Proxy.isProxyClass(series.getClass()));
+        assertEquals    ("Citation.series.name", "My aggregate dataset", series.getName().toString());
+        final IdentifierMap map = ((IdentifiedObject) series).getIdentifierMap();
+        assertNull  ("href",             map.get(IdentifierSpace.HREF));
+        assertEquals("uuid", UUID_VALUE, map.get(IdentifierSpace.UUID));
+        /*
+         * Marshal the object back to XML and compare with the expected result. The result
shall be
+         * slightly different than the original XML, since the UUID in the <gmd:series>
element shall
+         * move to the <gmd:CI_Series> element. This is the expected behavior because
we have a fully
+         * constructed object, not a reference to an object defined elsewhere.
+         */
+        final String actual = XML.marshal(citation);
+        assertXmlEquals(IDENTIFIED_XML, actual, "xmlns:*");
+        assertEquals(citation, XML.unmarshal(actual));
+    }
+
+    /**
+     * The same test than {@link #testReference()}, except that the {@code <gmd:CI_Series>}
element is empty.
+     * This situation shall force the creation of a new, empty, element for storing the {@code
uuidref} information.
+     *
+     * @throws JAXBException Should never happen.
+     */
+    @Test
+    @DependsOnMethod("testReference")
+    public void testReferenceInEmptyObject() throws JAXBException {
+        final Citation citation = (Citation) XML.unmarshal(REFERENCED_XML);
+        assertEquals("Citation.title",  "My data", citation.getTitle().toString());
+        /*
+         * Programmatic verification of the Series properties,
+         * which is the main object of interest in this test.
+         */
+        final Series series = citation.getSeries();
+        assertInstanceOf("Citation.series", IdentifiedObject.class, series);
+        assertNull      ("Citation.series.name", series.getName());
+        assertTrue      ("Citation.series.isProxy", Proxy.isProxyClass(series.getClass()));
+        assertInstanceOf("Citation.series", NilObject.class, series);
+        assertEquals    ("Series[{gco:uuid=“" + UUID_VALUE + "”}]", series.toString());
+        final IdentifierMap map = ((IdentifiedObject) series).getIdentifierMap();
+        assertNull  ("href",             map.get(IdentifierSpace.HREF));
+        assertEquals("uuid", UUID_VALUE, map.get(IdentifierSpace.UUID));
+        /*
+         * Marshal the object back to XML and compare with the expected result.
+         */
+        final String actual = XML.marshal(citation);
+        assertXmlEquals(REFERENCED_XML, actual, "xmlns:*");
+        assertEquals(citation, XML.unmarshal(actual));
+    }
+}

Propchange: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/xml/ObjectReferenceMarshallingTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/xml/ObjectReferenceMarshallingTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java?rev=1497820&r1=1497819&r2=1497820&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -17,14 +17,16 @@
 package org.apache.sis.internal.jaxb.gco;
 
 import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
 import org.apache.sis.xml.XLink;
 import org.apache.sis.xml.IdentifierMap;
 import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.xml.IdentifiedObject;
 import org.apache.sis.xml.ReferenceResolver;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.internal.jaxb.Context;
-import org.apache.sis.internal.jaxb.IdentifierMapAdapter;
 import org.apache.sis.internal.jaxb.SpecializedIdentifier;
 
 
@@ -76,6 +78,9 @@ final class ObjectReference {
 
     /**
      * Creates an object reference initialized to the given value.
+     *
+     * @see ReferenceResolver#canSubstituteByReference(MarshalContext, Class, Object, UUID)
+     * @see ReferenceResolver#canSubstituteByReference(MarshalContext, Class, Object, XLink)
      */
     ObjectReference(final UUID uuid, final String anyUUID, final XLink link) {
         this.uuid    = uuid;
@@ -132,34 +137,48 @@ final class ObjectReference {
             // However if both are present, assign the identifiers to that instance.
             if (metadata instanceof IdentifiedObject) {
                 final IdentifierMap map = ((IdentifiedObject) metadata).getIdentifierMap();
-                if (uuid  != null) putInto(map, IdentifierSpace.UUID,  uuid);
-                if (xlink != null) putInto(map, IdentifierSpace.XLINK, xlink);
+                putInto(context, map, IdentifierSpace.UUID,  uuid);
+                putInto(context, map, IdentifierSpace.XLINK, xlink);
             }
         }
         return metadata;
     }
 
     /**
-     * Adds a new identifier into the given map. This method is a shortcut which bypass the
check
-     * for previous values associated to same the authority. It is okay only when constructing
-     * new instances, for example at XML unmarshalling time.
+     * Adds a new identifier into the given map, if non null. No previous value should exist
in normal situation.
+     * However a previous value may exit in unusual (probably not very valid) XML, as in
the following example:
+     *
+     * {@preformat xml
+     *   <gmd:CI_Citation>
+     *     <gmd:series uuidref="f8f5fcb1-d57b-4013-b3a4-4eaa40df6dcf">
+     *       <gmd:CI_Series uuid="f8f5fcb1-d57b-4013-b3a4-4eaa40df6dcf">
+     *         ...
+     *       </gmd:CI_Series>
+     *     </gmd:series>
+     *   </gmd:CI_Citation>
+     * }
+     *
+     * In such situation, this method is silent if the two identifiers are equal, or logs
a warning and restores
+     * the previous value if they are not equal. The previous value is the "{@code uuid}"
attribute, which is
+     * assumed more closely tied to the actual metadata than the {@code uuidref} attribute.
      *
      * @param map       The map in which to write the identifier.
      * @param authority The identifier authority.
      * @param value     The identifier value, or {@code null} if not yet defined.
      */
-    private static <T> void putInto(final IdentifierMap map, final IdentifierSpace<T>
authority, final T value) {
-        if (map instanceof IdentifierMapAdapter) {
-            final SpecializedIdentifier<T> identifier = new SpecializedIdentifier<>(authority,
value);
-            /*
-             * If the following assert statement appears to fail in practice, then remove
-             * completly this method and use the public putSpecialized(…) method instead.
-             * Note: usage of 'put' is for having the compiler to check the key type.
-             */
-            assert map.put(authority, null) == null : identifier;
-            ((IdentifierMapAdapter) map).identifiers.add(identifier);
-        } else {
-            map.putSpecialized(authority, value);
+    private static <T> void putInto(final Context context, final IdentifierMap map,
+            final IdentifierSpace<T> authority, final T value)
+    {
+        if (value != null) {
+            final T previous = map.putSpecialized(authority, value);
+            if (previous != null && !previous.equals(value)) {
+                final LogRecord record = Errors.getResources((context != null) ? context.getLocale()
: null)
+                        .getLogRecord(Level.WARNING, Errors.Keys.InconsistentAttribute_2,
authority.getName(), value);
+                record.setSourceClassName(IdentifierMap.class.getName());
+                record.setSourceMethodName("putSpecialized");
+                Context.warningOccured(context, map, record);
+                map.putSpecialized(authority, previous);
+            }
         }
     }
 }

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java?rev=1497820&r1=1497819&r2=1497820&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -165,7 +165,12 @@ public abstract class PropertyType<Value
                 if (uuid == null) {
                     uuid = ObjectReference.toUUID(context, anyUUID); // May still null.
                 }
-                // Check if the user gives us the permission to use those identifiers.
+                /*
+                 * Check if the user gives us the permission to use reference to those identifiers.
+                 * If not, forget them. Information will actually not be lost, since the
same identifiers
+                 * will be provided by private methods in ISOMetadata. If we do nott clear
the identifiers
+                 * here, they would appear twice in the XML output.
+                 */
                 if (uuid != null && !resolver.canSubstituteByReference(context, type,
metadata, uuid)) {
                     uuid = null;
                 }
@@ -250,15 +255,9 @@ public abstract class PropertyType<Value
      * future implementations.
      *
      * @return {@code true} if the wrapped metadata should not be marshalled.
-     *
-     * @see #getElement()
      */
     protected final boolean skip() {
-        if (metadata instanceof NilObject) {
-            return true;
-        }
-        final Object ref = reference;
-        return (ref instanceof ObjectReference) && ((ObjectReference) ref).anyUUID
!= null;
+        return (metadata instanceof NilObject) || (reference instanceof ObjectReference);
     }
 
     /**
@@ -269,7 +268,7 @@ public abstract class PropertyType<Value
      * @return the current value, or {@code null} if none.
      * @category gco:ObjectReference
      */
-    @XmlAttribute(name = "uuidref", namespace = Namespaces.GCO)
+    @XmlAttribute(name = "uuidref")  // Defined in "gco" as unqualified attribute.
     public final String getUUIDREF() {
         final ObjectReference ref = reference(false);
         return (ref != null) ? ref.anyUUID : null;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java?rev=1497820&r1=1497819&r2=1497820&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -130,9 +130,9 @@ public class ReferenceResolver {
      * SIS can not know if the metadata shall be fully marshalled or not.
      * Such information needs to be provided by the application.
      *
-     * <p>The default implementation conservatively returns {@code false} in every
cases.
-     * Subclasses can override this method if they know whether the receiver will be able
-     * to resolve such references.</p>
+     * <p>The default implementation conservatively returns {@code false} in every
cases except for instances of
+     * {@link NilObject}, since the later exist only for carrying the {@code gco} and {@code
xlink} attributes.
+     * Subclasses can override this method if they know whether the receiver will be able
to resolve the reference.</p>
      *
      * @param  <T>     The compile-time type of the {@code type} argument.
      * @param  context Context (GML version, locale, <i>etc.</i>) of the (un)marshalling
process.
@@ -144,7 +144,7 @@ public class ReferenceResolver {
      *         instead than marshalling the given metadata.
      */
     public <T> boolean canSubstituteByReference(final MarshalContext context, final
Class<T> type, final T object, final UUID uuid) {
-        return false;
+        return (object instanceof NilObject);
     }
 
     /**
@@ -154,9 +154,9 @@ public class ReferenceResolver {
      * SIS can not know if the metadata shall be fully marshalled or not.
      * Such information needs to be provided by the application.
      *
-     * <p>The default implementation conservatively returns {@code false} in every
cases.
-     * Subclasses can override this method if they know whether the receiver will be able
-     * to resolve such references.</p>
+     * <p>The default implementation conservatively returns {@code false} in every
cases except for instances of
+     * {@link NilObject}, since the later exist only for carrying the {@code gco} and {@code
xlink} attributes.
+     * Subclasses can override this method if they know whether the receiver will be able
to resolve the reference.</p>
      *
      * @param  <T>     The compile-time type of the {@code type} argument.
      * @param  context Context (GML version, locale, <i>etc.</i>) of the (un)marshalling
process.
@@ -168,7 +168,7 @@ public class ReferenceResolver {
      *         instead than marshalling the given metadata.
      */
     public <T> boolean canSubstituteByReference(final MarshalContext context, final
Class<T> type, final T object, final XLink link) {
-        return false;
+        return (object instanceof NilObject);
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/jaxb/gco/PropertyTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/jaxb/gco/PropertyTypeTest.java?rev=1497820&r1=1497819&r2=1497820&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/jaxb/gco/PropertyTypeTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/jaxb/gco/PropertyTypeTest.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -21,6 +21,7 @@ import org.apache.sis.util.iso.SimpleInt
 import org.apache.sis.xml.XLink;
 import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.test.mock.ReferenceResolverMock;
+import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.XMLTestCase;
 import org.junit.Test;
@@ -55,6 +56,17 @@ public final strictfp class PropertyType
     }
 
     /**
+     * Creates a dummy XLink.
+     */
+    private static XLink createXLink() {
+        final XLink link = new XLink();
+        link.setShow(XLink.Show.REPLACE);
+        link.setActuate(XLink.Actuate.ON_LOAD);
+        link.setTitle(new SimpleInternationalString("myResult"));
+        return link;
+    }
+
+    /**
      * Tests the construction of a plain property (no identifier).
      *
      * @throws Exception Should never happen.
@@ -83,11 +95,12 @@ public final strictfp class PropertyType
 
     /**
      * Tests the construction of an object containing {@code UUID} and {@code XLink} references,
-     * which shall be discarded because didn't gave us the authorization to use them.
+     * but in a context where the user didn't gave us the authorization to use them.
      *
      * @throws Exception Should never happen.
      */
     @Test
+    @DependsOnMethod({"testWithUUID", "testWithXLink"})
     public void testWithDiscardedReferences() throws Exception {
         final UUID  uuid = UUID.randomUUID();
         final XLink link = createXLink();
@@ -100,10 +113,12 @@ public final strictfp class PropertyType
 
     /**
      * Tests the construction of an object containing a {@link UUID}.
+     * The {@code XLink} is allowed to replace the object definition in the XML to be marshalled.
      *
      * @throws Exception Should never happen.
      */
     @Test
+    @DependsOnMethod("testWithNoReference")
     public void testWithUUID() throws Exception {
         final UUID uuid = UUID.randomUUID();
         metadata.getIdentifierMap().putSpecialized(IdentifierSpace.UUID, uuid);
@@ -118,25 +133,17 @@ public final strictfp class PropertyType
         assertNull  ("title",         property.getTitle());
         assertNull  ("show",          property.getShow());
         assertNull  ("actuate",       property.getActuate());
-    }
-
-    /**
-     * Creates a dummy XLink.
-     */
-    private static XLink createXLink() {
-        final XLink link = new XLink();
-        link.setShow(XLink.Show.REPLACE);
-        link.setActuate(XLink.Actuate.ON_LOAD);
-        link.setTitle(new SimpleInternationalString("myResult"));
-        return link;
+        assertTrue  ("skip",          property.skip());
     }
 
     /**
      * Tests the construction of an object containing a {@link XLink}.
+     * The {@code XLink} is allowed to replace the object definition in the XML to be marshalled.
      *
      * @throws Exception Should never happen.
      */
     @Test
+    @DependsOnMethod("testWithNoReference")
     public void testWithXLink() throws Exception {
         final XLink link = createXLink();
         metadata.getIdentifierMap().putSpecialized(IdentifierSpace.XLINK, link);
@@ -151,5 +158,6 @@ public final strictfp class PropertyType
         assertEquals("myResult",            property.getTitle());
         assertEquals(XLink.Show.REPLACE,    property.getShow());
         assertEquals(XLink.Actuate.ON_LOAD, property.getActuate());
+        assertTrue  ("skip",                property.skip());
     }
 }

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/mock/ReferenceResolverMock.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/mock/ReferenceResolverMock.java?rev=1497820&r1=1497819&r2=1497820&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/mock/ReferenceResolverMock.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/mock/ReferenceResolverMock.java
[UTF-8] Fri Jun 28 15:50:31 2013
@@ -53,6 +53,9 @@ public final strictfp class ReferenceRes
      *     }
      * }
      *
+     * Alternatively, the {@code finally} block can be replaced by a call to {@code context.finish()}
+     * in a method annotated by {@link org.junit.After}.
+     *
      * @param  marshalling {@code true} for marshalling, or {@code false} for unmarshalling.
      * @return The (un)marshalling context.
      */



Mime
View raw message