sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1778893 [1/3] - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/metadata/ sis-metadata/src/main/java/org/apache/sis/metadata/iso/ sis-metadata/src/test/java/org/apache/sis/metadata/ sis-utility/src/main/java/org/apach...
Date Sun, 15 Jan 2017 09:20:19 GMT
Author: desruisseaux
Date: Sun Jan 15 09:20:18 2017
New Revision: 1778893

URL: http://svn.apache.org/viewvc?rev=1778893&view=rev
Log:
More accurate detection of cyclic graphs in TreeTableFormat by looking not only at the metadata instance, but also to in which property the metadata appears.
The intend is to support classes that implement more than one metadata interfaces, like the Metadata class used internally by the GPX datastore.
This work required that we clarify the 'equals(Object)' and 'hashCode()' method contract in TreeTable.Node interface.
As a side effect, this commit contains javadoc reformatting of various classes that were reviewed (but usually not significantly modified) as part of this work. 

Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/AbstractMetadataTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/ModifiableIdentifierMap.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.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/internal/jaxb/gml/GMLAdapter.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/CitationConstant.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/ReferenceResolver.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -235,9 +235,9 @@ class PropertyAccessor {
     /**
      * Creates a new property accessor for the specified metadata implementation.
      *
-     * @param  standard       The standard which define the {@code type} interface.
-     * @param  type           The interface implemented by the metadata class.
-     * @param  implementation The class of metadata implementations, or {@code type} if none.
+     * @param  standard        the standard which define the {@code type} interface.
+     * @param  type            the interface implemented by the metadata class.
+     * @param  implementation  the class of metadata implementations, or {@code type} if none.
      */
     PropertyAccessor(final Citation standard, final Class<?> type, final Class<?> implementation) {
         assert type.isAssignableFrom(implementation) : implementation;
@@ -398,9 +398,9 @@ class PropertyAccessor {
      * Returns the getters. The returned array should never be modified,
      * since it may be shared among many instances of {@code PropertyAccessor}.
      *
-     * @param  type The metadata interface.
-     * @param  implementation The class of metadata implementations, or {@code type} if none.
-     * @return The getters declared in the given interface (never {@code null}).
+     * @param  type            the metadata interface.
+     * @param  implementation  the class of metadata implementations, or {@code type} if none.
+     * @return the getters declared in the given interface (never {@code null}).
      */
     private static Method[] getGetters(final Class<?> type, final Class<?> implementation) {
         /*
@@ -492,10 +492,10 @@ class PropertyAccessor {
      * Returns the index of the specified property, or -1 if none.
      * The search is case-insensitive.
      *
-     * @param  name The name of the property to search.
-     * @param  mandatory Whether this method shall throw an exception or return {@code -1}
+     * @param  name       the name of the property to search.
+     * @param  mandatory  whether this method shall throw an exception or return {@code -1}
      *         if the given name is not found.
-     * @return The index of the given name, or -1 if none and {@code mandatory} is {@code false}.
+     * @return the index of the given name, or -1 if none and {@code mandatory} is {@code false}.
      * @throws IllegalArgumentException if the name is not found and {@code mandatory} is {@code true}.
      */
     final int indexOf(final String name, final boolean mandatory) {
@@ -521,9 +521,9 @@ class PropertyAccessor {
     /**
      * Returns the name of the property at the given index, or {@code null} if none.
      *
-     * @param  index The index of the property for which to get the name.
-     * @param  keyPolicy The kind of name to return.
-     * @return The name of the given kind at the given index, or {@code null} if the index is out of bounds.
+     * @param  index      the index of the property for which to get the name.
+     * @param  keyPolicy  the kind of name to return.
+     * @return the name of the given kind at the given index, or {@code null} if the index is out of bounds.
      */
     @SuppressWarnings("fallthrough")
     @Workaround(library="JDK", version="1.7") // Actually apply to String.intern() below.
@@ -567,9 +567,9 @@ class PropertyAccessor {
      *   <li>If the property is a collection, then returns the type of collection elements.</li>
      * </ul>
      *
-     * @param  index The index of the property.
-     * @param  policy The kind of type to return.
-     * @return The type of property values, or {@code null} if unknown.
+     * @param  index   the index of the property.
+     * @param  policy  the kind of type to return.
+     * @return the type of property values, or {@code null} if unknown.
      */
     Class<?> type(final int index, final TypeValuePolicy policy) {
         if (index >= 0 && index < allCount) {
@@ -623,8 +623,8 @@ class PropertyAccessor {
      * Returns the information for the property at the given index.
      * The information are created when first needed.
      *
-     * @param  index The index of the property for which to get the information.
-     * @return The information for the property at the given index, or {@code null} if the index is out of bounds.
+     * @param  index  the index of the property for which to get the information.
+     * @return the information for the property at the given index, or {@code null} if the index is out of bounds.
      *
      * @see PropertyInformation
      */
@@ -646,8 +646,10 @@ class PropertyAccessor {
             try {
                 range = implementation.getMethod(getter.getName(), (Class<?>[]) null).getAnnotation(ValueRange.class);
             } catch (NoSuchMethodException error) {
-                // Should never happen, since the implementation class
-                // implements the interface where the getter come from.
+                /*
+                 * Should never happen, since the implementation class
+                 * implements the interface where the getter come from.
+                 */
                 throw new AssertionError(error);
             }
             information = new PropertyInformation<>(standard, name, getter, elementType, range);
@@ -669,10 +671,10 @@ class PropertyAccessor {
      * so it is safe to invoke this method even if {@link #indexOf(String, boolean)}
      * returned -1.
      *
-     * @param  index The index of the property for which to get a value.
-     * @param  metadata The metadata object to query.
-     * @return The value, or {@code null} if none or if the given is out of bounds.
-     * @throws BackingStoreException If the implementation threw a checked exception.
+     * @param  index     the index of the property for which to get a value.
+     * @param  metadata  the metadata object to query.
+     * @return the value, or {@code null} if none or if the given is out of bounds.
+     * @throws BackingStoreException if the implementation threw a checked exception.
      */
     Object get(final int index, final Object metadata) throws BackingStoreException {
         return (index >= 0 && index < allCount) ? get(getters[index], metadata) : null;
@@ -684,9 +686,9 @@ class PropertyAccessor {
      * However if a checked exception is throw anyway (maybe in user defined "standard"), it
      * will be wrapped in a {@link BackingStoreException}. Unchecked exceptions are propagated.
      *
-     * @param  method The method to use for the query.
-     * @param  metadata The metadata object to query.
-     * @throws BackingStoreException If the implementation threw a checked exception.
+     * @param  method    the method to use for the query.
+     * @param  metadata  the metadata object to query.
+     * @throws BackingStoreException if the implementation threw a checked exception.
      *
      * @see #set(Method, Object, Object[])
      */
@@ -735,12 +737,12 @@ class PropertyAccessor {
      * However the given value will be silently discarded, so index out-of-bounds shall be used only
      * in the context of {@code remove} operations (this is not verified).</p>
      *
-     * @param  index       The index of the property to set.
-     * @param  metadata    The metadata object on which to set the value.
-     * @param  value       The new value.
-     * @param  mode        Whether this method should first fetches the old value,
-     *                     as one of the {@code RETURN_*} constants.
-     * @return The old value, or {@code null} if {@code returnValue} was {@code RETURN_NULL}.
+     * @param  index     the index of the property to set.
+     * @param  metadata  the metadata object on which to set the value.
+     * @param  value     the new value.
+     * @param  mode      whether this method should first fetches the old value,
+     *                   as one of the {@code RETURN_*} constants.
+     * @return the old value, or {@code null} if {@code returnValue} was {@code RETURN_NULL}.
      * @throws UnmodifiableMetadataException if the property for the given key is read-only.
      * @throws ClassCastException if the given value is not of the expected type.
      * @throws BackingStoreException if the implementation threw a checked exception.
@@ -756,7 +758,7 @@ class PropertyAccessor {
             final Method setter = setters[index];
             if (setter != null) {
                 final Object oldValue;
-                final Object snapshot; // Copy of oldValue before modification.
+                final Object snapshot;                      // Copy of oldValue before modification.
                 switch (mode) {
                     case RETURN_NULL: {
                         oldValue = null;
@@ -822,10 +824,10 @@ class PropertyAccessor {
      * exception is throw anyway, then it will be wrapped in a {@link BackingStoreException}.
      * Unchecked exceptions are propagated.</p>
      *
-     * @param  setter    The method to use for setting the new value.
-     * @param  metadata  The metadata object to query.
-     * @param  newValues The argument to give to the method to be invoked.
-     * @throws BackingStoreException If the implementation threw a checked exception.
+     * @param  setter     the method to use for setting the new value.
+     * @param  metadata   the metadata object to query.
+     * @param  newValues  the argument to give to the method to be invoked.
+     * @throws BackingStoreException if the implementation threw a checked exception.
      *
      * @see #get(Method, Object)
      */
@@ -873,21 +875,21 @@ class PropertyAccessor {
      * those collections are live. However this method can be though as if the collections were
      * not live, since the caller will invoke the setter method with the collection anyway.
      *
-     * @param getter      The method to use for fetching the previous value.
-     * @param metadata    The metadata object to query and modify.
-     * @param oldValue    The value returned by {@code get(getter, metadata)}, or {@code null} if unknown.
-     *                    This parameter is only an optimization for avoiding to invoke the getter method
-     *                    twice if the value is already known.
-     * @param newValues   The argument to convert. The content of this array will be modified in-place.
-     *                    Current implementation requires an array of length 1, however this restriction
-     *                    may be relaxed in a future SIS version if needed.
-     * @param elementType The target type (if singleton) or the type of elements in the collection.
-     * @param append      If {@code true} and the value is a collection, then that collection will be added
-     *                    to any previously existing collection instead of replacing it.
-     * @return If the given value has been added to an existing collection, then whether that existing
+     * @param  getter       the method to use for fetching the previous value.
+     * @param  metadata     the metadata object to query and modify.
+     * @param  oldValue     the value returned by {@code get(getter, metadata)}, or {@code null} if unknown.
+     *                      This parameter is only an optimization for avoiding to invoke the getter method
+     *                      twice if the value is already known.
+     * @param  newValues    the argument to convert. The content of this array will be modified in-place.
+     *                      Current implementation requires an array of length 1, however this restriction
+     *                      may be relaxed in a future SIS version if needed.
+     * @param  elementType  the target type (if singleton) or the type of elements in the collection.
+     * @param  append       if {@code true} and the value is a collection, then that collection will be added
+     *                      to any previously existing collection instead of replacing it.
+     * @return if the given value has been added to an existing collection, then whether that existing
      *         collection has been modified as a result of this method call. Otherwise {@code null}.
      * @throws ClassCastException if the element of the {@code arguments} array is not of the expected type.
-     * @throws BackingStoreException If the implementation threw a checked exception.
+     * @throws BackingStoreException if the implementation threw a checked exception.
      */
     private Boolean convert(final Method getter, final Object metadata, Object oldValue, final Object[] newValues,
             Class<?> elementType, final boolean append) throws ClassCastException, BackingStoreException
@@ -914,16 +916,18 @@ class PropertyAccessor {
              */
             if (newValue instanceof Collection<?>) {
                 final Iterator<?> it = ((Collection<?>) newValue).iterator();
-                if (!it.hasNext()) { // If empty, process like null argument.
+                if (!it.hasNext()) {                            // If empty, process like null argument.
                     newValues[0] = null;
                     return null;
                 }
                 final Object next = it.next();
-                if (!it.hasNext()) { // Singleton
+                if (!it.hasNext()) {                            // Singleton
                     newValue = next;
                 }
-                // Other cases: let the collection unchanged. It is likely to
-                // cause an exception later. The message should be appropriate.
+                /*
+                 * Other cases: let the collection unchanged. It is likely to
+                 * cause an exception later. The message should be appropriate.
+                 */
             }
             targetType = Numbers.primitiveToWrapper(targetType);
         } else {
@@ -944,8 +948,8 @@ class PropertyAccessor {
              */
             final boolean isCollection = (newValue instanceof Collection<?>);
             final Object[] elements = isCollection ? ((Collection<?>) newValue).toArray() : new Object[] {newValue};
-            final List<Object> elementList = Arrays.asList(elements); // Converted later (see above comment).
-            newValue = elementList; // Still contains the same values, but now guaranteed to be a collection.
+            final List<Object> elementList = Arrays.asList(elements);         // Converted later (see above comment).
+            newValue = elementList;         // Still contains the same values, but now guaranteed to be a collection.
             Collection<?> addTo = null;
             if (!isCollection || append) {
                 if (oldValue == null) {
@@ -996,9 +1000,9 @@ class PropertyAccessor {
      * The array content is modified in-place. This method accepts an array instead than
      * a single value because the values to convert may be the content of a collection.
      *
-     * @param  elements   The array which contains element to convert.
-     * @param  targetType The base type of target elements.
-     * @throws ClassCastException If an element can't be converted.
+     * @param  elements    the array which contains element to convert.
+     * @param  targetType  the base type of target elements.
+     * @throws ClassCastException if an element can't be converted.
      */
     @SuppressWarnings({"unchecked","rawtypes"})
     private void convert(final Object[] elements, final Class<?> targetType) throws ClassCastException {
@@ -1010,10 +1014,12 @@ class PropertyAccessor {
                 final Class<?> sourceType = value.getClass();
                 if (!targetType.isAssignableFrom(sourceType)) try {
                     if (converter == null) {
-                        converter = lastConverter; // Volatile field - read only if needed.
+                        converter = lastConverter;              // Volatile field - read only if needed.
                     }
-                    // Require the exact same classes, not parent or subclass,
-                    // otherwise the converter could be stricter than necessary.
+                    /*
+                     * Require the exact same classes, not parent or subclass,
+                     * otherwise the converter could be stricter than necessary.
+                     */
                     if (converter == null || converter.getSourceClass() != sourceType
                                           || converter.getTargetClass() != targetType)
                     {
@@ -1028,7 +1034,7 @@ class PropertyAccessor {
             }
         }
         if (hasNewConverter) {
-            lastConverter = converter; // Volatile field - store only if needed.
+            lastConverter = converter;                          // Volatile field - store only if needed.
         }
     }
 
@@ -1044,9 +1050,9 @@ class PropertyAccessor {
      *                      properties returned by {@link Collection#size()}.</li>
      * </ul>
      *
-     * @param  mode Kinds of count, as described above.
-     * @param  valuePolicy The behavior of the count toward null or empty values.
-     * @throws BackingStoreException If the implementation threw a checked exception.
+     * @param  mode         kinds of count, as described above.
+     * @param  valuePolicy  the behavior of the count toward null or empty values.
+     * @throws BackingStoreException if the implementation threw a checked exception.
      *
      * @see #count()
      */
@@ -1058,7 +1064,8 @@ class PropertyAccessor {
             return count();
         }
         int count = 0;
-        for (int i=0; i<standardCount; i++) { // Use 'standardCount' instead of 'allCount' for ignoring deprecated methods.
+        // Use 'standardCount' instead of 'allCount' for ignoring deprecated methods.
+        for (int i=0; i<standardCount; i++) {
             final Object value = get(getters[i], metadata);
             if (!valuePolicy.isSkipped(value)) {
                 switch (mode) {
@@ -1070,8 +1077,10 @@ class PropertyAccessor {
                         break;
                     }
                     case COUNT_DEEP: {
-                        // Count always at least one element because if the user wanted to skip null or empty
-                        // collections, then 'valuePolicy.isSkipped(value)' above would have returned 'true'.
+                        /*
+                         * Count always at least one element because if the user wanted to skip null or empty
+                         * collections, then 'valuePolicy.isSkipped(value)' above would have returned 'true'.
+                         */
                         count += (value != null && isCollection(i)) ? Math.max(((Collection<?>) value).size(), 1) : 1;
                         break;
                     }
@@ -1088,10 +1097,10 @@ class PropertyAccessor {
      * method without explicit calls to this {@code accessor.equals(…)} method for children.
      * However the final result may still be a deep comparison.
      *
-     * @param  metadata1 The first metadata object to compare. This object determines the accessor.
-     * @param  metadata2 The second metadata object to compare.
-     * @param  mode      The strictness level of the comparison.
-     * @throws BackingStoreException If the implementation threw a checked exception.
+     * @param  metadata1  the first metadata object to compare. This object determines the accessor.
+     * @param  metadata2  the second metadata object to compare.
+     * @param  mode       the strictness level of the comparison.
+     * @throws BackingStoreException if the implementation threw a checked exception.
      *
      * @see MetadataStandard#equals(Object, Object, ComparisonMode)
      */
@@ -1105,8 +1114,10 @@ class PropertyAccessor {
             final Object value1 = get(method, metadata1);
             final Object value2 = get(method, metadata2);
             if (isNullOrEmpty(value1) && isNullOrEmpty(value2)) {
-                // Consider empty collections/arrays as equal to null.
-                // Empty strings are also considered equal to null (this is more questionable).
+                /*
+                 * Consider empty collections/arrays as equal to null.
+                 * Empty strings are also considered equal to null (this is more questionable).
+                 */
                 continue;
             }
             final boolean equals;
@@ -1140,7 +1151,7 @@ class PropertyAccessor {
      * Replaces every properties in the specified metadata by their
      * {@linkplain ModifiableMetadata#unmodifiable() unmodifiable variant}.
      *
-     * @throws BackingStoreException If the implementation threw a checked exception.
+     * @throws BackingStoreException if the implementation threw a checked exception.
      */
     final void freeze(final Object metadata) throws BackingStoreException {
         assert implementation.isInstance(metadata) : metadata;
@@ -1191,7 +1202,7 @@ class PropertyAccessor {
      * This is a similar contract than {@link java.util.Set#hashCode()} (except for the interface)
      * and ensures that the hash code value is insensitive to the ordering of properties.
      *
-     * @throws BackingStoreException If the implementation threw a checked exception.
+     * @throws BackingStoreException if the implementation threw a checked exception.
      */
     public int hashCode(final Object metadata) throws BackingStoreException {
         assert type.isInstance(metadata) : metadata;

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNode.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -20,6 +20,7 @@ import java.util.List;
 import java.util.Iterator;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Objects;
 import java.util.NoSuchElementException;
 import java.util.ConcurrentModificationException;
 import org.apache.sis.util.Debug;
@@ -260,6 +261,26 @@ class TreeNode implements Node {
         return false;
     }
 
+    /**
+     * Returns {@code true} if the given object is of the same class than this node and contains a reference
+     * to the same metadata object. Since {@code TreeNode} generates all content from the wrapped metadata,
+     * this condition should ensure that two equal nodes have the same values and children.
+     */
+    @Override
+    public boolean equals(final Object other) {
+        return (other != null) && other.getClass() == getClass()
+                && ((TreeNode) other).metadata == metadata
+                && ((TreeNode) other).baseType == baseType;
+    }
+
+    /**
+     * Returns a hash code value for this node.
+     */
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(metadata) ^ Objects.hashCode(baseType);
+    }
+
 
 
 
@@ -275,15 +296,13 @@ class TreeNode implements Node {
      */
     static class Element extends TreeNode {
         /**
-         * The accessor to use for fetching the property names, types and values from the
-         * {@link #metadata} object. Note that the value of this field is the same for all
-         * siblings.
+         * The accessor to use for fetching the property names, types and values from the {@link #metadata} object.
+         * Note that the reference stored in this field is the same for all siblings.
          */
         private final PropertyAccessor accessor;
 
         /**
-         * Index of the value in the {@link #metadata} object to be fetched with the
-         * {@link #accessor}.
+         * Index of the value in the {@link #metadata} object to be fetched with the {@link #accessor}.
          */
         private final int indexInData;
 
@@ -294,7 +313,7 @@ class TreeNode implements Node {
          * @param  parent       the parent of this node.
          * @param  metadata     the metadata object for which this node will be a value.
          * @param  accessor     accessor to use for fetching the name, type and value.
-         * @param  indexInData  index to be given to the accessor of fetching the value.
+         * @param  indexInData  index to be given to the accessor for fetching the value.
          */
         Element(final TreeNode parent, final Object metadata,
                 final PropertyAccessor accessor, final int indexInData)
@@ -355,6 +374,23 @@ class TreeNode implements Node {
         final boolean isWritable() {
             return accessor.isWritable(indexInData);
         }
+
+        /**
+         * Returns {@code true} if the value returned by {@link #getUserObject()}
+         * should be the same for both nodes.
+         */
+        @Override
+        public boolean equals(final Object other) {
+            return super.equals(other) && ((Element) other).indexInData == indexInData;
+        }
+
+        /**
+         * Returns a hash code value for this node.
+         */
+        @Override
+        public int hashCode() {
+            return super.hashCode() ^ (31 * indexInData);
+        }
     }
 
 
@@ -442,7 +478,7 @@ class TreeNode implements Node {
                 }
                 final Iterator<?> it = values.iterator();
                 for (int i=0; i<indexInList; i++) {
-                    it.next(); // Inefficient way to move at the desired index, but hopefully rare.
+                    it.next();      // Inefficient way to move at the desired index, but hopefully rare.
                 }
                 return it.next();
             } catch (NullPointerException | IndexOutOfBoundsException | NoSuchElementException e) {
@@ -489,6 +525,23 @@ class TreeNode implements Node {
                 throw new ConcurrentModificationException(e);
             }
         }
+
+        /**
+         * Returns {@code true} if the value returned by {@link #getUserObject()}
+         * should be the same for both nodes.
+         */
+        @Override
+        public boolean equals(final Object other) {
+            return super.equals(other) && ((CollectionElement) other).indexInList == indexInList;
+        }
+
+        /**
+         * Returns a hash code value for this node.
+         */
+        @Override
+        public int hashCode() {
+            return super.hashCode() ^ indexInList;
+        }
     }
 
 

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -376,7 +376,7 @@ final class TreeNodeChildren extends Abs
                 }
                 subIterator = null;
                 subIndex = -1;
-                nextInAccessor++; // See the comment before nextInAccessor++ in the next() method.
+                nextInAccessor++;       // See the comment before nextInAccessor++ in the next() method.
             }
             /*
              * Search for the next property, which may be either a singleton or the first element
@@ -397,17 +397,21 @@ final class TreeNodeChildren extends Abs
                             subIterator = ((Iterable<?>) nextValue).iterator();
                         } else {
                             subIterator = Collections.emptyIterator();
-                            // Null collections are illegal (it shall be empty collections instead),
-                            // but we try to keep the iterator robut to ill-formed metadata, because
-                            // we want AbstractMetadata.toString() to work so we can spot problems.
+                            /*
+                             * Null collections are illegal (it shall be empty collections instead),
+                             * but we try to keep the iterator robut to ill-formed metadata, because
+                             * we want AbstractMetadata.toString() to work so we can spot problems.
+                             */
                         }
                         subIndex = 0;
                         if (subIterator.hasNext()) {
                             nextValue = subIterator.next();
                         } else {
                             nextValue = null;
-                            // Do not set 'childIterator' to null, since the above 'nextValue'
-                            // is considered as part of the child iteration.
+                            /*
+                             * Do not set 'childIterator' to null, since the above 'nextValue'
+                             * is considered as part of the child iteration.
+                             */
                         }
                     }
                     isNextVerified = true;

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -185,7 +185,7 @@ public class ImmutableIdentifier extends
      * Creates a new identifier from the specified one. This is a copy constructor which
      * get the code, codespace, authority and version from the given identifier.
      *
-     * @param identifier The identifier to copy.
+     * @param identifier  the identifier to copy.
      */
     public ImmutableIdentifier(final Identifier identifier) {
         ensureNonNull("identifier", identifier);
@@ -200,13 +200,10 @@ public class ImmutableIdentifier extends
     /**
      * Creates a new identifier from the specified code and authority.
      *
-     * @param authority
-     *          The person or party responsible for maintenance of the namespace, or {@code null} if not available.
-     * @param codeSpace
-     *          Identifier or namespace in which the code is valid, or {@code null} if not available.
-     *          This is often an abbreviation of the authority name.
-     * @param code
-     *          Alphanumeric value identifying an instance in the namespace. The code can not be null.
+     * @param authority  the person or party responsible for maintenance of the namespace, or {@code null} if not available.
+     * @param codeSpace  identifier or namespace in which the code is valid, or {@code null} if not available.
+     *                   This is often an abbreviation of the authority name.
+     * @param code       alphanumeric value identifying an instance in the namespace. The code can not be null.
      */
     public ImmutableIdentifier(final Citation authority, final String codeSpace, final String code) {
         this(authority, codeSpace, code, null, null);
@@ -216,17 +213,12 @@ public class ImmutableIdentifier extends
      * Creates a new identifier from the specified code and authority,
      * with an optional version number and description.
      *
-     * @param authority
-     *          The person or party responsible for maintenance of the namespace, or {@code null} if not available.
-     * @param codeSpace
-     *          Identifier or namespace in which the code is valid, or {@code null} if not available.
-     *          This is often an abbreviation of the authority name.
-     * @param code
-     *          Alphanumeric value identifying an instance in the namespace. The code can not be null.
-     * @param version
-     *          The version identifier for the namespace as specified by the code authority, or {@code null} if none.
-     * @param description
-     *          Natural language description of the meaning of the code value, or {@code null} if none.
+     * @param authority    the person or party responsible for maintenance of the namespace, or {@code null} if not available.
+     * @param codeSpace    identifier or namespace in which the code is valid, or {@code null} if not available.
+     *                     This is often an abbreviation of the authority name.
+     * @param code         alphanumeric value identifying an instance in the namespace. The code can not be null.
+     * @param version      the version identifier for the namespace as specified by the code authority, or {@code null} if none.
+     * @param description  natural language description of the meaning of the code value, or {@code null} if none.
      */
     public ImmutableIdentifier(final Citation authority, final String codeSpace,
             final String code, final String version, final InternationalString description)
@@ -294,7 +286,7 @@ public class ImmutableIdentifier extends
      * After successful construction, {@code ImmutableIdentifier} instances do not keep the locale
      * since localizations are deferred to the {@link InternationalString#toString(Locale)} method.</p>
      *
-     * @param  properties The properties to be given to this identifier.
+     * @param  properties  the properties to be given to this identifier.
      * @throws IllegalArgumentException if a property has an illegal value.
      */
     public ImmutableIdentifier(final Map<String,?> properties) throws IllegalArgumentException {
@@ -365,8 +357,8 @@ public class ImmutableIdentifier extends
      *       metadata contained in the given object are not recursively copied.</li>
      * </ul>
      *
-     * @param  object The object to get as a SIS implementation, or {@code null} if none.
-     * @return A SIS implementation containing the values of the given object (may be the
+     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
+     * @return a SIS implementation containing the values of the given object (may be the
      *         given object itself), or {@code null} if the argument was null.
      */
     public static ImmutableIdentifier castOrCopy(final Identifier object) {
@@ -381,7 +373,7 @@ public class ImmutableIdentifier extends
      * The organization's abbreviation is often the same than this identifier {@linkplain #getCodeSpace() code space},
      * but not necessarily.
      *
-     * @return The authority, or {@code null} if not available.
+     * @return the authority, or {@code null} if not available.
      */
     @Override
     public Citation getAuthority() {
@@ -393,7 +385,7 @@ public class ImmutableIdentifier extends
      *
      * <div class="note"><b>Example:</b> {@code "4326"}.</div>
      *
-     * @return Value identifying an instance in the namespace (never {@code null}).
+     * @return value identifying an instance in the namespace (never {@code null}).
      *
      * @see org.apache.sis.referencing.NamedIdentifier#tip()
      */
@@ -408,7 +400,7 @@ public class ImmutableIdentifier extends
      *
      * <div class="note"><b>Example:</b> {@code "EPSG"}.</div>
      *
-     * @return Identifier or namespace in which the code is valid, or {@code null} if not available.
+     * @return identifier or namespace in which the code is valid, or {@code null} if not available.
      *
      * @see org.apache.sis.referencing.NamedIdentifier#head()
      * @see org.apache.sis.referencing.NamedIdentifier#scope()
@@ -425,7 +417,7 @@ public class ImmutableIdentifier extends
      *
      * <div class="note"><b>Example:</b> the version of the underlying EPSG database.</div>
      *
-     * @return The version identifier for the namespace, or {@code null} if none.
+     * @return the version identifier for the namespace, or {@code null} if none.
      */
     @Override
     public String getVersion() {
@@ -437,7 +429,7 @@ public class ImmutableIdentifier extends
      *
      * <div class="note"><b>Example:</b> "World Geodetic System 1984".</div>
      *
-     * @return The natural language description, or {@code null} if none.
+     * @return the natural language description, or {@code null} if none.
      *
      * @since 0.5
      */
@@ -464,7 +456,7 @@ public class ImmutableIdentifier extends
     /**
      * Compares this object with the given one for equality.
      *
-     * @param object The object to compare with this identifier.
+     * @param  object  the object to compare with this identifier.
      * @return {@code true} if both objects are equal.
      */
     @Override
@@ -487,7 +479,7 @@ public class ImmutableIdentifier extends
      * Formats this identifier as a <cite>Well Known Text</cite> {@code Id[…]} element.
      * See class javadoc for more information on the WKT format.
      *
-     * @param  formatter The formatter where to format the inner content of this WKT element.
+     * @param  formatter  the formatter where to format the inner content of this WKT element.
      * @return {@code "Id"} (WKT 2) or {@code "Authority"} (WKT 1).
      *
      * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#33">WKT 2 specification §7.3.4</a>

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/AbstractMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/AbstractMetadataTest.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/AbstractMetadataTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/AbstractMetadataTest.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -29,7 +29,7 @@ import static org.apache.sis.test.TestUt
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.8
  * @module
  */
 @DependsOn(MetadataStandardTest.class)
@@ -44,7 +44,7 @@ public final strictfp class AbstractMeta
     @Test
     public void testHashCodeOnCyclicMetadata() {
         final int code = MetadataStandardTest.createCyclicMetadata().hashCode();
-        assertEquals(code, MetadataStandardTest.createCyclicMetadata().hashCode());
+        assertEquals("hashCode", code, MetadataStandardTest.createCyclicMetadata().hashCode());
     }
 
     /**
@@ -54,29 +54,41 @@ public final strictfp class AbstractMeta
      *
      * <p>The tree formatted by this test is:</p>
      * {@preformat text
-     *     Platform
-     *       ├─Description……………………… A platform.
-     *       └─Instrument
-     *           ├─Type……………………………… An instrument type.
-     *           └─Mounted on
-     *             (cycle omitted)
+     *     Acquisition information
+     *       └─Platform
+     *           ├─Description………………………………… A platform.
+     *           └─Instrument
+     *               ├─Type………………………………………… An instrument type.
+     *               └─Mounted on
+     *                   ├─Description…………… A platform.
+     *                   └─Instrument
+     *                         (omitted cycle)
      * }
+     *
+     * Note that the cycle detection apparently happens too late since "A platform" has been repeated.
+     * This is because that same Platform instance appears in two different metadata property.  We do
+     * not stop the formatting on the same metadata instance - we also require that it appears in the
+     * same property - for allowing the complete formatting of objects that implement more than one
+     * metadata interface.
      */
     @Test
     public void testToStringOnCyclicMetadata() {
         final String text = MetadataStandardTest.createCyclicMetadata().toString();
         /*
-         * We can not perform a full comparison of the string, since it is locale-dependent.
-         * Compare only the tree structure. The full tree is English is shown in javadoc.
+         * We can not perform a full comparison of the string since it is locale-dependent.
+         * Compare only the tree structure. The full tree in English is shown in javadoc.
          */
-        assertTrue(text, text.startsWith("Platform"));
-        assertArrayEquals(new String[] {
-            "",
-            "  ├─",
-            "  └─",
-            "      ├─",
-            "      └─",
-            "        (",
+        assertTrue(text, text.startsWith("Acquisition information"));
+        assertArrayEquals("toTreeStructure", new String[] {
+            "",                             // Acquisition information
+            "  └─",                         // Platform
+            "      ├─",                     // Description
+            "      └─",                     // Instrument
+            "          ├─",                 // Type
+            "          └─",                 // Mounted on
+            "              ├─",             // Description
+            "              └─",             // Instrument
+            "                    (",        // Omitted cycle
             ""}, toTreeStructure(text));
     }
 }

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -29,6 +29,7 @@ import org.apache.sis.metadata.iso.citat
 import org.apache.sis.metadata.iso.citation.HardCodedCitations;
 import org.apache.sis.metadata.iso.acquisition.DefaultPlatform;
 import org.apache.sis.metadata.iso.acquisition.DefaultInstrument;
+import org.apache.sis.metadata.iso.acquisition.DefaultAcquisitionInformation;
 import org.apache.sis.metadata.iso.quality.AbstractCompleteness;
 import org.apache.sis.internal.simple.SimpleIdentifiedObject;
 import org.apache.sis.util.iso.SimpleInternationalString;
@@ -215,14 +216,16 @@ public final strictfp class MetadataStan
      * Creates a metadata object having a cyclic association. The cycle is between
      * {@code platform.instrument} and {@code instrument.isMountedOn}.
      */
-    static DefaultPlatform createCyclicMetadata() {
+    static DefaultAcquisitionInformation createCyclicMetadata() {
         final DefaultInstrument instrument = new DefaultInstrument();
         instrument.setType(new SimpleInternationalString("An instrument type."));
         final DefaultPlatform platform = new DefaultPlatform();
         platform.setDescription(new SimpleInternationalString("A platform."));
         instrument.setMountedOn(platform);
         platform.setInstruments(singleton(instrument));
-        return platform;
+        final DefaultAcquisitionInformation acquisition = new DefaultAcquisitionInformation();
+        acquisition.setPlatforms(singleton(platform));
+        return acquisition;
     }
 
     /**
@@ -233,12 +236,14 @@ public final strictfp class MetadataStan
     @Test
     @DependsOnMethod("testEquals")
     public void testEqualsOnCyclicMetadata() {
-        final DefaultPlatform p1 = createCyclicMetadata();
-        final DefaultPlatform p2 = createCyclicMetadata();
-        assertTrue(p1.equals(p2));
-        ((DefaultInstrument) getSingleton(p2.getInstruments()))
-                .setType(new SimpleInternationalString("An other instrument type."));
-        assertFalse(p1.equals(p2));
+        final DefaultAcquisitionInformation p1 = createCyclicMetadata();
+        final DefaultAcquisitionInformation p2 = createCyclicMetadata();
+        assertTrue("equals", p1.equals(p2));
+
+        final DefaultPlatform   platform   = (DefaultPlatform)   getSingleton(p2.getPlatforms());
+        final DefaultInstrument instrument = (DefaultInstrument) getSingleton(platform.getInstruments());
+        instrument.setType(new SimpleInternationalString("An other instrument type."));
+        assertFalse("equals", p1.equals(p2));
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PrunerTest.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -23,7 +23,6 @@ import org.apache.sis.metadata.iso.exten
 import org.apache.sis.metadata.iso.identification.DefaultResolution;
 import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
 import org.apache.sis.metadata.iso.identification.DefaultRepresentativeFraction;
-import org.apache.sis.metadata.iso.acquisition.DefaultAcquisitionInformation;
 import org.apache.sis.internal.simple.SimpleIdentifier;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
@@ -40,7 +39,7 @@ import static org.apache.sis.metadata.Va
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.6
+ * @version 0.8
  * @module
  */
 @DependsOn(ValueMapTest.class)
@@ -153,9 +152,7 @@ public final strictfp class PrunerTest e
      * The cycle is between {@code platform.instrument} and {@code instrument.isMountedOn}.
      */
     private void createCyclicMetadata() {
-        final DefaultAcquisitionInformation acquisition = new DefaultAcquisitionInformation();
-        acquisition.setPlatforms(singleton(MetadataStandardTest.createCyclicMetadata()));
-        metadata.setAcquisitionInformation(singleton(acquisition));
+        metadata.setAcquisitionInformation(singleton(MetadataStandardTest.createCyclicMetadata()));
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapAdapter.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -25,6 +25,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.AbstractMap;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.io.Serializable;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
@@ -36,9 +37,6 @@ import org.apache.sis.internal.util.SetO
 
 import static org.apache.sis.util.collection.Containers.hashMapCapacity;
 
-// Branch-dependent imports
-import java.util.Objects;
-
 
 /**
  * Implementation of the map of identifiers associated to {@link org.apache.sis.xml.IdentifiedObject} instances.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/ModifiableIdentifierMap.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/ModifiableIdentifierMap.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/ModifiableIdentifierMap.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/ModifiableIdentifierMap.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -53,7 +53,7 @@ public final class ModifiableIdentifierM
     /**
      * Creates a new map which will be a view over the given identifiers.
      *
-     * @param identifiers The identifiers to wrap in a map view.
+     * @param  identifiers  the identifiers to wrap in a map view.
      */
     public ModifiableIdentifierMap(final Collection<Identifier> identifiers) {
         super(identifiers);
@@ -66,8 +66,8 @@ public final class ModifiableIdentifierM
      * {@link URI}, and use the value associated to the {@code HREF} key only as a fallback when the string can not
      * be parsed.
      *
-     * @param  href The new value, or {@code null} for removing the value.
-     * @return The previous value, or {@code null} if none.
+     * @param  href  the new value, or {@code null} for removing the value.
+     * @return the previous value, or {@code null} if none.
      *
      * @see #getHRef()
      */
@@ -124,8 +124,8 @@ public final class ModifiableIdentifierM
      * Removes all identifiers associated with the given {@linkplain Identifier#getAuthority() authority}.
      * The default implementation delegates to {@link #put(Citation, String)} with a {@code null} value.
      *
-     * @param  authority The authority to search, which should be an instance of {@link Citation}.
-     * @return The code of the identifier for the given authority, or {@code null} if none.
+     * @param  authority  the authority to search, which should be an instance of {@link Citation}.
+     * @return the code of the identifier for the given authority, or {@code null} if none.
      */
     @Override
     public String remove(final Object authority) {
@@ -143,9 +143,9 @@ public final class ModifiableIdentifierM
      * associated to the {@code XLINK} key. Only if the given string can not be parsed, then the value is stored
      * <cite>as-is</cite> under the {@code HREF} key.</p>
      *
-     * @param  authority The authority for which to set the code.
-     * @param  code The new code for the given authority, or {@code null} for removing the entry.
-     * @return The previous code for the given authority, or {@code null} if none.
+     * @param  authority  the authority for which to set the code.
+     * @param  code  the new code for the given authority, or {@code null} for removing the entry.
+     * @return the previous code for the given authority, or {@code null} if none.
      */
     @Override
     public String put(final Citation authority, final String code) {
@@ -163,7 +163,7 @@ public final class ModifiableIdentifierM
                     } catch (URISyntaxException e) {
                         SpecializedIdentifier.parseFailure(context, code, URI.class, e);
                         discarded = setHRef(null);
-                        break;  // Fallback on generic code below.
+                        break;                          // Fallback on generic code below.
                     }
                 }
                 final Identifier identifier = getIdentifier(authority);
@@ -185,20 +185,24 @@ public final class ModifiableIdentifierM
         while (it.hasNext()) {
             final Identifier identifier = it.next();
             if (identifier == null) {
-                it.remove(); // Opportunist cleaning, but should not happen.
+                it.remove();                        // Opportunist cleaning, but should not happen.
             } else if (Objects.equals(authority, identifier.getAuthority())) {
                 if (code != null && identifier instanceof IdentifierMapEntry) {
                     return ((IdentifierMapEntry) identifier).setValue(code);
-                    // No need to suppress other occurrences of the key (if any)
-                    // because we made a replacement in the first entry, so the
-                    // new value will be visible by the getter methods.
+                    /*
+                     * No need to suppress other occurrences of the key (if any)
+                     * because we made a replacement in the first entry, so the
+                     * new value will be visible by the getter methods.
+                     */
                 }
                 if (previous == null) {
                     previous = identifier.getCode();
                 }
                 it.remove();
-                // Continue the iteration in order to remove all other occurrences,
-                // in order to ensure that the getter methods will see the new value.
+                /*
+                 * Continue the iteration in order to remove all other occurrences,
+                 * in order to ensure that the getter methods will see the new value.
+                 */
             }
         }
         if (code != null) {
@@ -217,10 +221,10 @@ public final class ModifiableIdentifierM
      * as the {@link XLink#getHRef()} property of the {@code XLink} associated to the {@code XLINK} key.
      * The previous {@code HREF} value, if any, is discarded.</p>
      *
-     * @param  <T> The identifier type.
-     * @param  authority The namespace with which the given identifier is to be associated.
-     * @param  value The identifier to be associated with the given namespace.
-     * @return The previous identifier associated with {@code authority}, or {@code null}
+     * @param  <T>        the identifier type.
+     * @param  authority  the namespace with which the given identifier is to be associated.
+     * @param  value      the identifier to be associated with the given namespace.
+     * @return the previous identifier associated with {@code authority}, or {@code null}
      *         if there was no mapping of the specialized type for {@code authority}.
      */
     @Override
@@ -236,10 +240,10 @@ public final class ModifiableIdentifierM
     /**
      * Sets the identifier associated with the given authority, without processing for special cases.
      *
-     * @param  <T> The identifier type.
-     * @param  authority The namespace with which the given identifier is to be associated.
-     * @param  value The identifier to be associated with the given namespace.
-     * @return The previous identifier associated with {@code authority}, or {@code null}
+     * @param  <T>        the identifier type.
+     * @param  authority  the namespace with which the given identifier is to be associated.
+     * @param  value      the identifier to be associated with the given namespace.
+     * @return the previous identifier associated with {@code authority}, or {@code null}
      *         if there was no mapping of the specialized type for {@code authority}.
      */
     private <T> T store(final IdentifierSpace<T> authority, final T value) {
@@ -260,14 +264,18 @@ public final class ModifiableIdentifierM
                     if (value != null) {
                         id.value = value;
                         return old;
-                        // No need to suppress other occurrences of the key (if any)
-                        // because we made a replacement in the first entry, so the
-                        // new value will be visible by the getter methods.
+                        /*
+                         * No need to suppress other occurrences of the key (if any)
+                         * because we made a replacement in the first entry, so the
+                         * new value will be visible by the getter methods.
+                         */
                     }
                 }
                 it.remove();
-                // Continue the iteration in order to remove all other occurrences,
-                // in order to ensure that the getter methods will see the new value.
+                /*
+                 * Continue the iteration in order to remove all other occurrences,
+                 * in order to ensure that the getter methods will see the new value.
+                 */
             }
         }
         if (value != null) {

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -19,6 +19,7 @@ package org.apache.sis.internal.jaxb;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.UUID;
+import java.util.Objects;
 import java.io.Serializable;
 import java.util.logging.Level;
 import org.opengis.metadata.Identifier;
@@ -32,16 +33,13 @@ import org.apache.sis.util.Debug;
 import org.apache.sis.util.resources.Messages;
 import org.apache.sis.internal.util.Citations;
 
-// Branch-dependent imports
-import java.util.Objects;
-
 
 /**
  * Wraps a {@link XLink}, {@link URI} or {@link UUID} as an identifier in the {@link IdentifierMap}.
  * The {@linkplain #authority} is typically an instance of {@link NonMarshalledAuthority}. The value
  * is an object of a type constrained by the authority.
  *
- * @param  <T> The value type, typically {@link XLink}, {@link UUID} or {@link String}.
+ * @param  <T>  the value type, typically {@link XLink}, {@link UUID} or {@link String}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
@@ -78,8 +76,8 @@ public final class SpecializedIdentifier
     /**
      * Creates a new adapter for the given authority and identifier value.
      *
-     * @param authority The identifier authority.
-     * @param value The identifier value, or {@code null} if not yet defined.
+     * @param  authority  the identifier authority.
+     * @param  value      the identifier value, or {@code null} if not yet defined.
      */
     public SpecializedIdentifier(final IdentifierSpace<T> authority, final T value) {
         this.authority = authority;
@@ -92,8 +90,8 @@ public final class SpecializedIdentifier
      * authorities declared in the {@link IdentifierSpace} interface. Otherwise a
      * plain {@link IdentifierMapEntry} is created.
      *
-     * @param authority The authority, typically as one of the {@link IdentifierSpace} constants.
-     * @param code      The identifier code to parse.
+     * @param  authority  the authority, typically as one of the {@link IdentifierSpace} constants.
+     * @param  code       the identifier code to parse.
      *
      * @see IdentifierMapAdapter#put(Citation, String)
      */
@@ -145,10 +143,10 @@ public final class SpecializedIdentifier
      * <p>This method assumes that {@link IdentifierMap#put(Object, Object)} is
      * the public API by which this method has been invoked.</p>
      *
-     * @param context The marshalling context, or {@code null} if none.
-     * @param value   The value that we failed to parse.
-     * @param type    The target type of the parsing process.
-     * @param cause   The exception that occurred during the parsing process.
+     * @param  context  the marshalling context, or {@code null} if none.
+     * @param  value    the value that we failed to parse.
+     * @param  type     the target type of the parsing process.
+     * @param  cause    the exception that occurred during the parsing process.
      */
     static void parseFailure(final Context context, final String value, final Class<?> type, final Exception cause) {
         Context.warningOccured(context, Level.WARNING, IdentifierMap.class, "put", cause,
@@ -158,7 +156,7 @@ public final class SpecializedIdentifier
     /**
      * Returns the authority specified at construction time.
      *
-     * @return The identifier authority.
+     * @return the identifier authority.
      */
     @Override
     public Citation getAuthority() {
@@ -169,7 +167,7 @@ public final class SpecializedIdentifier
      * Returns the identifier value. This is the {@linkplain #getCode() code} expressed as
      * an object more specialized than {@link String}.
      *
-     * @return The identifier value, or {@code null} if none.
+     * @return the identifier value, or {@code null} if none.
      */
     public T getValue() {
         return value;
@@ -179,7 +177,7 @@ public final class SpecializedIdentifier
      * Returns a string representation of the {@linkplain #getValue() identifier value},
      * or {@code null} if none.
      *
-     * @return The identifier value.
+     * @return the identifier value.
      */
     @Override
     public String getCode() {
@@ -190,7 +188,7 @@ public final class SpecializedIdentifier
     /**
      * Infers a code space from the authority.
      *
-     * @return The code space, or {@code null} if none.
+     * @return the code space, or {@code null} if none.
      *
      * @since 0.5
      */
@@ -234,7 +232,7 @@ public final class SpecializedIdentifier
     /**
      * Compares this identifier with the given object for equality.
      *
-     * @param other The object to compare with this identifier for equality.
+     * @param  other  the object to compare with this identifier for equality.
      */
     @Override
     public boolean equals(final Object other) {
@@ -249,7 +247,7 @@ public final class SpecializedIdentifier
     /**
      * Returns a clone of this identifier.
      *
-     * @return A shallow clone of this identifier.
+     * @return a shallow clone of this identifier.
      */
     @Override
     public Object clone() {

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -87,11 +87,11 @@ final class ObjectReference {
      *
      * <p>This method is invoked at unmarshalling time by {@link PropertyType#resolve(Context)}.</p>
      *
-     * @param  <T>       The compile-time type of the {@code type} argument.
-     * @param  context   The marshalling context, or {@code null} if none.
-     * @param  type      The expected type of the metadata object.
-     * @param  metadata  The metadata object, or {@code null}.
-     * @return A metadata object for the identifiers, or {@code null}
+     * @param  <T>       the compile-time type of the {@code type} argument.
+     * @param  context   the marshalling context, or {@code null} if none.
+     * @param  type      the expected type of the metadata object.
+     * @param  metadata  the metadata object, or {@code null}.
+     * @return a metadata object for the identifiers, or {@code null}
      */
     final <T> T resolve(final Context context, final Class<T> type, T metadata) {
         if (metadata == null) {
@@ -99,8 +99,10 @@ final class ObjectReference {
             if ((uuid  == null || (metadata = resolver.resolve(context, type, uuid )) == null) &&
                 (xlink == null || (metadata = resolver.resolve(context, type, xlink)) == null))
             {
-                // Failed to find an existing metadata instance.
-                // Creates an empty instance with the identifiers.
+                /*
+                 * Failed to find an existing metadata instance.
+                 * Creates an empty instance with the identifiers.
+                 */
                 int count = 0;
                 SpecializedIdentifier<?>[] identifiers  = new SpecializedIdentifier<?>[2];
                 if (uuid  != null) identifiers[count++] = new SpecializedIdentifier<>(IdentifierSpace.UUID,  uuid);
@@ -109,8 +111,10 @@ final class ObjectReference {
                 metadata = resolver.newIdentifiedObject(context, type, identifiers);
             }
         } else {
-            // In principle, the XML should contain a full metadata object OR a uuidref attribute.
-            // However if both are present, assign the identifiers to that instance.
+            /*
+             * In principle, the XML should contain a full metadata object OR a uuidref attribute.
+             * However if both are present, assign the identifiers to that instance.
+             */
             if (metadata instanceof IdentifiedObject) {
                 final IdentifierMap map = ((IdentifiedObject) metadata).getIdentifierMap();
                 putInto(context, map, IdentifierSpace.UUID,  uuid);
@@ -138,9 +142,9 @@ final class ObjectReference {
      * 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.
+     * @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 Context context, final IdentifierMap map,
             final IdentifierSpace<T> authority, final T value)

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=1778893&r1=1778892&r2=1778893&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] Sun Jan 15 09:20:18 2017
@@ -153,8 +153,8 @@ public abstract class PropertyType<Value
      * Builds a {@code PropertyType} wrapper for the given primitive type wrapper.
      * This constructor checks for nil reasons only if {@code check} is {@code true}.
      *
-     * @param value The primitive type wrapper.
-     * @param mayBeNil {@code true} if we should check for nil reasons.
+     * @param  value     the primitive type wrapper.
+     * @param  mayBeNil  {@code true} if we should check for nil reasons.
      */
     PropertyType(final BoundType value, final boolean mayBeNil) {
         metadata = value;
@@ -172,7 +172,7 @@ public abstract class PropertyType<Value
      * implements the {@link NilObject} or {@link IdentifiedObject} interface. If the object implements
      * both of them (should not happen, but we never know), then the identifiers will have precedence.
      *
-     * @param value The interface to wrap.
+     * @param  value  the interface to wrap.
      */
     protected PropertyType(final BoundType value) {
         /*
@@ -291,7 +291,7 @@ public abstract class PropertyType<Value
         XLink xlink = ref.xlink;
         if (create && xlink == null) {
             ref.xlink = xlink = new XLink();
-            xlink.setType(XLink.Type.SIMPLE); // The "simple" type is fixed in the "gco" schema.
+            xlink.setType(XLink.Type.SIMPLE);           // The "simple" type is fixed in the "gco" schema.
         }
         return xlink;
     }
@@ -313,7 +313,7 @@ public abstract class PropertyType<Value
      * non-null {@linkplaih #reference} exists, since in such case the object can
      * not be nil.
      *
-     * @param nilReason The new attribute value.
+     * @param nilReason the new attribute value.
      * @category gco:PropertyType
      */
     public final void setNilReason(final String nilReason) {
@@ -330,7 +330,7 @@ public abstract class PropertyType<Value
      * @return the current value, or {@code null} if none.
      * @category gco:ObjectReference
      */
-    @XmlAttribute(name = "uuidref")  // Defined in "gco" as unqualified attribute.
+    @XmlAttribute(name = "uuidref")                 // Defined in "gco" as unqualified attribute.
     public final String getUUIDREF() {
         final ObjectReference ref = reference(false);
         return (ref != null) ? toString(ref.uuid) : null;
@@ -339,8 +339,8 @@ public abstract class PropertyType<Value
     /**
      * Sets the {@code uuidref} attribute value.
      *
-     * @param  uuid The new attribute value.
-     * @throws IllegalArgumentException If the given UUID can not be parsed.
+     * @param  uuid  the new attribute value.
+     * @throws IllegalArgumentException if the given UUID can not be parsed.
      * @category gco:ObjectReference
      */
     public final void setUUIDREF(final String uuid) throws IllegalArgumentException {
@@ -381,8 +381,8 @@ public abstract class PropertyType<Value
     /**
      * Sets the {@code href} attribute value.
      *
-     * @param href The new attribute value.
-     * @throws URISyntaxException If th given string can not be parsed as a URI.
+     * @param  href  the new attribute value.
+     * @throws URISyntaxException if the given string can not be parsed as a URI.
      * @category xlink
      */
     public final void setHRef(final String href) throws URISyntaxException {
@@ -405,8 +405,8 @@ public abstract class PropertyType<Value
     /**
      * Sets the {@code role} attribute value.
      *
-     * @param role The new attribute value.
-     * @throws URISyntaxException If th given string can not be parsed as a URI.
+     * @param  role  the new attribute value.
+     * @throws URISyntaxException if the given string can not be parsed as a URI.
      * @category xlink
      */
     public final void setRole(final String role) throws URISyntaxException {
@@ -429,8 +429,8 @@ public abstract class PropertyType<Value
     /**
      * Sets the {@code arcrole} attribute value.
      *
-     * @param arcrole The new attribute value.
-     * @throws URISyntaxException If th given string can not be parsed as a URI.
+     * @param  arcrole  the new attribute value.
+     * @throws URISyntaxException if the given string can not be parsed as a URI.
      * @category xlink
      */
     public final void setArcRole(final String arcrole) throws URISyntaxException {
@@ -453,7 +453,7 @@ public abstract class PropertyType<Value
     /**
      * Sets the {@code title} attribute value.
      *
-     * @param title The new attribute value.
+     * @param  title  the new attribute value.
      * @category xlink
      */
     public final void setTitle(String title) {
@@ -486,7 +486,7 @@ public abstract class PropertyType<Value
     /**
      * Sets the {@code show} attribute value.
      *
-     * @param show The new attribute value.
+     * @param  show  the new attribute value.
      * @category xlink
      */
     public final void setShow(final XLink.Show show) {
@@ -516,7 +516,7 @@ public abstract class PropertyType<Value
     /**
      * Sets the {@code actuate} attribute value.
      *
-     * @param actuate The new attribute value.
+     * @param  actuate  the new attribute value.
      * @category xlink
      */
     public final void setActuate(final XLink.Actuate actuate) {
@@ -536,7 +536,7 @@ public abstract class PropertyType<Value
      * a value from the object fields, because this method is invoked from
      * the constructor.
      *
-     * @return The bound type, which is typically the GeoAPI interface.
+     * @return the bound type, which is typically the GeoAPI interface.
      */
     protected abstract Class<BoundType> getBoundType();
 
@@ -545,8 +545,8 @@ public abstract class PropertyType<Value
      * This method is invoked by {@link #marshal} after making sure that
      * {@code value} is not null.
      *
-     * @param value The GeoAPI interface to wrap.
-     * @return The adapter.
+     * @param  value  the GeoAPI interface to wrap.
+     * @return the adapter.
      */
     protected abstract ValueType wrap(final BoundType value);
 
@@ -555,8 +555,8 @@ public abstract class PropertyType<Value
      * marshalled into an XML file or stream. JAXB calls automatically this method at
      * marshalling time.
      *
-     * @param value The bound type value, here the interface.
-     * @return The adapter for the given value.
+     * @param  value  the bound type value, here the interface.
+     * @return the adapter for the given value.
      */
     @Override
     public final ValueType marshal(final BoundType value) {
@@ -570,9 +570,9 @@ public abstract class PropertyType<Value
      * Converts an adapter read from an XML stream to the GeoAPI interface which will
      * contains this value. JAXB calls automatically this method at unmarshalling time.
      *
-     * @param  value The adapter for a metadata value.
-     * @return An instance of the GeoAPI interface which represents the metadata value.
-     * @throws URISyntaxException If a URI can not be parsed.
+     * @param  value  the adapter for a metadata value.
+     * @return an instance of the GeoAPI interface which represents the metadata value.
+     * @throws URISyntaxException if a URI can not be parsed.
      */
     @Override
     public final BoundType unmarshal(final ValueType value) throws URISyntaxException {
@@ -583,7 +583,7 @@ public abstract class PropertyType<Value
      * If the {@linkplain #metadata} is still null, tries to resolve it using UUID, XLink
      * or NilReason information. This method is invoked at unmarshalling time.
      *
-     * @throws URISyntaxException If a nil reason is present and can not be parsed.
+     * @throws URISyntaxException if a nil reason is present and can not be parsed.
      */
     final BoundType resolve(final Context context) throws URISyntaxException {
         final ObjectReference ref = reference(false);
@@ -608,8 +608,8 @@ public abstract class PropertyType<Value
      * This method is not invoked if the missing component is flagged as mandatory by GML,
      * but is not mandatory for SIS working.
      *
-     * @param  missing The name of the missing XML component.
-     * @throws IllegalArgumentException Always thrown.
+     * @param  missing  the name of the missing XML component.
+     * @throws IllegalArgumentException always thrown.
      *
      * @since 0.7
      */

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/GMLAdapter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/GMLAdapter.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/GMLAdapter.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gml/GMLAdapter.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -82,12 +82,12 @@ public abstract class GMLAdapter {
      * <p>This constructor is typically invoked at marshalling time. The {@link #id}
      * value set by this constructor will be used by JAXB for producing the XML.</p>
      *
-     * @param wrapped An instance of a GeoAPI interface to be wrapped.
+     * @param  wrapped  an instance of a GeoAPI interface to be wrapped.
      */
     protected GMLAdapter(final Object wrapped) {
         if (wrapped instanceof IdentifiedObject) {
             final IdentifierMap map = ((IdentifiedObject) wrapped).getIdentifierMap();
-            if (map != null) { // Should not be null, but let be safe.
+            if (map != null) {                                  // Should not be null, but let be safe.
                 id = map.get(IdentifierSpace.ID);
             }
         }
@@ -98,12 +98,12 @@ public abstract class GMLAdapter {
      * is typically invoked at unmarshalling time in order to assign the ID of this
      * temporary wrapper to the "real" GeoAPI implementation instance.
      *
-     * @param wrapped The GeoAPI implementation for which to assign the ID.
+     * @param  wrapped  the GeoAPI implementation for which to assign the ID.
      */
     public final void copyIdTo(final Object wrapped) {
         if (id != null && wrapped instanceof IdentifiedObject) {
             final IdentifierMap map = ((IdentifiedObject) wrapped).getIdentifierMap();
-            if (map != null) { // Should not be null, but let be safe.
+            if (map != null) {                                  // Should not be null, but let be safe.
                 map.put(IdentifierSpace.ID, id);
             }
         }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/CitationConstant.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/CitationConstant.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/CitationConstant.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/CitationConstant.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -137,8 +137,10 @@ public class CitationConstant extends Si
                 if (c == null) {
                     c = MetadataServices.getInstance().createCitation(title);
                     if (c == null) {
-                        // 'sis-metadata' module not on the classpath (should be very rare)
-                        // or no citation defined for the given primary key.
+                        /*
+                         * 'sis-metadata' module not on the classpath (should be very rare)
+                         * or no citation defined for the given primary key.
+                         */
                         c = new SimpleCitation(title);
                     }
                     delegate = c;



Mime
View raw message