sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1519001 - in /sis/branches/JDK7/core: sis-metadata/src/main/java/org/apache/sis/metadata/ sis-referencing/src/main/java/org/apache/sis/geometry/ sis-referencing/src/main/java/org/apache/sis/internal/referencing/ sis-referencing/src/main/ja...
Date Fri, 30 Aug 2013 15:54:46 GMT
Author: desruisseaux
Date: Fri Aug 30 15:54:46 2013
New Revision: 1519001

URL: http://svn.apache.org/r1519001
Log:
Clarify a bit the policy on null collections in private fields of AbstractIdentifiedObject,
and ported implementation of equals(Object, ComparisonMode).

Added:
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
      - copied, changed from r1518914, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Utilities.java
Removed:
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Utilities.java
Modified:
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java?rev=1519001&r1=1519000&r2=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java
[UTF-8] Fri Aug 30 15:54:46 2013
@@ -101,7 +101,7 @@ final class Cloner extends org.apache.si
                 // Do not use the SIS Checked* classes since
                 // we don't need type checking anymore.
                 if (isSet) {
-                    collection = CollectionsExt.immutableSet(array);
+                    collection = CollectionsExt.immutableSet(false, array);
                 } else {
                     // Conservatively assumes a List if we are not sure to have a Set,
                     // since the list is less destructive (no removal of duplicated).

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java?rev=1519001&r1=1519000&r2=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/ArrayEnvelope.java
[UTF-8] Fri Aug 30 15:54:46 2013
@@ -38,7 +38,7 @@ import org.apache.sis.referencing.CRS;
 
 import static org.apache.sis.util.ArgumentChecks.*;
 import static org.apache.sis.math.MathFunctions.isNegative;
-import static org.apache.sis.internal.referencing.Utilities.isPoleToPole;
+import static org.apache.sis.internal.referencing.Formulas.isPoleToPole;
 
 // Related to JDK7
 import java.util.Objects;
@@ -90,6 +90,11 @@ class ArrayEnvelope extends AbstractEnve
         this.ordinates = ordinates;
     }
 
+    /*
+     * Constructors below this point have public access because if we decided to make class
+     * ArrayEnvelope public, then we would probably want to make those constructors public
too.
+     */
+
     /**
      * Constructs an envelope defined by two corners given as direct positions.
      * If at least one corner is associated to a CRS, then the new envelope will also

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java?rev=1519001&r1=1519000&r2=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
[UTF-8] Fri Aug 30 15:54:46 2013
@@ -38,7 +38,7 @@ import static org.apache.sis.math.MathFu
 import static org.apache.sis.math.MathFunctions.isNegative;
 import static org.apache.sis.math.MathFunctions.isSameSign;
 import static org.apache.sis.util.ArgumentChecks.ensureDimensionMatches;
-import static org.apache.sis.internal.referencing.Utilities.isPoleToPole;
+import static org.apache.sis.internal.referencing.Formulas.isPoleToPole;
 
 // Following imports are needed because we can't extend AbstractEnvelope.
 // We want to write this class as if it was an AbstractEnvelope subclass.

Copied: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
(from r1518914, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Utilities.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java?p2=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Utilities.java&r1=1518914&r2=1519001&rev=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Utilities.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
[UTF-8] Fri Aug 30 15:54:46 2013
@@ -23,7 +23,7 @@ import static java.lang.Math.*;
 
 
 /**
- * Miscellaneous utilities which should not be put in public API.
+ * Miscellaneous numerical utilities which should not be put in public API.
  * This class contains methods that depend on hard-coded arbitrary tolerance threshold, and
we
  * do not want to expose publicly those arbitrary values (or at least not in a too direct
way).
  *
@@ -32,7 +32,7 @@ import static java.lang.Math.*;
  * @version 0.3
  * @module
  */
