Author: desruisseaux
Date: Thu Oct 8 12:52:50 2015
New Revision: 1707518
URL: http://svn.apache.org/viewvc?rev=1707518&view=rev
Log:
Check also in the list of aliases for inferring a gml:id.
Give precedence of gml:id over uuid or other xlink.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1707518&r1=1707517&r2=1707518&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
[UTF-8] Thu Oct 8 12:52:50 2015
@@ -945,10 +945,19 @@ public class AbstractIdentifiedObject ex
}
}
/*
- * In last ressort, append code without codespace since the name are often verbose.
- * If that name is also used, append a number until we find a free ID.
+ * 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 (name == null || !appendUnicodeIdentifier(id, '-', name.getCode(), ":", false))
{
+ if (alias != null) {
+ for (final GenericName alias : alias) {
+ if (appendUnicodeIdentifier(id, '-', alias.toString(), ":", false))
{
+ break;
+ }
+ }
+ }
+ }
+ if (id.length() != 0) {
candidate = id.toString();
if (!Context.setObjectForID(context, this, candidate)) {
final int s = id.append('-').length();
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java?rev=1707518&r1=1707517&r2=1707518&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
[UTF-8] Thu Oct 8 12:52:50 2015
@@ -210,15 +210,18 @@ public final strictfp class AbstractIden
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;
+ 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();
}
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java?rev=1707518&r1=1707517&r2=1707518&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/PropertyType.java
[UTF-8] Thu Oct 8 12:52:50 2015
@@ -185,12 +185,25 @@ public abstract class PropertyType<Value
return;
}
}
- metadata = value; // Non-null only after we verified that not a NilObject.
-
+ /*
+ * Verifies if the object to marshall can be replaced by a xlink or uuidref.
+ * First, check if we can use a xlink:href="#foo" reference to a gml:id="foo".
+ * Only if no gml:id was found, check for user-defined xlink or uuidref.
+ */
@SuppressWarnings("OverridableMethodCallDuringObjectConstruction")
final Class<BoundType> type = getBoundType();
final Context context = Context.current();
final ReferenceResolver resolver = Context.resolver(context);
+ final String id = Context.getObjectID(context, value);
+ if (id != null && resolver.canSubstituteByReference(context, type, value,
id)) try {
+ final XLink link = new XLink();
+ link.setHRef(new URI(null, null, id));
+ reference = new ObjectReference(null, link);
+ return;
+ } catch (URISyntaxException e) {
+ Context.warningOccured(context, getClass(), "<init>", e, true);
+ }
+ metadata = value; // Non-null only after we verified that not a NilObject or xlink:href="#foo".
if (value instanceof IdentifiedObject) {
/*
* Get the identifiers as full UUID or XLink objects. We do not use the more
permissive methods
@@ -241,21 +254,6 @@ public abstract class PropertyType<Value
}
}
}
- /*
- * If the object to marshall has not been replaced by a user-specified {@code uuidref}
or {@code xlink},
- * verify if we already marshalled that object previously with a {@code gml:id} attribute.
- */
- if (metadata != null) {
- final String id = Context.getObjectID(context, metadata);
- if (id != null && resolver.canSubstituteByReference(context, type, value,
id)) try {
- final XLink link = new XLink();
- link.setHRef(new URI(null, null, id));
- reference = new ObjectReference(null, link);
- metadata = null; // Clear only after success.
- } catch (URISyntaxException e) {
- Context.warningOccured(context, getClass(), "<init>", e, true);
- }
- }
}
/**
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java?rev=1707518&r1=1707517&r2=1707518&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
[UTF-8] Thu Oct 8 12:52:50 2015
@@ -74,8 +74,7 @@ public class ReferenceResolver {
*
* @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.
- * @param type The type of object to be unmarshalled as an <strong>interface</strong>.
- * This is usually a <a href="http://www.geoapi.org">GeoAPI</a>
interface.
+ * @param type The type of object to be unmarshalled, often as a GeoAPI interface.
* @param identifiers An arbitrary amount of identifiers. For each identifier, the
* {@linkplain Identifier#getAuthority() authority} is typically (but not
* necessarily) one of the constants defined in {@link IdentifierSpace}.
@@ -97,8 +96,7 @@ public class ReferenceResolver {
*
* @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.
- * @param type The type of object to be unmarshalled as an <strong>interface</strong>.
- * This is usually a <a href="http://www.geoapi.org">GeoAPI</a>
interface.
+ * @param type The type of object to be unmarshalled, often as a GeoAPI interface.
* @param uuid The {@code uuid} attributes.
* @return An object of the given type for the given {@code uuid} attribute, or {@code
null} if none.
*/
@@ -122,7 +120,7 @@ public class ReferenceResolver {
*
* @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.
- * @param type The type of object to be unmarshalled, often as an interface.
+ * @param type The type of object to be unmarshalled, often as a GeoAPI interface.
* @param link The {@code xlink} attributes.
* @return An object of the given type for the given {@code xlink} attribute, or {@code
null} if none.
*/
@@ -140,6 +138,43 @@ public class ReferenceResolver {
}
/**
+ * Returns {@code true} if the marshaller can use a {@code xlink:href="#id"} reference
to the given object
+ * instead than writing the full XML element. This method is invoked by the marshaller
when:
+ *
+ * <ul>
+ * <li>The given object has already been marshalled in the same XML document.</li>
+ * <li>The marshalled object had a {@code gml:id} attribute
+ * <ul>
+ * <li>either specified explicitely by
+ * <code>{@linkplain IdentifierMap#put IdentifierMap.put}({@linkplain IdentifierSpace#ID},
id)</code></li>
+ * <li>or inferred automatically by the marshalled object
+ * (e.g. {@link org.apache.sis.referencing.AbstractIdentifiedObject}).</li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * Note that if this method returns {@code true}, then the use of {@code xlink:href="#id"}
will have
+ * precedence over {@linkplain #canSubstituteByReference(MarshalContext, Class, Object,
UUID) UUID}
+ * and {@linkplain #canSubstituteByReference(MarshalContext, Class, Object, XLink) XLink
alternatives}.
+ *
+ * <p>The default implementation unconditionally returns {@code true}.
+ * Subclasses can override this method if they want to filter which objects to declare
by 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.
+ * @param type The type of object to be unmarshalled, often as a GeoAPI interface.
+ * @param object The object to be marshalled.
+ * @param id The {@code gml:id} value of the object to be marshalled.
+ * @return {@code true} if the marshaller can use the {@code xlink:href="#id"} attribute
+ * instead than marshalling the given object.
+ *
+ * @since 0.7
+ */
+ public <T> boolean canSubstituteByReference(final MarshalContext context, final
Class<T> type, final T object, final String id) {
+ return true;
+ }
+
+ /**
* Returns {@code true} if the marshaller can use a reference to the given object
* instead than writing the full XML element. This method is invoked when an object to
* be marshalled has a UUID identifier. Because those object may be defined externally,
@@ -156,7 +191,7 @@ public class ReferenceResolver {
*
* @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.
- * @param type The type of object to be unmarshalled, often as an interface.
+ * @param type The type of object to be unmarshalled, often as a GeoAPI interface.
* @param object The object to be marshalled.
* @param uuid The unique identifier of the object to be marshalled.
* @return {@code true} if the marshaller can use the {@code uuidref} attribute
@@ -183,8 +218,7 @@ public class ReferenceResolver {
*
* @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.
- * @param type The type of object to be marshalled as an <strong>interface</strong>.
- * This is usually a <a href="http://www.geoapi.org">GeoAPI</a>
interface.
+ * @param type The type of object to be unmarshalled, often as a GeoAPI interface.
* @param object The object to be marshalled.
* @param link The reference of the object to be marshalled.
* @return {@code true} if the marshaller can use the {@code xlink:href} attribute
@@ -195,35 +229,6 @@ public class ReferenceResolver {
}
/**
- * Returns {@code true} if the marshaller can use a {@code xlink:href="#id"} reference
to the given object
- * instead than writing the full XML element. This method is invoked by the marshaller
when all the following
- * conditions are meet:
- *
- * <ul>
- * <li>The given object has already been marshalled in the same XML document.</li>
- * <li>The marshalled object had a {@code gml:id} attribute.</li>
- * <li>Other {@code canSubstituteByReference(context, type, object, …)} methods
returned {@code false}.</li>
- * </ul>
- *
- * The default implementation unconditionally returns {@code true}.
- * Subclasses can override this method if they want to filter wish objects to declare
by reference.
- *
- * @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.
- * @param type The type of object to be marshalled as an <strong>interface</strong>.
- * This is usually a <a href="http://www.geoapi.org">GeoAPI</a>
interface.
- * @param object The object to be marshalled.
- * @param id The {@code gml:id} value of the object to be marshalled.
- * @return {@code true} if the marshaller can use the {@code xlink:href="#id"} attribute
- * instead than marshalling the given object.
- *
- * @since 0.7
- */
- public <T> boolean canSubstituteByReference(final MarshalContext context, final
Class<T> type, final T object, final String id) {
- return true;
- }
-
- /**
* Returns the {@code <gmx:Anchor>} to use for the given text, or {@code null}
if none.
* Anchors can appear in ISO 19139 documents where we would normally expect a character
* sequence. For example:
|