sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1778893 [2/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
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -19,6 +19,7 @@ package org.apache.sis.internal.util;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.Locale;
+import java.util.Objects;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.util.InternationalString;
@@ -30,9 +31,6 @@ import org.apache.sis.util.Static;
 
 import static org.apache.sis.util.iso.DefaultNameSpace.DEFAULT_SEPARATOR;
 
-// Branch-dependent imports
-import java.util.Objects;
-
 
 /**
  * Utility methods working on {@link Citation} objects. The public facade of those methods is
@@ -58,8 +56,8 @@ public final class Citations extends Sta
      * <p>This method can be used for identifying where in Apache SIS source code the relationship between
      * EPSG authority and IOGP code space is hard-coded.</p>
      *
-     * @param  codeSpace The identifier code space, or {@code null}.
-     * @param  code The identifier code, or {@code null}.
+     * @param  codeSpace  the identifier code space, or {@code null}.
+     * @param  code       the identifier code, or {@code null}.
      * @return {@code true} if the given identifier is {@code "IOGP:EPSG"}.
      *
      * @see org.apache.sis.metadata.iso.citation.Citations#EPSG
@@ -75,9 +73,9 @@ public final class Citations extends Sta
      * Returns the collection iterator, or {@code null} if the given collection is null
      * or empty. We use this method as a paranoiac safety against broken implementations.
      *
-     * @param  <E> The type of elements in the collection.
-     * @param  collection The collection from which to get the iterator, or {@code null}.
-     * @return The iterator over the given collection elements, or {@code null}.
+     * @param  <E>         the type of elements in the collection.
+     * @param  collection  the collection from which to get the iterator, or {@code null}.
+     * @return the iterator over the given collection elements, or {@code null}.
      */
     public static <E> Iterator<E> iterator(final Collection<E> collection) {
         return (collection != null && !collection.isEmpty()) ? collection.iterator() : null;
@@ -104,8 +102,8 @@ public final class Citations extends Sta
      * The method to be used consistently for comparing titles or identifiers in all {@code fooMathes(…)}
      * methods declared in this class.
      *
-     * @param  s1 The first characters sequence to compare, or {@code null}.
-     * @param  s2 The second characters sequence to compare, or {@code null}.
+     * @param  s1  the first characters sequence to compare, or {@code null}.
+     * @param  s2  the second characters sequence to compare, or {@code null}.
      * @return {@code true} if both arguments are {@code null} or if the two given texts are equal,
      *         ignoring case and any characters other than digits and letters.
      *
@@ -121,14 +119,14 @@ public final class Citations extends Sta
      * See {@link org.apache.sis.metadata.iso.citation.Citations#titleMatches(Citation, Citation)}
      * for the public documentation of this method.
      *
-     * @param  c1 The first citation to compare, or {@code null}.
-     * @param  c2 the second citation to compare, or {@code null}.
+     * @param  c1  the first citation to compare, or {@code null}.
+     * @param  c2  the second citation to compare, or {@code null}.
      * @return {@code true} if both arguments are non-null, and at least one title or alternate title matches.
      */
     public static boolean titleMatches(final Citation c1, final Citation c2) {
         if (c1 != null && c2 != null) {
             if (c1 == c2) {
-                return true; // Optimisation for a common case.
+                return true;                                                // Optimisation for a common case.
             }
             InternationalString candidate = c2.getTitle();
             Iterator<? extends InternationalString> iterator = null;
@@ -162,8 +160,8 @@ public final class Citations extends Sta
      * See {@link org.apache.sis.metadata.iso.citation.Citations#titleMatches(Citation, String)}
      * for the public documentation of this method.
      *
-     * @param  citation The citation to check for, or {@code null}.
-     * @param  title The title or alternate title to compare, or {@code null}.
+     * @param  citation  the citation to check for, or {@code null}.
+     * @param  title     the title or alternate title to compare, or {@code null}.
      * @return {@code true} if both arguments are non-null, and the title or an alternate
      *         title matches the given string.
      */
@@ -202,8 +200,8 @@ public final class Citations extends Sta
      * See {@link org.apache.sis.metadata.iso.citation.Citations#identifierMatches(Citation, Citation)}
      * for the public documentation of this method.
      *
-     * @param  c1 The first citation to compare, or {@code null}.
-     * @param  c2 the second citation to compare, or {@code null}.
+     * @param  c1  the first citation to compare, or {@code null}.
+     * @param  c2  the second citation to compare, or {@code null}.
      * @return {@code true} if both arguments are non-null, and at least one identifier matches.
      */
     public static boolean identifierMatches(Citation c1, Citation c2) {
@@ -242,9 +240,9 @@ public final class Citations extends Sta
      * See {@link org.apache.sis.metadata.iso.citation.Citations#identifierMatches(Citation, String)}
      * for the public documentation of this method.
      *
-     * @param  citation   The citation to check for, or {@code null}.
-     * @param  identifier The identifier to compare, or {@code null} if unknown.
-     * @param  code       Value of {@code identifier.getCode()}, or {@code null}.
+     * @param  citation    the citation to check for, or {@code null}.
+     * @param  identifier  the identifier to compare, or {@code null} if unknown.
+     * @param  code        value of {@code identifier.getCode()}, or {@code null}.
      * @return {@code true} if both arguments are non-null, and an identifier matches the given string.
      */
     public static boolean identifierMatches(final Citation citation, final Identifier identifier, final CharSequence code) {
@@ -277,9 +275,9 @@ public final class Citations extends Sta
      * If one of the authority is null, then the comparison fallback on the given {@code codeSpace}.
      * If the code spaces are also null, then this method conservatively returns {@code false}.
      *
-     * @param  identifier The identifier to compare.
-     * @param  authority  The desired authority, or {@code null}.
-     * @param  codeSpace  The desired code space or {@code null}, used as a fallback if an authority is null.
+     * @param  identifier  the identifier to compare.
+     * @param  authority   the desired authority, or {@code null}.
+     * @param  codeSpace   the desired code space or {@code null}, used as a fallback if an authority is null.
      * @return {@code true} if the authority or code space (as a fallback only) matches.
      */
     private static boolean authorityMatches(final Identifier identifier, final Citation authority, final String codeSpace) {
@@ -308,8 +306,8 @@ public final class Citations extends Sta
      * at least in the case of {@linkplain org.apache.sis.referencing.operation.DefaultOperationMethod operation methods} and
      * {@linkplain org.apache.sis.parameter.AbstractParameterDescriptor parameters}.</p>
      *
-     * @param  id1 The first collection of identifiers, or {@code null}.
-     * @param  id2 The second collection of identifiers, or {@code null}.
+     * @param  id1  the first collection of identifiers, or {@code null}.
+     * @param  id2  the second collection of identifiers, or {@code null}.
      * @return {@code TRUE} or {@code FALSE} on match or mismatch respectively, or {@code null} if this method
      *         can not determine if there is a match or mismatch.
      */
@@ -350,9 +348,9 @@ public final class Citations extends Sta
      *   <li>For assigning a value to a {@code codeSpace} field, use {@link #getUnicodeIdentifier(Citation)}.</li>
      * </ul>
      *
-     * @param  citation The citation for which to get the identifier, or {@code null}.
-     * @param  strict {@code true} for returning a non-null value only if the identifier is a valid Unicode identifier.
-     * @return A non-empty identifier for the given citation without leading or trailing whitespaces,
+     * @param  citation  the citation for which to get the identifier, or {@code null}.
+     * @param  strict    {@code true} for returning a non-null value only if the identifier is a valid Unicode identifier.
+     * @return a non-empty identifier for the given citation without leading or trailing whitespaces,
      *         or {@code null} if the given citation is null or does not declare any identifier or title.
      *
      * @see <a href="https://issues.apache.org/jira/browse/SIS-201">SIS-201</a>
@@ -384,8 +382,10 @@ public final class Citations extends Sta
                                 if (!Character.isUnicodeIdentifierPart(c) &&
                                         (strict || (c != '.' && c != '-')))
                                 {
-                                    // Above special case for '.' and '-' characters is documented
-                                    // in the public Citations.getIdentifier(Citation) method.
+                                    /*
+                                     * Above special case for '.' and '-' characters is documented
+                                     * in the public Citations.getIdentifier(Citation) method.
+                                     */
                                     isUnicode = false;
                                     break;
                                 }
@@ -462,8 +462,8 @@ public final class Citations extends Sta
      * use {@code getIdentifier(citation, true)} instead, which will produce the same result but preserving the
      * ignorable characters, which can be useful for formatting purpose.
      *
-     * @param  citation The citation for which to get the Unicode identifier, or {@code null}.
-     * @return A non-empty Unicode identifier for the given citation without leading or trailing whitespaces,
+     * @param  citation  the citation for which to get the Unicode identifier, or {@code null}.
+     * @return a non-empty Unicode identifier for the given citation without leading or trailing whitespaces,
      *         or {@code null} if the given citation is null or does not have any Unicode identifier or title.
      *
      * @since 0.6
@@ -499,8 +499,10 @@ public final class Citations extends Sta
                             buffer.appendCodePoint(c);
                         }
                     }
-                    // No need to verify if the buffer is empty, because ignorable
-                    // characters are not legal Unicode identifier start.
+                    /*
+                     * No need to verify if the buffer is empty, because ignorable
+                     * characters are not legal Unicode identifier start.
+                     */
                     return buffer.toString();
                 }
                 i += n;
@@ -522,8 +524,8 @@ public final class Citations extends Sta
      * behavior of this method close to the behavior of {@link #getUnicodeIdentifier(Citation)}, which is the
      * method having a public facade.</p>
      *
-     * @param  citation The citation for which to infer the code space, or {@code null}.
-     * @return A non-empty code space for the given citation without leading or trailing whitespaces,
+     * @param  citation  the citation for which to infer the code space, or {@code null}.
+     * @return a non-empty code space for the given citation without leading or trailing whitespaces,
      *         or {@code null} if the given citation is null or does not have any Unicode identifier or title.
      *
      * @since 0.6

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TabularFormat.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -65,10 +65,11 @@ import org.apache.sis.util.resources.Err
  * @version 0.3
  * @module
  *
- * @param <T> The base type of objects parsed and formatted by this class.
+ * @param  <T>  the base type of objects parsed and formatted by this class.
  *
  * @see TableAppender
  */
+@SuppressWarnings("CloneableClassWithoutClone")   // Because this class does not contain field that need to be cloned.
 public abstract class TabularFormat<T> extends CompoundFormat<T> {
     /**
      * For cross-version compatibility.
@@ -120,17 +121,18 @@ public abstract class TabularFormat<T> e
     private boolean isParsePatternDefined;
 
     /**
-     * The pattern used at parsing time for finding the column separators, or {@code null}
-     * if not yet constructed. This field is serialized because it may be a user-specified pattern.
+     * The pattern used at parsing time for finding the column separators, or {@code null} if not
+     * yet constructed. This field is serialized because it may be a user-specified pattern.
+     * The same {@code Pattern} instance can be safely shared by many {@code TabularFormat} instances.
      */
     private Pattern parsePattern;
 
     /**
      * Creates a new tabular format.
      *
-     * @param locale   The locale to use for numbers, dates and angles formatting,
-     *                 or {@code null} for the {@linkplain Locale#ROOT root locale}.
-     * @param timezone The timezone, or {@code null} for UTC.
+     * @param  locale    the locale to use for numbers, dates and angles formatting,
+     *                   or {@code null} for the {@linkplain Locale#ROOT root locale}.
+     * @param  timezone  the timezone, or {@code null} for UTC.
      */
     public TabularFormat(final Locale locale, final TimeZone timezone) {
         super(locale, timezone);
@@ -143,7 +145,7 @@ public abstract class TabularFormat<T> e
     /**
      * Returns the current line separator. The default value is system-dependent.
      *
-     * @return The current line separator.
+     * @return the current line separator.
      */
     public String getLineSeparator() {
         return lineSeparator;
@@ -152,7 +154,7 @@ public abstract class TabularFormat<T> e
     /**
      * Sets the line separator. Can not be a null or empty string.
      *
-     * @param separator The new line separator.
+     * @param  separator  the new line separator.
      */
     public void setLineSeparator(final String separator) {
         ArgumentChecks.ensureNonEmpty("separator", separator);
@@ -164,7 +166,7 @@ public abstract class TabularFormat<T> e
      * only if more than one column is formatted. See {@link #setColumnSeparatorPattern(String)}
      * for a description of the pattern syntax.
      *
-     * @return The pattern of the current column separator.
+     * @return the pattern of the current column separator.
      */
     public String getColumnSeparatorPattern() {
         final StringBuilder buffer = new StringBuilder(8);
@@ -223,8 +225,8 @@ public abstract class TabularFormat<T> e
      * then insert a space"</cite>.
      * </div>
      *
-     * @param  pattern The pattern of the new column separator.
-     * @throws IllegalArgumentException If the given pattern is illegal.
+     * @param  pattern  the pattern of the new column separator.
+     * @throws IllegalArgumentException if the given pattern is illegal.
      */
     public void setColumnSeparatorPattern(final String pattern) throws IllegalArgumentException {
         ArgumentChecks.ensureNonEmpty("pattern", pattern);
@@ -238,9 +240,9 @@ public abstract class TabularFormat<T> e
 scan:   for (int i=0; i<length; i++) {
             final char c = pattern.charAt(i);
             switch (c) {
-                case '\uFFFF': { // This "character" is reserved.
+                case '\uFFFF': {                        // This "character" is reserved.
                     prefix = null;
-                    break scan; // This will cause IllegalArgumentException to be thrown.
+                    break scan;                         // This will cause IllegalArgumentException to be thrown.
                 }
                 case '\\': {
                     if (i != separatorIndex) {
@@ -262,7 +264,7 @@ scan:   for (int i=0; i<length; i++) {
                     if (i != separatorIndex) {
                         if (separatorIndex >= 0) {
                             prefix = null;
-                            break scan; // This will cause IllegalArgumentException to be thrown.
+                            break scan;                 // This will cause IllegalArgumentException to be thrown.
                         }
                         separatorIndex = i+1;
                     }
@@ -312,8 +314,8 @@ scan:   for (int i=0; i<length; i++) {
      * Returns a matcher for the column separators in the given text.
      * This method is invoked by subclasses in their {@code parse(…)} implementations.
      *
-     * @param  text The text for which to get a matcher.
-     * @return A matcher for the column separators in the given text.
+     * @param  text  the text for which to get a matcher.
+     * @return a matcher for the column separators in the given text.
      */
     protected Matcher getColumnSeparatorMatcher(final CharSequence text) {
         if (parsePattern == null) {

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/InstallationResources.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -46,6 +46,12 @@ import java.io.BufferedReader;
  *     META-INF/services/org.apache.sis.setup.InstallationResources
  * }
  *
+ * Above registration is usually done automatically when extension modules are added on the classpath.
+ * For example adding the {@code org.apache.sis.non-free:​sis-epsg} Maven dependency as documented on
+ * the <a href="http://sis.apache.org/epsg.html">Apache SIS web site</a> is the only step needed for
+ * allowing Apache SIS to read the EPSG scripts (however SIS still needs an installation directory
+ * for writing the database; see above-cited web page for more information).
+ *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
  * @version 0.7

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -175,7 +175,7 @@ public enum ComparisonMode {
      * This method currently returns {@code true} for {@code IGNORE_METADATA}, {@code APPROXIMATIVE}
      * or {@code DEBUG} only, but this list may be extended in future SIS versions.
      *
-     * @return Whether this comparison ignore metadata.
+     * @return whether this comparison ignore metadata.
      *
      * @since 0.6
      */
@@ -188,7 +188,7 @@ public enum ComparisonMode {
      * This method currently returns {@code true} for {@code APPROXIMATIVE} or {@code DEBUG} only,
      * but this list may be extended in future SIS versions.
      *
-     * @return Whether this comparison uses a tolerance threshold.
+     * @return whether this comparison uses a tolerance threshold.
      *
      * @since 0.6
      */
@@ -202,9 +202,9 @@ public enum ComparisonMode {
      *
      * <p><b>Note:</b> this method never return the {@link #DEBUG} mode.</p>
      *
-     * @param  o1 The first object to compare, or {@code null}.
-     * @param  o2 The second object to compare, or {@code null}.
-     * @return The most suitable comparison mode, or {@code null} if the two given objects
+     * @param  o1  the first object to compare, or {@code null}.
+     * @param  o2  the second object to compare, or {@code null}.
+     * @return the most suitable comparison mode, or {@code null} if the two given objects
      *         are not equal according any mode in this enumeration.
      */
     public static ComparisonMode equalityLevel(final Object o1, Object o2) {

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/LenientComparable.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -137,8 +137,8 @@ public interface LenientComparable {
      *       {@code APPROXIMATIVE} mode is incompatible with the transitivity contract.</li>
      * </ul>
      *
-     * @param  other The object to compare to {@code this}.
-     * @param  mode The strictness level of the comparison.
+     * @param  other  the object to compare to {@code this}.
+     * @param  mode   the strictness level of the comparison.
      * @return {@code true} if both objects are equal according the given comparison mode.
      *
      * @see Utilities#deepEquals(Object, Object, ComparisonMode)
@@ -170,7 +170,7 @@ public interface LenientComparable {
      * subclasses override the above {@link #equals(Object, ComparisonMode)} method instead
      * than this one.
      *
-     * @param  other The object to compare to {@code this}.
+     * @param  other  the object to compare to {@code this}.
      * @return {@code true} if both objects are strictly equal.
      *
      * @see ComparisonMode#STRICT

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -22,6 +22,7 @@ import java.util.Map;
 import java.util.LinkedHashMap;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Objects;
 import java.io.Serializable;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
@@ -32,9 +33,6 @@ import static org.apache.sis.util.CharSe
 import static org.apache.sis.util.collection.Containers.isNullOrEmpty;
 import static org.apache.sis.util.collection.Containers.hashMapCapacity;
 
-// Branch-dependent imports
-import java.util.Objects;
-
 
 /**
  * A {@link TreeTable} implementation with a {@linkplain #getColumns() list of columns} given at
@@ -119,7 +117,7 @@ public class DefaultTreeTable implements
      * Creates a new tree table with the given columns. The given array shall not be null or
      * empty, and shall not contain null or duplicated elements.
      *
-     * @param columns The list of table columns.
+     * @param  columns  the list of table columns.
      */
     public DefaultTreeTable(TableColumn<?>... columns) {
         ArgumentChecks.ensureNonNull("columns", columns);
@@ -137,7 +135,7 @@ public class DefaultTreeTable implements
      * Creates a new tree table initialized to the given root.
      * The {@linkplain #getColumns() list of columns} is inferred from the given node.
      *
-     * @param root The tree table root (can not be null).
+     * @param  root  the tree table root (can not be null).
      */
     public DefaultTreeTable(final Node root) {
         ArgumentChecks.ensureNonNull("root", root);
@@ -149,8 +147,8 @@ public class DefaultTreeTable implements
      * Creates a map of column indices from the given list of columns.
      * This method is invoked for initializing the {@link #columnIndices} field.
      *
-     * @param  columns The list of columns.
-     * @return The map of column indices.
+     * @param  columns  the list of columns.
+     * @return the map of column indices.
      */
     static Map<TableColumn<?>,Integer> createColumnIndices(final TableColumn<?>[] columns) {
         Map<TableColumn<?>,Integer> map;
@@ -176,7 +174,7 @@ public class DefaultTreeTable implements
      * Returns all columns in the given map, sorted by increasing index value.
      * This method relies on {@link LinkedHashMap} preserving insertion order.
      *
-     * @return The columns in an array of elements of type {@code TableColumn},
+     * @return the columns in an array of elements of type {@code TableColumn},
      *         <strong>not a subtype</strong> for allowing usage in
      *         {@link UnmodifiableArrayList#wrap(Object[])}.
      */
@@ -192,6 +190,7 @@ public class DefaultTreeTable implements
      * @see Node#setValue(TableColumn, Object)
      */
     @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")         // Safe because returned list is unmodifiable.
     public final List<TableColumn<?>> getColumns() {
         if (columns == null) {
             columns = UnmodifiableArrayList.wrap(getColumns(columnIndices));
@@ -216,8 +215,8 @@ public class DefaultTreeTable implements
      * Sets the root to the given node. If a root already existed prior this method call,
      * then the previous root node will be discarded.
      *
-     * @param  root The new root node (can not be null).
-     * @throws IllegalArgumentException If the table columns in the given node are inconsistent
+     * @param  root  the new root node (can not be null).
+     * @throws IllegalArgumentException if the table columns in the given node are inconsistent
      *         with the table columns in this {@code DefaultTreeTable}.
      */
     public void setRoot(final TreeTable.Node root) {
@@ -236,8 +235,8 @@ public class DefaultTreeTable implements
      * If the root is an instance of {@link Node}, then cloning the root will recursively clone
      * all its {@linkplain Node#getChildren() children}.
      *
-     * @return A clone of this table.
-     * @throws CloneNotSupportedException If this table, the root node or one of its children
+     * @return a clone of this table.
+     * @throws CloneNotSupportedException if this table, the root node or one of its children
      *         can not be cloned.
      *
      * @see Node#clone()
@@ -255,7 +254,7 @@ public class DefaultTreeTable implements
      * later is an instance of the {@link Node} inner class, then all node values and children
      * will be compared recursively.
      *
-     * @param  other The object to compare with this table.
+     * @param  other  the object to compare with this table.
      * @return {@code true} if the two objects are equal.
      *
      * @see Node#equals(Object)
@@ -291,7 +290,7 @@ public class DefaultTreeTable implements
      * developers are encouraged to create and configure their own {@link TreeTableFormat}
      * instance.
      *
-     * @return A string representation of this tree table.
+     * @return a string representation of this tree table.
      */
     @Override
     public String toString() {
@@ -304,15 +303,14 @@ public class DefaultTreeTable implements
 
 
     /**
-     * A {@link TreeTable.Node} implementation which can store values for a pre-defined list
-     * of columns. The list of columns is specified by a {@link TreeTable}, or inherited from
-     * a parent node.
+     * A {@link TreeTable.Node} implementation which can store values for a pre-defined list of columns.
+     * The list of columns is specified by a {@link TreeTable}, or inherited from a parent node.
      *
      * <div class="section">Note on the parent node</div>
-     * The value returned by the {@link #getParent()} method is updated automatically when
-     * this node is <em>added to</em> or <em>removed from</em> the {@linkplain #getChildren()
-     * list of children} of another {@code Node} instance - there is no {@code setParent(Node)}
-     * method. As a derived value, the parent is ignored by the {@link #clone()},
+     * The value returned by the {@link #getParent()} method is updated automatically when this node
+     * is <em>added to</em> or <em>removed from</em> the {@linkplain #getChildren() list of children}
+     * of another {@code Node} instance - there is no {@code setParent(Node)} method. Since the parent
+     * is inferred rather than user-specified, it is ignored by the {@link #clone()},
      * {@link #equals(Object)} and {@link #hashCode()} methods.
      *
      * @author  Martin Desruisseaux (Geomatys)
@@ -344,7 +342,7 @@ public class DefaultTreeTable implements
              * Creates a new, initially empty, node list. The node given in argument to this
              * constructor will be the parent of all nodes added as children to this list.
              *
-             * @param parent The node which will own this list.
+             * @param  parent  the node which will own this list.
              */
             Children(final TreeTable.Node parent) {
                 super(parent);
@@ -410,7 +408,7 @@ public class DefaultTreeTable implements
          * is the caller responsibility to {@linkplain DefaultTreeTable#setRoot set the table root
          * node}.</p>
          *
-         * @param table The table for which this node is created.
+         * @param  table  the table for which this node is created.
          */
         public Node(final TreeTable table) {
             ArgumentChecks.ensureNonNull("table", table);
@@ -428,7 +426,7 @@ public class DefaultTreeTable implements
          * {@linkplain #getChildren() list of children}. The new node will be able to store values
          * for the same columns than the parent node.
          *
-         * @param parent The parent of the new node.
+         * @param  parent  the parent of the new node.
          */
         public Node(final Node parent) {
             ArgumentChecks.ensureNonNull("parent", parent);
@@ -443,8 +441,8 @@ public class DefaultTreeTable implements
          * {@linkplain #getChildren() list of children} at the given index. The new node
          * will be able to store values for the same columns than the parent node.
          *
-         * @param parent The parent of the new node.
-         * @param index  The index where to add the new node in the parent list of children.
+         * @param  parent  the parent of the new node.
+         * @param  index   the index where to add the new node in the parent list of children.
          */
         public Node(final Node parent, final int index) {
             ArgumentChecks.ensureNonNull("parent", parent);
@@ -465,7 +463,7 @@ public class DefaultTreeTable implements
          *   <tr><td>"Name"</td> <td>{@link CharSequence}</td> <td>{@code name}</td></tr>
          * </table>
          *
-         * @param  name The initial value for the "Name" column (can be {@code null}).
+         * @param  name  the initial value for the "Name" column (can be {@code null}).
          */
         public Node(final CharSequence name) {
             columnIndices = TableColumn.NAME_MAP;
@@ -529,6 +527,7 @@ public class DefaultTreeTable implements
          * cast will need to be replaced by an "instanceof" check.
          */
         @Override
+        @SuppressWarnings("ReturnOfCollectionOrArrayField")         // Returned list modifiable on intend.
         public final List<TreeTable.Node> getChildren() {
             if (children == null) {
                 if (isLeaf()) {
@@ -554,7 +553,7 @@ public class DefaultTreeTable implements
          *
          * Subclasses may override this method with different behavior.
          *
-         * @throws UnsupportedOperationException If this node {@linkplain #isLeaf() is a leaf}.
+         * @throws UnsupportedOperationException if this node {@linkplain #isLeaf() is a leaf}.
          */
         @Override
         public Node newChild() {
@@ -567,9 +566,9 @@ public class DefaultTreeTable implements
         /**
          * Returns the value in the given column, or {@code null} if none.
          *
-         * @param  <V>    The base type of values in the given column.
-         * @param  column Identifier of the column from which to get the value.
-         * @return The value in the given column, or {@code null} if none.
+         * @param  <V>     the base type of values in the given column.
+         * @param  column  identifier of the column from which to get the value.
+         * @return the value in the given column, or {@code null} if none.
          */
         @Override
         public <V> V getValue(final TableColumn<V> column) {
@@ -588,10 +587,10 @@ public class DefaultTreeTable implements
          * The {@link #isEditable(TableColumn)} method can be invoked before this setter method
          * for determining if the given column is modifiable.
          *
-         * @param  <V>    The base type of values in the given column.
-         * @param  column Identifier of the column into which to set the value.
-         * @param  value  The value to set.
-         * @throws IllegalArgumentException If the given column is not a legal column for this node.
+         * @param  <V>     the base type of values in the given column.
+         * @param  column  identifier of the column into which to set the value.
+         * @param  value   the value to set.
+         * @throws IllegalArgumentException if the given column is not a legal column for this node.
          *
          * @see #isEditable(TableColumn)
          */
@@ -634,8 +633,8 @@ public class DefaultTreeTable implements
          * but does not clone the column {@linkplain #getValue(TableColumn) values}.
          * The parent of the cloned node is set to {@code null}.
          *
-         * @return A clone of this node without parent.
-         * @throws CloneNotSupportedException If this node or one of its children can not be cloned.
+         * @return a clone of this node without parent.
+         * @throws CloneNotSupportedException if this node or one of its children can not be cloned.
          */
         @Override
         public Node clone() throws CloneNotSupportedException {
@@ -675,7 +674,7 @@ public class DefaultTreeTable implements
          *   <li>For making possible to compare branches instead than only whole trees.</li>
          * </ul></div>
          *
-         * @param  other The object to compare with this node.
+         * @param  other  the object to compare with this node.
          * @return {@code true} if the two objects are equal, ignoring the parent node.
          */
         @Override
@@ -689,7 +688,7 @@ public class DefaultTreeTable implements
                 if (columnIndices.equals(that.columnIndices)) {
                     final Object[] v1 = this.values;
                     final Object[] v2 = that.values;
-                    if (v1 != v2) { // For skipping the loop if v1 and v2 are null.
+                    if (v1 != v2) {                                 // For skipping the loop if v1 and v2 are null.
                         for (int i=columnIndices.size(); --i>=0;) {
                             if (!Objects.equals((v1 != null) ? v1[i] : null,
                                                 (v2 != null) ? v2[i] : null))
@@ -724,14 +723,18 @@ public class DefaultTreeTable implements
             int hash = 0;
             final Object[] values = this.values;
             if (values != null) {
-                // Do not use Objects.hashCode(...) because we want the result of array
-                // containing only null elements to be the same than null array (zero).
+                /*
+                 * Do not use Objects.hashCode(…) because we want the result of array
+                 * containing only null elements to be the same than null array (zero).
+                 */
                 for (int i=values.length; --i>=0;) {
                     hash = 31*hash + Objects.hashCode(values[i]);
                 }
             }
-            // Do not use Objects.hashCode(...) because we
-            // want the same result for null and empty list.
+            /*
+             * Do not use Objects.hashCode(…) because we
+             * want the same result for null and empty list.
+             */
             if (!isNullOrEmpty(children)) {
                 hash += 37 * children.hashCode();
             }
@@ -746,7 +749,7 @@ public class DefaultTreeTable implements
          * where <var>Node</var> is the {@linkplain Class#getSimpleName() simple classname}
          * and <var>i</var> is the index of this node in the parent node.
          *
-         * @return A string representation of this node.
+         * @return a string representation of this node.
          */
         @Override
         public String toString() {

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeNodeList.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -102,9 +102,9 @@ abstract class TreeNodeList extends Abst
      * Returns {@code true} if the node associated to this list is already the parent of the given
      * node, {@code false} if the given node has no parent, or throws an exception otherwise.
      *
-     * @param  node The node for which to check the parent.
+     * @param  node  the node for which to check the parent.
      * @return {@code true} if the given node already has its parent set, or {@code false} otherwise.
-     * @throws IllegalArgumentException If the given node is the children of another list.
+     * @throws IllegalArgumentException if the given node is the children of another list.
      */
     private boolean isParentOf(final TreeTable.Node node) throws IllegalArgumentException {
         if (node == parent) {
@@ -130,16 +130,16 @@ abstract class TreeNodeList extends Abst
      *       do not change the node parent yet.</li>
      * </ul>
      *
-     * @param  node The node on which to set the parent (never {@code null}).
-     * @param  mode One of the {@link #NULL}, {@link #THIS} or {@link #DRY_RUN} constants.
-     * @throws IllegalArgumentException If this method can not set the parent of the given node.
+     * @param  node  the node on which to set the parent (never {@code null}).
+     * @param  mode  one of the {@link #NULL}, {@link #THIS} or {@link #DRY_RUN} constants.
+     * @throws IllegalArgumentException if this method can not set the parent of the given node.
      */
     protected abstract void setParentOf(TreeTable.Node node, int mode) throws IllegalArgumentException;
 
     /**
      * Returns the type of elements in this list.
      *
-     * @return Fixed to {@code TreeTable.Node}.
+     * @return fixed to {@code TreeTable.Node}.
      */
     @Override
     public final Class<TreeTable.Node> getElementType() {
@@ -149,7 +149,7 @@ abstract class TreeNodeList extends Abst
     /**
      * Returns the number of nodes in this list.
      *
-     * @return The number of nodes.
+     * @return the number of nodes.
      */
     @Override
     public final int size() {
@@ -159,8 +159,8 @@ abstract class TreeNodeList extends Abst
     /**
      * Returns the node at the specified index in this list.
      *
-     * @param  index The index of the node to fetch.
-     * @return The node at the given index (never {@code null}).
+     * @param  index  the index of the node to fetch.
+     * @return the node at the given index (never {@code null}).
      */
     @Override
     public TreeTable.Node get(final int index) {
@@ -171,10 +171,10 @@ abstract class TreeNodeList extends Abst
     /**
      * Sets the node at the specified index in this list.
      *
-     * @param  index The index of the node to set.
-     * @param  node The node to store at the given index (can not be {@code null}).
-     * @return The node which was previously stored at the given index (never {@code null}).
-     * @throws IllegalArgumentException If this list can not add the given node, for example
+     * @param  index  the index of the node to set.
+     * @param  node   the node to store at the given index (can not be {@code null}).
+     * @return the node which was previously stored at the given index (never {@code null}).
+     * @throws IllegalArgumentException if this list can not add the given node, for example
      *         if the node is already an element of another {@code TreeNodeList}.
      */
     @Override
@@ -201,9 +201,9 @@ abstract class TreeNodeList extends Abst
      * Adds the given node at the given index in this list, shifting all nodes currently at
      * and after the given index.
      *
-     * @param  index The index where to insert the node.
-     * @param  node The node to store at the given index (can not be {@code null}).
-     * @throws IllegalArgumentException If this list can not add the given node, for example
+     * @param  index  the index where to insert the node.
+     * @param  node   the node to store at the given index (can not be {@code null}).
+     * @throws IllegalArgumentException if this list can not add the given node, for example
      *         if the node is already an element of another {@code TreeNodeList}.
      */
     @Override
@@ -241,8 +241,8 @@ abstract class TreeNodeList extends Abst
      * occur either because the node is a custom user implementation with pre-set parent, or
      * because the node is already presents in this list.
      *
-     * @param  node The node to check.
-     * @throws IllegalArgumentException If the given node is already present in this list.
+     * @param  node  the node to check.
+     * @throws IllegalArgumentException if the given node is already present in this list.
      */
     private void ensureNotPresent(final TreeTable.Node node) throws IllegalArgumentException {
         for (int i=size; --i>=0;) {
@@ -257,7 +257,7 @@ abstract class TreeNodeList extends Abst
      * reverse order (last added nodes are removed first). If this method failed to remove a
      * node, then that node and all nodes at lower index will be left in the list.
      *
-     * @throws IllegalArgumentException If this method failed to remove a node in the given range.
+     * @throws IllegalArgumentException if this method failed to remove a node in the given range.
      */
     @Override
     protected void removeRange(final int lower, final int upper) throws IllegalArgumentException {
@@ -266,7 +266,7 @@ abstract class TreeNodeList extends Abst
         try {
             while (i != lower) {
                 setParentOf(children[i-1], NULL);
-                i--; // Must be decremented only after 'setParentOf' returned successfully.
+                i--;            // Must be decremented only after 'setParentOf' returned successfully.
             }
         } finally {
             modCount++;
@@ -282,8 +282,8 @@ abstract class TreeNodeList extends Abst
      * Removes from this list the node at the given index.
      * All nodes after the given index will be shifted by one.
      *
-     * @param  index The index of the node to remove.
-     * @return The node which was previously at the given index (never {@code null}).
+     * @param  index  the index of the node to remove.
+     * @return the node which was previously at the given index (never {@code null}).
      */
     @Override
     public final TreeTable.Node remove(final int index) throws IllegalArgumentException {
@@ -301,10 +301,10 @@ abstract class TreeNodeList extends Abst
      * The default implementation searches the node using the {@link #indexOf(Object)},
      * then removes it (if the node has been found) using the {@link #remove(int)} method.
      *
-     * @param  node The node to remove. {@code null} values are ignored.
-     * @return {@code true} if the node has been removed, or {@code false} if this list doesn't
+     * @param  node  the node to remove. {@code null} values are ignored.
+     * @return {@code true} if the node has been removed, or {@code false} if this list does not
      *         contain the given node.
-     * @throws IllegalArgumentException If the node has been found but this list can not remove it.
+     * @throws IllegalArgumentException if the node has been found but this list can not remove it.
      */
     @Override
     public boolean remove(final Object node) throws IllegalArgumentException {
@@ -321,7 +321,7 @@ abstract class TreeNodeList extends Abst
      * if the {@linkplain TreeTable.Node#getParent() node parent} is the {@link #parent} instance.
      * This implementation does not iterate over the children.
      *
-     * @param  node The node to check (can be {@code null}).
+     * @param  node  the node to check (can be {@code null}).
      * @return {@code true} if this list contains the given node.
      */
     @Override
@@ -334,8 +334,8 @@ abstract class TreeNodeList extends Abst
      * This method delegates to {@link #lastIndexOf(Object)} because the list is not
      * expected to contain duplicated values.
      *
-     * @param  node The node to search (can be {@code null}).
-     * @return Index of the given node, or -1 if not found.
+     * @param  node  the node to search (can be {@code null}).
+     * @return index of the given node, or -1 if not found.
      */
     @Override
     public final int indexOf(final Object node) {
@@ -345,8 +345,8 @@ abstract class TreeNodeList extends Abst
     /**
      * Returns the index of the last occurrence of the specified node in this list.
      *
-     * @param  node The node to search (can be {@code null}).
-     * @return Index of the given node, or -1 if not found.
+     * @param  node  the node to search (can be {@code null}).
+     * @return index of the given node, or -1 if not found.
      */
     @Override
     public final int lastIndexOf(final Object node) {

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -74,7 +74,7 @@ public interface TreeTable {
      * tree. However any {@link Node} instance can return {@code null} for a
      * particular column if the node doesn't have that column.
      *
-     * @return The union of all table columns in every tree node.
+     * @return the union of all table columns in every tree node.
      *
      * @see Node#getValue(TableColumn)
      * @see Node#setValue(TableColumn, Object)
@@ -84,7 +84,7 @@ public interface TreeTable {
     /**
      * Returns the root node of the tree.
      *
-     * @return The root node of the tree.
+     * @return the root node of the tree.
      */
     Node getRoot();
 
@@ -119,7 +119,7 @@ public interface TreeTable {
      *
      * @author  Martin Desruisseaux (IRD, Geomatys)
      * @since   0.3
-     * @version 0.3
+     * @version 0.8
      * @module
      */
     public static interface Node {
@@ -131,7 +131,7 @@ public interface TreeTable {
          * modifiable, then implementations are encouraged to update automatically the parent when a child
          * is <em>added to</em> or <em>removed from</em> that collection.</p>
          *
-         * @return The parent, or {@code null} if none.
+         * @return the parent, or {@code null} if none.
          * @category tree
          */
         Node getParent();
@@ -163,7 +163,7 @@ public interface TreeTable {
          * {@linkplain org.apache.sis.metadata.AbstractMetadata#asTreeTable() metadata tree table view},
          * compliance to the {@code List} contract is impractical or inefficient.
          *
-         * @return The children, or an empty collection if none.
+         * @return the children, or an empty collection if none.
          * @category tree
          */
         Collection<Node> getChildren();
@@ -174,17 +174,17 @@ public interface TreeTable {
          * the end of the collection, but this is not mandatory: implementations can add the child
          * at whatever position they see fit.
          *
-         * @return The new child.
-         * @throws UnsupportedOperationException If this node can not add new children.
+         * @return the new child.
+         * @throws UnsupportedOperationException if this node can not add new children.
          */
         Node newChild() throws UnsupportedOperationException;
 
         /**
          * Returns the value in the given column, or {@code null} if none.
          *
-         * @param  <V>    The base type of values in the given column.
-         * @param  column Identifier of the column from which to get the value.
-         * @return The value in the given column, or {@code null} if none.
+         * @param  <V>     the base type of values in the given column.
+         * @param  column  identifier of the column from which to get the value.
+         * @return the value in the given column, or {@code null} if none.
          *
          * @see TreeTable#getColumns()
          * @category table
@@ -196,11 +196,11 @@ public interface TreeTable {
          * The {@link #isEditable(TableColumn)} method can be invoked before this setter method
          * for determining if the given column is modifiable.
          *
-         * @param  <V>    The base type of values in the given column.
-         * @param  column Identifier of the column into which to set the value.
-         * @param  value  The value to set.
-         * @throws IllegalArgumentException If the given column is not a legal column for this node.
-         * @throws UnsupportedOperationException If values in the given column can not be modified.
+         * @param  <V>     the base type of values in the given column.
+         * @param  column  identifier of the column into which to set the value.
+         * @param  value   the value to set.
+         * @throws IllegalArgumentException if the given column is not a legal column for this node.
+         * @throws UnsupportedOperationException if values in the given column can not be modified.
          *
          * @see TreeTable#getColumns()
          * @see #isEditable(TableColumn)
@@ -213,7 +213,7 @@ public interface TreeTable {
          * column is not a legal column for this {@code Node} instance, then this method
          * returns {@code false}.
          *
-         * @param  column The column to query.
+         * @param  column  the column to query.
          * @return {@code true} if the given column is a legal column for this {@code Node}
          *         implementation and the corresponding value is editable, or {@code false}
          *         otherwise.
@@ -231,9 +231,112 @@ public interface TreeTable {
          * <var>longitude</var>) tuple, then a {@code TreeTable.Node} could be defined to have 3 columns for the
          * above 3 tuple components, and the user object could be the original {@code CityLocation} instance.</div>
          *
-         * @return Any object stored at this node by the user, or {@code null} if none.
+         * @return any object stored at this node by the user, or {@code null} if none.
          * @category tree
          */
         Object getUserObject();
+
+        /**
+         * Returns {@code true} if the given object is a node with the same content than this node.
+         * For this method, the meaning of <cite>same content</cite> is defined as below:
+         *
+         * <ul>
+         *   <li>The given object is also a {@code Node}.</li>
+         *   <li>The list returned by {@link TreeTable#getColumns()} is equals for both nodes.</li>
+         *   <li>The objects returned by {@link #getValue(TableColumn)} are equal for each column.</li>
+         *   <li>The list returned by {@linkplain #getChildren() children} is equals for both node.</li>
+         * </ul>
+         *
+         * The node returned by {@link #getParent()} shall <strong>not</strong> be taken in account.
+         * It is necessary to ignore the parent for consistency with {@linkplain DefaultTreeTable#clone() clone}
+         * and for avoiding infinite recursivity when comparing the children.
+         * A third reason is given in the <cite>purpose</cite> example below.
+         *
+         * <div class="note"><b>Purpose of this method: example with ISO metadata</b><br>
+         * Consider the following tree made of ISO 19115 metadata objects: a platform containing a list of instruments,
+         * and an instrument containing a reference to the platform on which the instrument is installed. In this example,
+         * nodes 2 and 4 contain a reference to the same {@code Platform} instance, so we have a cyclic graph:
+         *
+         * <table class="compact" summary="Metadata tree example">
+         * <tr><th>Node 1:</th><td>{@code  }{@linkplain org.apache.sis.metadata.iso.acquisition.DefaultAcquisitionInformation Acquisition information}</td></tr>
+         * <tr><th>Node 2:</th><td>{@code   └─}{@linkplain org.apache.sis.metadata.iso.acquisition.DefaultPlatform Platform}</td></tr>
+         * <tr><th>Node 3:</th><td>{@code      └─}{@linkplain org.apache.sis.metadata.iso.acquisition.DefaultInstrument Instrument}</td></tr>
+         * <tr><th>Node 4:</th><td>{@code         └─}{@linkplain org.apache.sis.metadata.iso.acquisition.DefaultPlatform Platform} (same instance than above)</td></tr>
+         * <tr><th>Node 5:</th><td>{@code            └─}<i>etc…</i></td></tr>
+         * </table>
+         *
+         * The {@link org.apache.sis.metadata.AbstractMetadata#asTreeTable()} method gives a view in which each node
+         * has its content fully generated from wrapped metadata object. Consequently a naive walk over the above tree
+         * causes an infinite loop with {@code TreeTable} generating nodes with identical content as we bounce between
+         * {@code Platform} and {@code Instrument} metadata objects. To break this loop, we need to know when the
+         * <em>content</em> of a node (in this example, the wrapped metadata object) has already been visited.
+         * The parent shall <strong>not</strong> be taken in account since node 2 and 4 have different parents
+         * despite having the same {@code Platform} content.
+         *
+         * <p>In this use case, the {@code Node.equals(Object)} implementation needs only to compare the wrapped
+         * metadata (usually given by the {@linkplain #getUserObject() user object}) since the node content,
+         * including the list of children, is fully determined by those metadata. An identity comparison
+         * (with {@code ==}) is sufficient for the purpose of avoiding infinite recursivity.</p></div>
+         *
+         * <div class="section">Flexibility in implementations</div>
+         * The above list specifies minimal conditions that must be true when two nodes are considered equal.
+         * Implementations should not relax those conditions, but are free to make them more restrictive.
+         * In particular, many implementations will require that the two nodes are instances of the same class.
+         * Some implementations may also perform identity comparisons (with the {@code ==} operator) between values
+         * instead than using {@link Object#equals(Object)}. This flexibility means that even if all above conditions
+         * are true, this is not a guarantee that this method will return {@code true}.
+         *
+         * <p>It is okay to <em>not</em> override this method at all since the identity comparison inherited from
+         * {@link Object#equals(Object)} is consistent with this method contract. Alternatively, {@code Node}
+         * implementations having a content fully determined by the wrapped {@linkplain #getUserObject() user
+         * object} need only the following implementation:</p>
+         *
+         * {@preformat java
+         *     &#64;Override
+         *     public boolean equals(Object obj) {
+         *         return (obj instanceof MyNode) && ((MyNode) obj).getUserObject() == getUserObject();
+         *     }
+         * }
+         *
+         * Implementation details may vary, for example in the way to compare {@code null} user objects or by invoking
+         * {@link Object#equals(Object)} instead than performing identity comparisons. Note however that since this
+         * method purpose is to detect cyclic graphs (see above example), user objects should be compared with
+         * {@code equals(Object)} only if their implementations are known to be safe against infinite recursivity.
+         *
+         * @param  other  the other object to compare with this node.
+         * @return whether the two objects are nodes with equal values and equal children, ignoring parents.
+         *
+         * @since 0.8
+         */
+        @Override
+        boolean equals(Object other);
+
+        /**
+         * Returns a hash code value consistent with the {@code equals(Object)} implementation for this node.
+         * If the {@link #equals(Object)} method has not been overridden, then this {@code hashCode()} method
+         * should not be overridden neither. Otherwise if this node content ({@linkplain #getValue values} and
+         * {@linkplain #getChildren() children}) is fully generated from the {@linkplain #getUserObject() user
+         * object}, then the {@code equals(…)} and {@code hashCode()} methods may be implemented like below:
+         *
+         * {@preformat java
+         *     &#64;Override
+         *     public boolean equals(Object obj) {
+         *         return (obj instanceof MyNode) && ((MyNode) obj).getUserObject() == getUserObject();
+         *     }
+         *
+         *     &#64;Override
+         *     public int hashCode() {
+         *         return System.identityHashCode(getUserObject());
+         *     }
+         * }
+         *
+         * Otherwise this method should compute a hash code based on values and children of this node, ignoring parent.
+         *
+         * @return a hash code for this node, potentially based on values and children but ignoring parent.
+         *
+         * @since 0.8
+         */
+        @Override
+        int hashCode();
     }
 }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -17,13 +17,15 @@
 package org.apache.sis.util.collection;
 
 import java.util.Arrays;
-import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.TimeZone;
 import java.util.Currency;
+import java.util.ConcurrentModificationException;
 import java.io.IOException;
 import java.text.Format;
 import java.text.ParsePosition;
@@ -98,7 +100,7 @@ import static org.apache.sis.util.Charac
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
 public class TreeTableFormat extends TabularFormat<TreeTable> {
@@ -159,10 +161,10 @@ public class TreeTableFormat extends Tab
     private transient String treeBlank, treeLine, treeCross, treeEnd;
 
     /**
-     * The map to be given to {@link Writer#parentObjects}, created when first needed
-     * and reused for subsequent formating.
+     * The set to be given to {@link Writer#parentObjects},
+     * created when first needed and reused for subsequent formating.
      */
-    private transient Map<Object,Object> parentObjects;
+    private transient Set<TreeTable.Node> recursivityGuard;
 
     /**
      * Creates a new tree table format.
@@ -585,18 +587,9 @@ public class TreeTableFormat extends Tab
         private boolean[] isLast;
 
         /**
-         * The {@linkplain TreeTable.Node#getUserObject() user object} of the parent nodes.
-         * We use this map as a safety against infinite recursivity, on the assumption that
-         * the node content and children are fully determined by the user object.
-         *
-         * <p>User objects in this map will be compared by the identity comparator rather than by the
-         * {@code equals(Object)} method because the later may be costly and could itself be vulnerable
-         * to infinite recursivity if it has not been implemented defensively.</p>
-         *
-         * <p>We check the user object instead than the node itself because the same node instance can
-         * theoretically not appear twice with a different parent.</p>
+         * The node that have already been formatted. We use this map as a safety against infinite recursivity.
          */
-        private final Map<Object,Object> parentObjects;
+        private final Set<TreeTable.Node> recursivityGuard;
 
         /**
          * The format for the column in process of being written. This is a format to use for the column as a whole.
@@ -607,17 +600,17 @@ public class TreeTableFormat extends Tab
         /**
          * Creates a new instance which will write to the given appendable.
          *
-         * @param  out            where to format the tree.
-         * @param  column         the columns of the tree table to format.
-         * @param  parentObjects  an initially empty {@link IdentityHashMap}.
+         * @param  out               where to format the tree.
+         * @param  column            the columns of the tree table to format.
+         * @param  recursivityGuard  an initially empty set.
          */
-        Writer(final Appendable out, final TableColumn<?>[] columns, final Map<Object,Object> parentObjects) {
+        Writer(final Appendable out, final TableColumn<?>[] columns, final Set<TreeTable.Node> recursivityGuard) {
             super(columns.length >= 2 ? new TableAppender(out, "") : out);
             this.columns = columns;
             this.formats = getFormats(columns, false);
             this.values  = new Object[columns.length];
             this.isLast  = new boolean[8];
-            this.parentObjects = parentObjects;
+            this.recursivityGuard = recursivityGuard;
             setTabulationExpanded(true);
             setLineSeparator(" ¶ ");
         }
@@ -707,9 +700,7 @@ public class TreeTableFormat extends Tab
          * If the collection contains other collections, the other collections will <strong>not</strong>
          * be written recursively.
          */
-        private void formatCollection(final Iterable<?> values, final boolean recursive)
-                throws IOException
-        {
+        private void formatCollection(final Iterable<?> values, final boolean recursive) throws IOException {
             if (values != null) {
                 if (recursive) {
                     append('…');                                // Do not format collections inside collections.
@@ -771,25 +762,30 @@ public class TreeTableFormat extends Tab
             }
             /*
              * Format the children only if we do not detect an infinite recursivity. Our recursivity detection
-             * algorithm assumes that the node content is fully determined by the user object. If that assumption
-             * holds, then we have an infinite recursivity if the user object of the current node is also the user
-             * object of a parent node.
+             * algorithm assumes that the Node.equals(Object) method has been implemented as specified in its javadoc.
+             * In particular, the implementation may compare the values and children but shall not compare the parent.
              *
-             * Note that the value stored in the 'parentObjects' map needs to be the 'userObject' because we want
-             * the map value to be null if the user object is null, in order to format the children even if many
-             * null user objects exist in the tree.
+             * We skip the check for the particular case of DefaultTreeTable.Node implementation because it performs
+             * a real check of values and children, which is a little bit costly and known to be unnecessary in that
+             * particular case.
              */
-            final Object userObject = node.getUserObject();
-            if (parentObjects.put(userObject, userObject) == null) {
+            final boolean omitCheck = (node.getClass() == DefaultTreeTable.Node.class);
+            if (omitCheck || recursivityGuard.add(node)) {
                 final Iterator<? extends TreeTable.Node> it = node.getChildren().iterator();
                 boolean hasNext = it.hasNext();
                 while (hasNext) {
                     final TreeTable.Node child = it.next();
                     hasNext = it.hasNext();
-                    isLast[level] = !hasNext; // Must be set before the call to 'format' below.
+                    isLast[level] = !hasNext;                   // Must be set before the call to 'format' below.
                     format(child, level+1);
                 }
-                parentObjects.remove(userObject);
+                if (!omitCheck && !recursivityGuard.remove(node)) {
+                    /*
+                     * Assuming that Node.hashCode() and Node.equals(Object) implementation are not broken,
+                     * this exception may happen only if the node content changed during this method execution.
+                     */
+                    throw new ConcurrentModificationException();
+                }
             } else {
                 /*
                  * Detected a recursivity. Format "(cycle omitted)" just below the node.
@@ -798,7 +794,7 @@ public class TreeTableFormat extends Tab
                     out.append(getTreeSymbols(true, isLast[i]));
                 }
                 final Locale locale = getDisplayLocale();
-                out.append('(').append(Vocabulary.getResources(locale)
+                out.append(treeBlank).append('(').append(Vocabulary.getResources(locale)
                    .getString(Vocabulary.Keys.CycleOmitted).toLowerCase(locale))
                    .append(')').append(lineSeparator);
             }
@@ -831,15 +827,27 @@ public class TreeTableFormat extends Tab
             final List<TableColumn<?>> c = tree.getColumns();
             columns = c.toArray(new TableColumn<?>[c.size()]);
         }
-        if (parentObjects == null) {
-            parentObjects = new IdentityHashMap<>();
+        if (recursivityGuard == null) {
+            recursivityGuard = new HashSet<>();
         }
         try {
-            final Writer out = new Writer(toAppendTo, columns, parentObjects);
+            final Writer out = new Writer(toAppendTo, columns, recursivityGuard);
             out.format(tree.getRoot(), 0);
             out.flush();
         } finally {
-            parentObjects.clear();
+            recursivityGuard.clear();
         }
     }
+
+    /**
+     * Returns a clone of this format.
+     *
+     * @return a clone of this format.
+     */
+    @Override
+    public TreeTableFormat clone() {
+        final TreeTableFormat c = (TreeTableFormat) super.clone();
+        c.recursivityGuard = null;
+        return c;
+    }
 }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifiedObject.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -90,7 +90,7 @@ public interface IdentifiedObject {
      * Note that XML ID attribute are actually unique only in the scope of the XML document
      * being processed.
      *
-     * @return All identifiers associated to this object, or an empty collection if none.
+     * @return all identifiers associated to this object, or an empty collection if none.
      *
      * @see org.apache.sis.metadata.iso.citation.DefaultCitation#getIdentifiers()
      * @see org.apache.sis.metadata.iso.acquisition.DefaultObjective#getIdentifiers()
@@ -126,7 +126,7 @@ public interface IdentifiedObject {
      * The map supports {@link IdentifierMap#put(Object, Object) put} operations
      * if and only if this {@code IdentifiedObject} is modifiable.
      *
-     * @return The identifiers as a map of (<var>authority</var>, <var>code</var>) entries,
+     * @return the identifiers as a map of (<var>authority</var>, <var>code</var>) entries,
      *         or an empty map if none.
      */
     IdentifierMap getIdentifierMap();

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierMap.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -47,9 +47,9 @@ public interface IdentifierMap extends M
      * or {@code null} if this map contains no mapping of the
      * specialized type for the namespace.
      *
-     * @param  <T> The identifier type.
-     * @param  authority The namespace whose associated identifier is to be returned.
-     * @return The identifier to which the given namespace is mapped, or
+     * @param  <T>        the identifier type.
+     * @param  authority  the namespace whose associated identifier is to be returned.
+     * @return the identifier to which the given namespace is mapped, or
      *         {@code null} if this map contains no mapping for the namespace.
      */
     <T> T getSpecialized(IdentifierSpace<T> authority);
@@ -59,12 +59,12 @@ public interface IdentifierMap extends M
      * (optional operation). If the map previously contained a mapping for
      * the namespace, then the old value is replaced by the specified value.
      *
-     * @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}.
-     * @throws UnsupportedOperationException If the identifier map is unmodifiable.
+     * @throws UnsupportedOperationException if the identifier map is unmodifiable.
      */
     <T> T putSpecialized(IdentifierSpace<T> authority, T value) throws UnsupportedOperationException;
 }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/IdentifierSpace.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -42,7 +42,7 @@ import org.apache.sis.internal.jaxb.NonM
  * The values defined in this interface can be used as keys in the map returned by
  * {@link IdentifiedObject#getIdentifierMap()}.
  *
- * @param <T> The type of object used as identifier values.
+ * @param  <T>  the type of object used as identifier values.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
@@ -124,7 +124,7 @@ public interface IdentifierSpace<T> exte
      *       identifiers are marshalled as {@code <MD_Identifier>} XML elements rather than attributes.</li>
      * </ul>
      *
-     * @return The name of this identifier space (may be XML attribute name).
+     * @return the name of this identifier space (may be XML attribute name).
      */
     String getName();
 }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java?rev=1778893&r1=1778892&r2=1778893&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java [UTF-8] Sun Jan 15 09:20:18 2017
@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Objects;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationHandler;
@@ -33,9 +34,6 @@ import org.apache.sis.util.resources.Err
 import org.apache.sis.internal.jaxb.IdentifierMapAdapter;
 import org.apache.sis.internal.jaxb.ModifiableIdentifierMap;
 
-// Branch-dependent imports
-import java.util.Objects;
-
 
 /**
  * The handler for an object where all methods returns null or empty collections, except
@@ -102,7 +100,7 @@ final class NilObjectHandler implements
                 return type;
             }
         }
-        throw new AssertionError(proxy); // Should not happen.
+        throw new AssertionError(proxy);                                // Should not happen.
     }
 
     /**
@@ -186,7 +184,7 @@ final class NilObjectHandler implements
             return attribute.equals(h.attribute);
         }
         switch (mode) {
-            case STRICT: return false; // The above test is the only relevant one for this mode.
+            case STRICT: return false;              // The above test is the only relevant one for this mode.
             case BY_CONTRACT: {
                 Object tx = attribute, ox = null;
                 if (tx instanceof IdentifierMapAdapter) {
@@ -223,10 +221,10 @@ final class NilObjectHandler implements
                 }
                 if (value != null) {
                     if ((value instanceof Collection<?>) && ((Collection<?>) value).isEmpty()) {
-                        continue; // Empty collection, which is consistent with this proxy behavior.
+                        continue;           // Empty collection, which is consistent with this proxy behavior.
                     }
                     if ((value instanceof Map<?,?>) && ((Map<?,?>) value).isEmpty()) {
-                        continue; // Empty collection, which is consistent with this proxy behavior.
+                        continue;           // Empty collection, which is consistent with this proxy behavior.
                     }
                     return false;
                 }

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=1778893&r1=1778892&r2=1778893&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] Sun Jan 15 09:20:18 2017
@@ -72,13 +72,13 @@ public class ReferenceResolver {
      *       {@code false}, depending on the method return type.</li>
      * </ul>
      *
-     * @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  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}.
-     * @return An object of the given type for the given identifiers, or {@code null} if none.
+     * @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  identifiers  an arbitrary amount of identifiers. For each identifier,
+     *         the {@linkplain org.apache.sis.metadata.iso.ImmutableIdentifier#getAuthority() authority}
+     *         is typically (but not necessarily) one of the constants defined in {@link IdentifierSpace}.
+     * @return an object of the given type for the given identifiers, or {@code null} if none.
      */
     @SuppressWarnings("unchecked")
     public <T> T newIdentifiedObject(final MarshalContext context, final Class<T> type, final Identifier... identifiers) {
@@ -94,11 +94,11 @@ public class ReferenceResolver {
      * Returns an object of the given type for the given {@code uuid} attribute, or {@code null} if none.
      * The default implementation returns {@code null} in all cases.
      *
-     * @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  uuid The {@code uuid} attributes.
-     * @return An object of the given type for the given {@code uuid} attribute, or {@code null} if none.
+     * @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  uuid     the {@code uuid} attributes.
+     * @return an object of the given type for the given {@code uuid} attribute, or {@code null} if none.
      */
     @SuppressWarnings("unchecked")
     public <T> T resolve(final MarshalContext context, final Class<T> type, final UUID uuid) {
@@ -118,11 +118,11 @@ public class ReferenceResolver {
      *   <li>Otherwise returns {@code null}.</li>
      * </ul>
      *
-     * @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  link    The {@code xlink} attributes.
-     * @return An object of the given type for the given {@code xlink} attribute, or {@code null} if none.
+     * @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  link     the {@code xlink} attributes.
+     * @return an object of the given type for the given {@code xlink} attribute, or {@code null} if none.
      */
     public <T> T resolve(final MarshalContext context, final Class<T> type, final XLink link) {
         ensureNonNull("type",  type);
@@ -173,11 +173,11 @@ public class ReferenceResolver {
      * <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.
+     * @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.
      *
@@ -202,11 +202,11 @@ public class ReferenceResolver {
      *
      * Subclasses can override this method if they know whether the receiver will be able to resolve the 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 unmarshalled, often as a GeoAPI interface.
-     * @param  object  The object to be marshalled.
-     * @param  uuid    The unique identifier of the object to be marshalled.
+     * @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  uuid     the unique identifier of the object to be marshalled.
      * @return {@code true} if the marshaller can use the {@code uuidref} attribute
      *         instead than marshalling the given object.
      */
@@ -229,11 +229,11 @@ public class ReferenceResolver {
      *
      * Subclasses can override this method if they know whether the receiver will be able to resolve the 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 unmarshalled, often as a GeoAPI interface.
-     * @param  object  The object to be marshalled.
-     * @param  link    The reference of the object to be marshalled.
+     * @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  link     the reference of the object to be marshalled.
      * @return {@code true} if the marshaller can use the {@code xlink:href} attribute
      *         instead than marshalling the given object.
      */
@@ -263,15 +263,14 @@ public class ReferenceResolver {
      * </td></tr>
      * </table>
      *
-     * Subclasses can override this method if they can provide a mapping from some text
-     * values to anchors.
+     * Subclasses can override this method if they can provide a mapping from some text values to anchors.
      *
-     * @param  context Context (GML version, locale, <i>etc.</i>) of the (un)marshalling process.
-     * @param  value   The value for which an anchor is requested. Often the same instance than {@code text},
-     *                 but can also be the {@link java.net.URI} or {@link java.util.Locale} instance for which
-     *                 {@code text} is a string representation.
-     * @param  text    The textual representation of the value for which to get the anchor.
-     * @return The anchor for the given text, or {@code null} if none.
+     * @param  context  context (GML version, locale, <i>etc.</i>) of the (un)marshalling process.
+     * @param  value    the value for which an anchor is requested. Often the same instance than {@code text},
+     *                  but can also be the {@link java.net.URI} or {@link java.util.Locale} instance for which
+     *                  {@code text} is a string representation.
+     * @param  text     the textual representation of the value for which to get the anchor.
+     * @return the anchor for the given text, or {@code null} if none.
      */
     public XLink anchor(final MarshalContext context, final Object value, final CharSequence text) {
         return (text instanceof Anchor) ? (Anchor) text : null;



Mime
View raw message