-public final class Utilities extends Static {
+public final class Formulas extends Static {
     /**
      * Default tolerance threshold for comparing ordinate values in a projected CRS,
      * assuming that the unit of measurement is metre. This is not a tolerance for
@@ -56,7 +56,7 @@ public final class Utilities extends Sta
     /**
      * Do not allow instantiation of this class.
      */
-    private Utilities() {
+    private Formulas() {
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1519001&r1=1519000&r2=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
[UTF-8] Fri Aug 30 15:54:46 2013
@@ -49,17 +49,22 @@ import org.apache.sis.util.iso.Types;
 import org.apache.sis.util.resources.Errors;
 
 import static org.apache.sis.util.ArgumentChecks.*;
+import static org.apache.sis.util.Utilities.deepEquals;
 import static org.apache.sis.internal.util.Citations.iterator;
 import static org.apache.sis.internal.util.CollectionsExt.nonNull;
+import static org.apache.sis.internal.util.CollectionsExt.nonEmpty;
 import static org.apache.sis.internal.util.CollectionsExt.immutableSet;
 
+// Related to JDK7
+import java.util.Objects;
+
 
 /**
  * Base class for objects identified by a name or a code. Those objects are typically
  * {@linkplain org.apache.sis.referencing.datum.DefaultGeodeticDatum geodetic datum}   (e.g.
"<cite>World Geodetic System 1984</cite>"),
  * {@linkplain org.apache.sis.referencing.crs.AbstractCRS Coordinate Reference System} (e.g.
"<cite>WGS 84 / World Mercator</cite>") or
  * {@linkplain org.apache.sis.referencing.operation.DefaultProjection map projection}  (e.g.
"<cite>Mercator (variant A)</cite>").
- * Those names, or a code (e.g. {@code "EPSG:3395"}) can be used for fetching an object from
a database.
+ * Those names, or a code (e.g. {@code "EPSG:3395"}), can be used for fetching an object
from a database.
  * However it is not sufficient to know the object name. We also need to know who define
that name
  * (the {@linkplain NamedIdentifier#getAuthority() authority}) since the same objects are
often named differently
  * depending on the providers, or conversely the same name is used for different objects
depending on the provider.
@@ -121,7 +126,9 @@ public class AbstractIdentifiedObject ex
     private final ReferenceIdentifier name;
 
     /**
-     * An alternative name by which this object is identified.
+     * An alternative name by which this object is identified, or {@code null} if none.
+     * We must be prepared to handle either null or an empty set for "no alias" because
+     * we may get both on unmarshalling.
      */
     private final Collection<GenericName> alias;
 
@@ -129,6 +136,9 @@ public class AbstractIdentifiedObject ex
      * An identifier which references elsewhere the object's defining information.
      * Alternatively an identifier by which this object can be referenced.
      *
+     * <p>We must be prepared to handle either null or an empty set for
+     * "no identifiers" because we may get both on unmarshalling.</p>
+     *
      * @see #getIdentifiers()
      * @see #getIdentifier()
      */
@@ -158,10 +168,10 @@ public class AbstractIdentifiedObject ex
      */
     public AbstractIdentifiedObject(final IdentifiedObject object) {
         ensureNonNull("object", object);
-        name        =         object.getName();
-        alias       = nonNull(object.getAlias());
-        identifiers = nonNull(object.getIdentifiers());
-        remarks     =         object.getRemarks();
+        name        =          object.getName();
+        alias       = nonEmpty(object.getAlias()); // Favor null for empty set in case it
is not Collections.EMPTY_SET
+        identifiers = nonEmpty(object.getIdentifiers());
+        remarks     =          object.getRemarks();
     }
 
     /**
@@ -248,7 +258,7 @@ public class AbstractIdentifiedObject ex
         // -------------------------------------------------------------------
         value = properties.get(ALIAS_KEY);
         try {
-            alias = immutableSet(Types.toGenericNames(value, null));
+            alias = immutableSet(true, Types.toGenericNames(value, null));
         } catch (ClassCastException e) {
             throw (IllegalArgumentException) illegalPropertyType(ALIAS_KEY, value).initCause(e);
         }
@@ -262,7 +272,7 @@ public class AbstractIdentifiedObject ex
         } else if (value instanceof ReferenceIdentifier) {
             identifiers = Collections.singleton((ReferenceIdentifier) value);
         } else if (value instanceof ReferenceIdentifier[]) {
-            identifiers = immutableSet((ReferenceIdentifier[]) value);
+            identifiers = immutableSet(true, (ReferenceIdentifier[]) value);
         } else {
             throw illegalPropertyType(IDENTIFIERS_KEY, value);
         }
@@ -348,7 +358,7 @@ public class AbstractIdentifiedObject ex
      *
      * @return The primary name.
      *
-     * @see Citations#getName(IdentifiedObject, Citation)
+     * @see IdentifiedObjects#getName(IdentifiedObject, Citation)
      */
     @Override
     public ReferenceIdentifier getName() {
@@ -478,9 +488,89 @@ public class AbstractIdentifiedObject ex
         return eq;
     }
 
+    /**
+     * Compares this object with the specified object for equality.
+     * The strictness level is controlled by the second argument:
+     *
+     * <ul>
+     *   <li>If {@code mode} is {@link ComparisonMode#STRICT STRICT}, then all available
properties
+     *       are compared including {@linkplain #getName() name}, {@linkplain #getRemarks()
remarks},
+     *       {@linkplain #getIdentifiers() identifiers code}, <i>etc.</i></li>
+     *   <li>If {@code mode} is {@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA},
+     *       then this method compare only the properties needed for computing transformations.
+     *       In other words, {@code sourceCS.equals(targetCS, IGNORE_METADATA)} returns {@code
true}
+     *       if the transformation from {@code sourceCS} to {@code targetCS} is likely to
be the
+     *       identity transform, no matter what {@link #getName()} said.</li>
+     * </ul>
+     *
+     * {@section Exceptions to the above rules}
+     * Some subclasses (especially {@link org.apache.sis.referencing.datum.AbstractDatum}
+     * and {@link org.apache.sis.parameter.AbstractParameterDescriptor}) will test for the
+     * {@linkplain #getName() name}, since objects with different name have completely
+     * different meaning. For example nothing differentiate the {@code "semi_major"} and
+     * {@code "semi_minor"} parameters except the name. The name comparison may be loose
+     * however, i.e. we may accept a name matching an alias.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  mode {@link ComparisonMode#STRICT STRICT} for performing a strict comparison,
or
+     *         {@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} for comparing only
properties
+     *         relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
     @Override
-    public boolean equals(Object other, ComparisonMode mode) {
-        throw new UnsupportedOperationException("Not supported yet.");
+    public boolean equals(final Object object, final ComparisonMode mode) {
+        if (object == null) {
+            return false;
+        }
+        if (getClass() == object.getClass()) {
+            /*
+             * If the classes are the same, then the hash codes should be computed in the
same
+             * way. Since those codes are cached, this is an efficient way to quickly check
if
+             * the two objects are different. Note that using the hash codes for comparisons
+             * that ignore metadata is okay only if the implementation note described in
the
+             * 'computeHashCode()' javadoc hold (metadata not used in hash code computation).
+             */
+            if (mode.ordinal() < ComparisonMode.APPROXIMATIVE.ordinal()) {
+                final int tc = hashCode;
+                if (tc != 0) {
+                    final int oc = ((AbstractIdentifiedObject) object).hashCode;
+                    if (oc != 0 && tc != oc) {
+                        return false;
+                    }
+                }
+            }
+        } else {
+            if (mode == ComparisonMode.STRICT) { // Same classes was required for this mode.
+                return false;
+            }
+            if (!(object instanceof IdentifiedObject)) {
+                return false;
+            }
+        }
+        switch (mode) {
+            case STRICT: {
+                final AbstractIdentifiedObject that = (AbstractIdentifiedObject) object;
+                return Objects.equals(        name,                 that.name)         &&
+                       Objects.equals(nonNull(alias),       nonNull(that.alias))       &&
+                       Objects.equals(nonNull(identifiers), nonNull(that.identifiers)) &&
+                       Objects.equals(        remarks,              that.remarks);
+            }
+            case BY_CONTRACT: {
+                final IdentifiedObject that = (IdentifiedObject) object;
+                return deepEquals(        getName(),                 that.getName(),    
    mode) &&
+                       deepEquals(nonNull(getAlias()),       nonNull(that.getAlias()),  
    mode) &&
+                       deepEquals(nonNull(getIdentifiers()), nonNull(that.getIdentifiers()),
mode) &&
+                       deepEquals(        getRemarks(),              that.getRemarks(), 
    mode);
+            }
+            case IGNORE_METADATA:
+            case APPROXIMATIVE:
+            case DEBUG: {
+                return true;
+            }
+            default: {
+                throw new IllegalArgumentException(Errors.format(Errors.Keys.UnknownEnumValue_1,
mode));
+            }
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java?rev=1519001&r1=1519000&r2=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
[UTF-8] Fri Aug 30 15:54:46 2013
@@ -91,6 +91,22 @@ public final class CollectionsExt extend
     }
 
     /**
+     * Returns the given collection if non-empty, or {@code null} if the given collection
is null or empty.
+     * This method is generally not recommended, since public API should prefer empty collection
instead of
+     * null. However it is occasionally useful for managing private fields, especially for
inter-operability
+     * with frameworks that may expect or return null (e.g. if we want to exclude completely
an empty collection
+     * from marshalling with JAXB).
+     *
+     * @param  <T> The type of the collection.
+     * @param  <E> The type of elements in the collection.
+     * @param  c   The collection, or {@code null}.
+     * @return The given collection, or an empty set of the given collection was null.
+     */
+    public static <T extends Collection<E>, E> T nonEmpty(final T c) {
+        return (c != null && c.isEmpty()) ? null : c;
+    }
+
+    /**
      * Returns the given collection, or {@link Collections#EMPTY_SET} if the given collection
is null.
      *
      * @param  <E> The type of elements in the collection.
@@ -118,21 +134,37 @@ public final class CollectionsExt extend
      * sense of {@link Object#equals(Object)}, then only the last instance of the duplicated
      * values will be included in the returned set.
      *
-     * @param  <E> The type of array elements.
-     * @param  array The array to copy in a set. May be {@code null}.
+     * @param  <E>         The type of array elements.
+     * @param  excludeNull {@code true} for excluding the {@code null} element from the returned
set.
+     * @param  array       The array to copy in a set. May be {@code null} or contain null
elements.
      * @return A set containing the array elements, or {@code null} if the given array was
null.
      *
      * @see Collections#unmodifiableSet(Set)
      */
     @SafeVarargs
-    public static <E> Set<E> immutableSet(final E... array) {
+    @SuppressWarnings("fallthrough")
+    public static <E> Set<E> immutableSet(final boolean excludeNull, final E...
array) {
         if (array == null) {
             return null;
         }
         switch (array.length) {
-            case 0:  return Collections.emptySet();
-            case 1:  return Collections.singleton(array[0]);
-            default: return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(array)));
+            case 1: {
+                final E element = array[0];
+                if (element != null || !excludeNull) {
+                    return Collections.singleton(element);
+                }
+                // Fallthrough for an empty set.
+            }
+            case 0: {
+                return Collections.emptySet();
+            }
+            default: {
+                final Set<E> set = new LinkedHashSet<>(Arrays.asList(array));
+                if (excludeNull) {
+                    set.remove(null);
+                }
+                return unmodifiableOrCopy(set);
+            }
         }
     }
 

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1519001&r1=1519000&r2=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] Fri Aug 30 15:54:46 2013
@@ -546,6 +546,11 @@ public final class Errors extends Indexe
         public static final int UnknownCommand_1 = 102;
 
         /**
+         * Unknown enumeration value: {0}.
+         */
+        public static final int UnknownEnumValue_1 = 115;
+
+        /**
          * Format of “{0}” is not recognized.
          */
         public static final int UnknownFormatFor_1 = 107;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1519001&r1=1519000&r2=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] Fri Aug 30 15:54:46 2013
@@ -121,6 +121,7 @@ UnexpectedEndOfFile_1           = Unexpe
 UnexpectedEndOfString_1         = More characters were expected at the end of \u201c{0}\u201d.
 UnexpectedFileFormat_2          = File \u201c{1}\u201d seems to be encoded in an other format
than {0}.
 UnknownCommand_1                = Command \u201c{0}\u201d is not recognized.
+UnknownEnumValue_1              = Unknown enumeration value: {0}.
 UnknownFormatFor_1              = Format of \u201c{0}\u201d is not recognized.
 UnknownOption_1                 = Option \u201c{0}\u201d is not recognized.
 UnknownType_1                   = Type \u2018{0}\u2019 is unknown in this context.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1519001&r1=1519000&r2=1519001&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] Fri Aug 30 15:54:46 2013
@@ -110,6 +110,7 @@ UnexpectedEndOfFile_1           = Fin de
 UnexpectedEndOfString_1         = D\u2019autres caract\u00e8res \u00e9taient attendus \u00e0
la fin du texte \u201c{0}\u201d.
 UnexpectedFileFormat_2          = Le fichier \u201c{1}\u201d semble \u00eatre encod\u00e9
dans un autre format que {0}.
 UnknownCommand_1                = La commande \u201c{0}\u201d n\u2019est pas reconnue.
+UnknownEnumValue_1              = Valeur d\u2019\u00e9num\u00e9ration inconnue: {0}.
 UnknownFormatFor_1              = Le format de \u201c{0}\u201d n\u2019est pas reconnu.
 UnknownOption_1                 = L\u2019option \u201c{0}\u201d n\u2019est pas reconnue.
 UnknownType_1                   = Le type \u2018{0}\u2019 n\u2019est pas reconnu dans ce
contexte.



Mime
View raw message