sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1467267 - in /sis/branches/JDK7: sis-metadata/src/main/java/org/apache/sis/metadata/ sis-utility/src/main/java/org/apache/sis/internal/jaxb/ sis-utility/src/main/java/org/apache/sis/internal/util/ sis-utility/src/main/java/org/apache/sis/u...
Date Fri, 12 Apr 2013 13:37:57 GMT
Author: desruisseaux
Date: Fri Apr 12 13:37:56 2013
New Revision: 1467267

URL: http://svn.apache.org/r1467267
Log:
Moved UnmodifiableArrayList out of public because this class contains a significant hole in type safety.
The getElementType() method return the value of Class.getComponentType(). But because Java arrays are covariant
(at the contrary of collection), the returned value may be Class<? extends E> while the method return type is
declared as Class<E>. This is safe only if the caller know that he invoked UnmodifiableArrayList.wrap(E[]) with
an array whose component type is exactly E, not a subtype of E. We can try to be careful about that in SIS code,
but we can not rely every users to be aware of this hole. So we are better to keep this class hidden.

Also removed many CollectionsExt method from public API. The fact that their contract is tedious to explain
is an indication that those methods should not be public. Furthermore they may change in any future SIS version.

Added:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
      - copied, changed from r1467105, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptyQueue.java
      - copied, changed from r1467105, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptySortedSet.java
      - copied, changed from r1467105, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/UnmodifiableArrayList.java
      - copied, changed from r1467105, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/UnmodifiableArrayList.java
Removed:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/UnmodifiableArrayList.java
Modified:
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Pruner.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -16,14 +16,17 @@
  */
 package org.apache.sis.metadata;
 
+import java.util.Arrays;
 import java.util.Map;
 import java.util.Set;
 import java.util.Iterator;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import org.apache.sis.util.collection.CollectionsExt;
-import org.apache.sis.util.collection.UnmodifiableArrayList;
+
+import static org.apache.sis.internal.util.CollectionsExt.unmodifiableOrCopy;
 
 
 /**
@@ -101,11 +104,15 @@ final class Cloner extends org.apache.si
                 // Do not use the SIS Checked* classes since we don't
                 // need synchronization or type checking anymore.
                 if (isSet) {
-                    collection = CollectionsExt.immutableSet(array);
+                    switch (array.length) {
+                        case 0:  collection = Collections.emptySet(); break;
+                        case 1:  collection = Collections.singleton(array[0]); break;
+                        default: collection = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(array))); break;
+                    }
                 } else {
                     // Conservatively assumes a List if we are not sure to have a Set,
                     // since the list is less destructive (no removal of duplicated).
-                    collection = UnmodifiableArrayList.wrap(array);
+                    collection = CollectionsExt.unmodifiableList(array);
                 }
             }
             return collection;
@@ -120,7 +127,7 @@ final class Cloner extends org.apache.si
                 final Map.Entry<Object,Object> entry = it.next();
                 entry.setValue(clone(entry.getValue()));
             }
-            return CollectionsExt.unmodifiableOrCopy(map);
+            return unmodifiableOrCopy(map);
         }
         /*
          * CASE 4 - The object is presumed cloneable.

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -46,10 +46,10 @@ import org.apache.sis.util.collection.Ba
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.xml.IdentifiedObject;
 
-import static org.apache.sis.util.collection.CollectionsExt.modifiableCopy;
-import static org.apache.sis.util.collection.CollectionsExt.hashMapCapacity;
-import static org.apache.sis.internal.util.Utilities.floatEpsilonEqual;
 import static org.apache.sis.metadata.PropertyComparator.*;
+import static org.apache.sis.internal.util.Utilities.floatEpsilonEqual;
+import static org.apache.sis.internal.util.CollectionsExt.modifiableCopy;
+import static org.apache.sis.util.collection.CollectionsExt.hashMapCapacity;
 
 
 /**

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Pruner.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Pruner.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Pruner.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/Pruner.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -21,7 +21,7 @@ import java.util.Iterator;
 import java.util.Collection;
 import java.util.IdentityHashMap;
 import org.opengis.util.CodeList;
-import org.apache.sis.util.collection.CollectionsExt;
+import org.apache.sis.internal.util.CollectionsExt;
 
 
 /**

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -27,7 +27,7 @@ import java.lang.reflect.Field;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.apache.sis.internal.simple.SimpleCitation;
-import org.apache.sis.util.collection.UnmodifiableArrayList;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.xml.IdentifierSpace;

Copied: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java (from r1467105, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java?p2=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java&r1=1467105&r2=1467267&rev=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -14,13 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.util.collection;
+package org.apache.sis.internal.util;
 
 import java.util.*;
-import java.io.Serializable;
 import org.apache.sis.util.Static;
-import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.ObjectConverter;
 
 
 /**
@@ -29,11 +26,8 @@ import org.apache.sis.util.ObjectConvert
  * Some worthy methods are:
  *
  * <ul>
- *   <li>Null-safe {@link #isNullOrEmpty(Collection) isNullOrEmpty} method,
- *       for the convenience of classes using the <cite>lazy instantiation</cite> pattern.</li>
  *   <li>{@link #toCollection(Object) toCollection} for wrapping or copying arbitrary objects to
  *       list or collection.</li>
- *   <li>List and sorted set {@linkplain #listComparator() comparators}.</li>
  *   <li>{@link #modifiableCopy(Collection) modifiableCopy} method for taking a snapshot of an arbitrary
  *       implementation into an unsynchronized, modifiable, in-memory object.</li>
  *   <li>{@link #unmodifiableOrCopy(Set) unmodifiableOrCopy} methods, which may be slightly more
@@ -41,6 +35,10 @@ import org.apache.sis.util.ObjectConvert
  *       when the unmodifiable collection is not required to be a view over the original collection.</li>
  * </ul>
  *
+ * This class is not in public API because some functionality provided there are not really the
+ * purpose of a geospatial library and may change at any time. Some method contracts are a little
+ * bit tedious to explain, which is an other indication that they should not be in public API.
+ *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3 (derived from geotk-3.00)
  * @version 0.3
@@ -54,39 +52,6 @@ public final class CollectionsExt extend
     }
 
     /**
-     * Returns {@code true} if the given collection is either null or
-     * {@linkplain Collection#isEmpty() empty}. If this method returns {@code false},
-     * then the given collection is guaranteed to be non-null and to contain at least
-     * one element.
-     *
-     * <p>This is a convenience method for classes implementing the <cite>lazy instantiation</cite>
-     * pattern. In such cases, null collections (i.e. collections not yet instantiated) are typically
-     * considered as {@linkplain Collection#isEmpty() empty}.</p>
-     *
-     * @param collection The collection to test, or {@code null}.
-     * @return {@code true} if the given collection is null or empty, or {@code false} otherwise.
-     */
-    public static boolean isNullOrEmpty(final Collection<?> collection) {
-        return (collection == null) || collection.isEmpty();
-    }
-
-    /**
-     * Returns {@code true} if the given map is either null or {@linkplain Map#isEmpty() empty}.
-     * If this method returns {@code false}, then the given map is guaranteed to be non-null and
-     * to contain at least one element.
-     *
-     * <p>This is a convenience method for classes implementing the <cite>lazy instantiation</cite>
-     * pattern. In such cases, null maps (i.e. maps not yet instantiated) are typically considered
-     * as {@linkplain Map#isEmpty() empty}.</p>
-     *
-     * @param map The map to test, or {@code null}.
-     * @return {@code true} if the given map is null or empty, or {@code false} otherwise.
-     */
-    public static boolean isNullOrEmpty(final Map<?,?> map) {
-        return (map == null) || map.isEmpty();
-    }
-
-    /**
      * Returns a {@linkplain Queue queue} which is always empty and accepts no element.
      *
      * @param <E> The type of elements in the empty collection.
@@ -118,125 +83,6 @@ public final class CollectionsExt extend
     }
 
     /**
-     * Returns a set whose elements are derived <cite>on-the-fly</cite> from the given set.
-     * Conversions from the original elements to the derived elements are performed when needed
-     * by invoking the {@link ObjectConverter#convert(Object)} method on the given converter.
-     * Those conversions are repeated every time a {@code Set} method is invoked; there is no cache.
-     * Consequently, any change in the original set is immediately visible in the derived set,
-     * and conversely.
-     *
-     * <p>The {@link Set#add(Object) Set.add(E)} method is supported only if the given converter
-     * is {@linkplain org.apache.sis.math.FunctionProperty#INVERTIBLE invertible}.
-     * An invertible converter is not mandatory for other {@code Set} operations.
-     * However {@link Set#contains(Object) contains} and {@link Set#remove(Object) remove}
-     * operations are likely to be faster if the inverse converter is available.</p>
-     *
-     * <p>The derived set may contain fewer elements than the original set if some elements
-     * are not convertible. Non-convertible elements are <var>S</var> values for which
-     * {@code converter.convert(S)} returns {@code null}. As a consequence of this sentinel
-     * value usage, the derived set can not contain {@code null} elements.</p>
-     *
-     * <p>The returned set can be serialized if the given set and converter are serializable.
-     * The returned set is not synchronized by itself, but is nevertheless thread-safe if the
-     * given set (including its iterator) and converter are thread-safe.</p>
-     *
-     * @param  <S>       The type of elements in the storage (original) set.
-     * @param  <E>       The type of elements in the derived set.
-     * @param  storage   The storage set containing the original elements, or {@code null}.
-     * @param  converter The converter from the elements in the storage set to the elements
-     *                   in the derived set.
-     * @return A view over the {@code storage} set containing all elements converted by the given
-     *         converter, or {@code null} if {@code storage} was null.
-     *
-     * @see org.apache.sis.util.ObjectConverters#derivedSet(Set, ObjectConverter)
-     *
-     * @category converter
-     */
-    public static <S,E> Set<E> derivedSet(final Set<S> storage, final ObjectConverter<S,E> converter) {
-        ArgumentChecks.ensureNonNull("converter", converter);
-        if (storage == null) {
-            return null;
-        }
-        return DerivedSet.create(storage, converter);
-    }
-
-    /**
-     * Returns a map whose whose keys and values are derived <cite>on-the-fly</cite> from the given map.
-     * Conversions from the original entries to the derived entries are performed when needed
-     * by invoking the {@link ObjectConverter#convert(Object)} method on the given converters.
-     * Those conversions are repeated every time a {@code Map} method is invoked; there is no cache.
-     * Consequently, any change in the original map is immediately visible in the derived map,
-     * and conversely.
-     *
-     * <p>The {@link Map#put(Object,Object) Map.put(K,V)} method is supported only if the given
-     * converters are {@linkplain org.apache.sis.math.FunctionProperty#INVERTIBLE invertible}.
-     * An invertible converter is not mandatory for other {@code Map} operations.
-     * However some of them are likely to be faster if the inverse converters are available.</p>
-     *
-     * <p>The derived map may contain fewer entries than the original map if some keys
-     * are not convertible. Non-convertible keys are <var>K</var> values for which
-     * {@code keyConverter.convert(K)} returns {@code null}. As a consequence of this sentinel
-     * value usage, the derived map can not contain {@code null} keys.
-     * It may contain {@code null} values however.</p>
-     *
-     * <p>The returned map can be serialized if the given map and converters are serializable.
-     * The returned map is <strong>not</strong> thread-safe.</p>
-     *
-     * @param <SK>         The type of keys   in the storage map.
-     * @param <SV>         The type of values in the storage map.
-     * @param <K>          The type of keys   in the derived map.
-     * @param <V>          The type of values in the derived map.
-     * @param storage      The storage map containing the original entries, or {@code null}.
-     * @param keyConverter The converter from the keys in the storage map to the keys in the derived map.
-     * @param valueConverter The converter from the values in the storage map to the values in the derived map.
-     * @return A view over the {@code storage} map containing all entries converted by the given
-     *         converters, or {@code null} if {@code storage} was null.
-     *
-     * @see org.apache.sis.util.ObjectConverters#derivedMap(Map, ObjectConverter, ObjectConverter)
-     * @see org.apache.sis.util.ObjectConverters#derivedKeys(Map, ObjectConverter, Class)
-     * @see org.apache.sis.util.ObjectConverters#derivedValues(Map, Class, ObjectConverter)
-     *
-     * @category converter
-     */
-    public static <SK,SV,K,V> Map<K,V> derivedMap(final Map<SK,SV> storage,
-                                                  final ObjectConverter<SK,K> keyConverter,
-                                                  final ObjectConverter<SV,V> valueConverter)
-    {
-        ArgumentChecks.ensureNonNull("keyConverter",   keyConverter);
-        ArgumentChecks.ensureNonNull("valueConverter", valueConverter);
-        if (storage == null) {
-            return null;
-        }
-        return DerivedMap.create(storage, keyConverter, valueConverter);
-    }
-
-    /**
-     * Returns the specified array as an immutable set, or {@code null} if the array is null.
-     * If the given array contains duplicated elements, i.e. elements that are equal in the
-     * 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}.
-     * @return A set containing the array elements, or {@code null} if the given array was null.
-     *
-     * @see Collections#unmodifiableSet(Set)
-     *
-     * @category converter
-     */
-    @SafeVarargs
-    public static <E> Set<E> immutableSet(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)));
-        }
-    }
-
-    /**
      * Returns a unmodifiable version of the given set.
      * This method is different than the standard {@link Collections#unmodifiableSet(Set)}
      * in that it tries to returns a more efficient object when there is zero or one element.
@@ -251,8 +97,6 @@ public final class CollectionsExt extend
      * @param  <E>  The type of elements in the set.
      * @param  set  The set to make unmodifiable, or {@code null}.
      * @return A unmodifiable version of the given set, or {@code null} if the given set was null.
-     *
-     * @category converter
      */
     public static <E> Set<E> unmodifiableOrCopy(Set<E> set) {
         if (set != null) {
@@ -289,8 +133,6 @@ public final class CollectionsExt extend
      * @param  <V>  The type of values in the map.
      * @param  map  The map to make unmodifiable, or {@code null}.
      * @return A unmodifiable version of the given map, or {@code null} if the given map was null.
-     *
-     * @category converter
      */
     public static <K,V> Map<K,V> unmodifiableOrCopy(Map<K,V> map) {
         if (map != null) {
@@ -331,8 +173,6 @@ public final class CollectionsExt extend
      * @param  <E> The type of elements in the collection.
      * @param  collection The collection to copy, or {@code null}.
      * @return A copy of the given collection, or {@code null} if the given collection was null.
-     *
-     * @category converter
      */
     @SuppressWarnings("unchecked")
     public static <E> Collection<E> modifiableCopy(final Collection<E> collection) {
@@ -384,8 +224,6 @@ public final class CollectionsExt extend
      * @param  <V> The type of values in the map.
      * @param  map The map to copy, or {@code null}.
      * @return A copy of the given map, or {@code null} if the given map was null.
-     *
-     * @category converter
      */
     @SuppressWarnings("unchecked")
     public static <K,V> Map<K,V> modifiableCopy(final Map<K,V> map) {
@@ -432,8 +270,6 @@ public final class CollectionsExt extend
      *
      * @param  value The value to return as a collection, or {@code null}.
      * @return The value as a collection, or wrapped in a collection (never {@code null}).
-     *
-     * @category converter
      */
     public static Collection<?> toCollection(final Object value) {
         if (value == null) {
@@ -485,8 +321,6 @@ public final class CollectionsExt extend
      * @param  <T> The type of elements in the given collection.
      * @param  collection The collection to cast or copy to a list.
      * @return The given collection as a list, or a copy of the given collection.
-     *
-     * @category converter
      */
     public static <T> List<T> toList(final Collection<T> collection) {
         if (collection instanceof List<?>) {
@@ -494,169 +328,4 @@ public final class CollectionsExt extend
         }
         return new ArrayList<>(collection);
     }
-
-    /**
-     * The comparator to be returned by {@link Collections#listComparator()} and similar methods.
-     */
-    private static final class Compare<T extends Comparable<T>>
-            implements Comparator<Collection<T>>, Serializable
-    {
-        /**
-         * For cross-version compatibility.
-         */
-        private static final long serialVersionUID = 7050753365408754641L;
-
-        /**
-         * The unique instance. Can not be public because of parameterized types: we need a method
-         * for casting to the expected type. This is the same trick than the one used by the JDK
-         * in the {@link Collections#emptySet()} method for instance.
-         */
-        @SuppressWarnings("rawtypes")
-        static final Comparator INSTANCE = new Compare();
-
-        /**
-         * Do not allow instantiation other than the unique {@link #INSTANCE}.
-         */
-        private Compare() {
-        }
-
-        /**
-         * Compares two collections of comparable objects.
-         */
-        @Override
-        public int compare(final Collection<T> c1, final Collection<T> c2) {
-            final Iterator<T> i1 = c1.iterator();
-            final Iterator<T> i2 = c2.iterator();
-            int c;
-            do {
-                final boolean h1 = i1.hasNext();
-                final boolean h2 = i2.hasNext();
-                if (!h1) return h2 ? -1 : 0;
-                if (!h2) return +1;
-                final T e1 = i1.next();
-                final T e2 = i2.next();
-                c = e1.compareTo(e2);
-            } while (c == 0);
-            return c;
-        }
-    };
-
-    /**
-     * Returns a comparator for lists of comparable elements. The first element of each list are
-     * {@linkplain Comparable#compareTo(Object) compared}. If one is <cite>greater than</cite> or
-     * <cite>less than</cite> the other, the result of that comparison is returned. Otherwise
-     * the second element are compared, and so on until either non-equal elements are found,
-     * or end-of-list are reached. In the later case, the shortest list is considered
-     * <cite>less than</cite> the longest one.
-     *
-     * <p>If both lists have the same length and equal elements in the sense of
-     * {@link Comparable#compareTo}, then the comparator returns 0.</p>
-     *
-     * @param  <T> The type of elements in both lists.
-     * @return The ordering between two lists.
-     *
-     * @category comparator
-     */
-    @SuppressWarnings("unchecked")
-    public static <T extends Comparable<T>> Comparator<List<T>> listComparator() {
-        return Compare.INSTANCE;
-    }
-
-    /**
-     * Returns a comparator for sorted sets of comparable elements. The first element of each set
-     * are {@linkplain Comparable#compareTo(Object) compared}. If one is <cite>greater than</cite>
-     * or <cite>less than</cite> the other, the result of that comparison is returned. Otherwise
-     * the second element are compared, and so on until either non-equal elements are found,
-     * or end-of-set are reached. In the later case, the smallest set is considered
-     * <cite>less than</cite> the largest one.
-     *
-     * {@note There is no method accepting an arbitrary <code>Set</code> or <code>Collection</code>
-     *        argument because this comparator makes sense only for collections having determinist
-     *        iteration order.}
-     *
-     * @param <T> The type of elements in both sets.
-     * @return The ordering between two sets.
-     *
-     * @category comparator
-     */
-    @SuppressWarnings("unchecked")
-    public static <T extends Comparable<T>> Comparator<SortedSet<T>> sortedSetComparator() {
-        return Compare.INSTANCE;
-    }
-
-    /**
-     * The comparator to be returned by {@link Collections#valueComparator()}.
-     */
-    private static final class ValueComparator<K,V extends Comparable<V>>
-            implements Comparator<Map.Entry<K,V>>, Serializable
-    {
-        /**
-         * For cross-version compatibility.
-         */
-        private static final long serialVersionUID = 807166038568740444L;
-
-        /**
-         * The unique instance. Can not be public because of parameterized types: we need a method
-         * for casting to the expected type. This is the same trick than the one used by the JDK
-         * in the {@link Collections#emptySet()} method for instance.
-         */
-        @SuppressWarnings("rawtypes")
-        static final ValueComparator INSTANCE = new ValueComparator();
-
-        /**
-         * Do not allow instantiation other than the unique {@link #INSTANCE}.
-         */
-        private ValueComparator() {
-        }
-
-        /**
-         * Compares the values of two entries.
-         */
-        @Override
-        public int compare(final Map.Entry<K,V> e1, final Map.Entry<K,V> e2) {
-            return e1.getValue().compareTo(e2.getValue());
-        }
-    }
-
-    /**
-     * Returns a comparator for map entries having comparable {@linkplain java.util.Map.Entry#getValue() values}.
-     * For any pair of entries {@code e1} and {@code e2}, this method performs the comparison as below:
-     *
-     * {@preformat java
-     *     return e1.getValue().compareTo(e2.getValue());
-     * }
-     *
-     * This comparator can be used as a complement to {@link SortedSet}. While {@code SortedSet}
-     * maintains keys ordering at all time, {@code valueComparator()} is typically used only at
-     * the end of a process in which the values are the numerical calculation results.
-     *
-     * @param <K> The type of keys in the map entries.
-     * @param <V> The type of values in the map entries.
-     * @return A comparator for the values of the given type.
-     *
-     * @category comparator
-     */
-    @SuppressWarnings("unchecked")
-    public static <K,V extends Comparable<V>> Comparator<Map.Entry<K,V>> valueComparator() {
-        return ValueComparator.INSTANCE;
-    }
-
-    /**
-     * Returns the capacity to be given to the {@link HashMap#HashMap(int) HashMap}
-     * constructor for holding the given number of elements. This method computes the capacity
-     * for the default <cite>load factor</cite>, which is 0.75.
-     *
-     * <p>The same calculation can be used for {@link LinkedHashMap} and
-     * {@link HashSet} as well, which are built on top of {@code HashMap}.</p>
-     *
-     * @param count The number of elements to be put into the hash map or hash set.
-     * @return The minimal initial capacity to be given to the hash map constructor.
-     */
-    public static int hashMapCapacity(final int count) {
-        int r = count >>> 2;
-        if ((count & 0x3) != 0) {
-            r++;
-        }
-        return count + r;
-    }
 }

Copied: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptyQueue.java (from r1467105, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptyQueue.java?p2=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptyQueue.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java&r1=1467105&r2=1467267&rev=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptyQueue.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.util.collection;
+package org.apache.sis.internal.util;
 
 import java.io.Serializable;
 import java.util.AbstractQueue;

Copied: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptySortedSet.java (from r1467105, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptySortedSet.java?p2=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptySortedSet.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java&r1=1467105&r2=1467267&rev=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/EmptySortedSet.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.util.collection;
+package org.apache.sis.internal.util;
 
 import java.io.Serializable;
 import java.util.AbstractSet;

Copied: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/UnmodifiableArrayList.java (from r1467105, sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/UnmodifiableArrayList.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/UnmodifiableArrayList.java?p2=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/UnmodifiableArrayList.java&p1=sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/UnmodifiableArrayList.java&r1=1467105&r2=1467267&rev=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/UnmodifiableArrayList.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/UnmodifiableArrayList.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -14,11 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.util.collection;
+package org.apache.sis.internal.util;
 
 import java.io.Serializable;
 import java.util.AbstractList;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.collection.CheckedContainer;
 
 // Related to JDK7
 import java.util.Objects;
@@ -37,8 +38,20 @@ import java.util.Objects;
  *     List<?> list = Collections.unmodifiableList(Arrays.asList(array));
  * }
  *
- * except that this class uses one less level of indirection. Despite that advantage being minor,
- * this class is defined because extensively used in the SIS library.
+ * except that this class uses one less level of indirection (which may be significant since
+ * unmodifiable lists are extensively used in SIS) and implements the {@link CheckedContainer}
+ * interface.
+ *
+ * {@section WARNING! Type safety hole}
+ * The {@link #getElementType()} return type is {@code Class<E>}, but its implementation actually
+ * returns {@code Class<? extends E>}. This contract violation is possible because Java arrays are
+ * covariant (at the contrary of collections). In order to avoid such contract violation, callers
+ * <strong>must</strong> ensure that the type of array elements in exactly {@code E}, not a subtype
+ * of {@code E}. This class has no way to verify that condition. This class is not in the public API
+ * for this reason.
+ *
+ * <p>Note that the public API, {@link org.apache.sis.util.collection.CollectionsExt#unmodifiableList(E[])},
+ * returns {@code List<? extends E>}, which is okay.</p>
  *
  * @param <E> The type of elements in the list.
  *
@@ -66,12 +79,15 @@ public class UnmodifiableArrayList<E> ex
      * <p>This constructor is for sub-classing only. Users should invoke the {@link #wrap(Object[])}
      * static method instead.</p>
      *
+     * {@section WARNING! Type safety hole}
+     * Callers <strong>must</strong> ensure that the type of array elements in exactly {@code E},
+     * not a subtype of {@code E}. See class javadoc for more information.
+     *
      * @param array The array to wrap.
      */
     @SafeVarargs
     protected UnmodifiableArrayList(final E... array) {
-        ArgumentChecks.ensureNonNull("array", array);
-        this.array = array;
+        this.array = Objects.requireNonNull(array);
     }
 
     /**
@@ -79,6 +95,12 @@ public class UnmodifiableArrayList<E> ex
      * retained (i.e. the array is <strong>not</strong> cloned). Consequently the given array
      * shall not be modified after construction if the returned list is intended to be immutable.
      *
+     * {@section WARNING! Type safety hole}
+     * Callers <strong>must</strong> ensure that the type of array elements in exactly {@code E},
+     * not a subtype of {@code E}. If the caller is okay with {@code List<? extends E>}, then (s)he
+     * should use {@link org.apache.sis.util.collection.CollectionsExt#unmodifiableList(E[])} instead.
+     * See class javadoc for more information.
+     *
      * @param  <E> The type of elements in the list.
      * @param  array The array to wrap, or {@code null} if none.
      * @return The given array wrapped in an unmodifiable list, or {@code null} if the given
@@ -95,6 +117,12 @@ public class UnmodifiableArrayList<E> ex
      * specified sub-region of the given array shall not be modified after construction if the
      * returned list is intended to be immutable.
      *
+     * {@section WARNING! Type safety hole}
+     * Callers <strong>must</strong> ensure that the type of array elements in exactly {@code E},
+     * not a subtype of {@code E}. If the caller is okay with {@code List<? extends E>}, then (s)he
+     * should use {@link org.apache.sis.util.collection.CollectionsExt#unmodifiableList(E[])} instead.
+     * See class javadoc for more information.
+     *
      * @param  <E>   The type of elements in the list.
      * @param  array The array to wrap.
      * @param  lower Low endpoint (inclusive) of the sublist.
@@ -120,8 +148,8 @@ public class UnmodifiableArrayList<E> ex
      * @return The type of elements in the list.
      */
     @Override
-    @SuppressWarnings("unchecked") // Safe if this instance was created safely with wrap(E[]).
     public Class<E> getElementType() {
+        // No @SuppressWarnings because this cast is really unsafe. See class javadoc.
         return (Class<E>) array.getClass().getComponentType();
     }
 
@@ -288,6 +316,10 @@ public class UnmodifiableArrayList<E> ex
 
         /**
          * Creates a new sublist.
+         *
+         * {@section WARNING! Type safety hole}
+         * Callers <strong>must</strong> ensure that the type of array elements in exactly {@code E},
+         * not a subtype of {@code E}. See {@link UnmodifiableArrayList} class javadoc for more information.
          */
         SubList(final E[] array, final int lower, final int size) {
             super(array);

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Numbers.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -27,7 +27,7 @@ import java.lang.reflect.Array;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.collection.CollectionsExt;
+import org.apache.sis.internal.util.CollectionsExt;
 
 import static java.lang.Double.doubleToLongBits;
 

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CollectionsExt.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -16,30 +16,19 @@
  */
 package org.apache.sis.util.collection;
 
-import java.util.*;
-import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.Collection;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
 
 
 /**
  * Static methods working on {@link Collection} objects.
  * This is an extension to the standard {@link Collections} utility class.
- * Some worthy methods are:
- *
- * <ul>
- *   <li>Null-safe {@link #isNullOrEmpty(Collection) isNullOrEmpty} method,
- *       for the convenience of classes using the <cite>lazy instantiation</cite> pattern.</li>
- *   <li>{@link #toCollection(Object) toCollection} for wrapping or copying arbitrary objects to
- *       list or collection.</li>
- *   <li>List and sorted set {@linkplain #listComparator() comparators}.</li>
- *   <li>{@link #modifiableCopy(Collection) modifiableCopy} method for taking a snapshot of an arbitrary
- *       implementation into an unsynchronized, modifiable, in-memory object.</li>
- *   <li>{@link #unmodifiableOrCopy(Set) unmodifiableOrCopy} methods, which may be slightly more
- *       compact than the standard {@link Collections#unmodifiableSet(Set)} equivalent
- *       when the unmodifiable collection is not required to be a view over the original collection.</li>
- * </ul>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3 (derived from geotk-3.00)
@@ -87,34 +76,45 @@ public final class CollectionsExt extend
     }
 
     /**
-     * Returns a {@linkplain Queue queue} which is always empty and accepts no element.
-     *
-     * @param <E> The type of elements in the empty collection.
-     * @return An empty collection.
-     *
-     * @see Collections#emptyList()
-     * @see Collections#emptySet()
+     * Returns an unmodifiable view of the given array. A direct reference to the given array is
+     * retained (i.e. the array is <strong>not</strong> cloned). Consequently the given array
+     * shall not be modified after construction if the returned list is intended to be immutable.
+     *
+     * <p>The returned list implements the {@link CheckedContainer} interface. The value returned by
+     * its {@link CheckedContainer#getElementType()} method is inferred from the array component type.
+     * Because arrays in the Java language are covariant (at the contrary of collections),
+     * the list type have to be {@code <? extends E>} instead than {@code <E>}.</p>
+     *
+     * @param  <E> The base type of elements in the list.
+     * @param  array The array to wrap, or {@code null} if none.
+     * @return The given array wrapped in an unmodifiable list, or {@code null} if the given
+     *         array was null.
      */
-    @SuppressWarnings({"unchecked","rawtype"})
-    public static <E> Queue<E> emptyQueue() {
-        return EmptyQueue.INSTANCE;
+    @SafeVarargs
+    public static <E> List<? extends E> unmodifiableList(final E... array) {
+        return UnmodifiableArrayList.wrap(array);
     }
 
     /**
-     * Returns a {@linkplain SortedSet sorted set} which is always empty and accepts no element.
-     *
-     * {@note This method exists only on the JDK6 and JDK7 branches. This method will
-     *        be removed from the JDK8 branch, since it has been added to the JDK.}
-     *
-     * @param <E> The type of elements in the empty collection.
-     * @return An empty collection.
-     *
-     * @see Collections#emptyList()
-     * @see Collections#emptySet()
+     * Returns an unmodifiable view of a subregion of the given array. A direct reference to the
+     * given array is retained (i.e. the array is <strong>not</strong> cloned). Consequently the
+     * specified sub-region of the given array shall not be modified after construction if the
+     * returned list is intended to be immutable.
+     *
+     * <p>The returned list implements the {@link CheckedContainer} interface. The value returned by
+     * its {@link CheckedContainer#getElementType()} method is inferred from the array component type.
+     * Because arrays in the Java language are covariant (at the contrary of collections),
+     * the list type have to be {@code <? extends E>} instead than {@code <E>}.</p>
+     *
+     * @param  <E>   The type of elements in the list.
+     * @param  array The array to wrap (can not be null).
+     * @param  lower Low endpoint (inclusive) of the sublist.
+     * @param  upper High endpoint (exclusive) of the sublist.
+     * @return The given array wrapped in an unmodifiable list.
+     * @throws IndexOutOfBoundsException If the lower or upper value are out of bounds.
      */
-    @SuppressWarnings({"unchecked","rawtype"})
-    public static <E> SortedSet<E> emptySortedSet() {
-        return EmptySortedSet.INSTANCE;
+    public static <E> List<? extends E> unmodifiableList(final E[] array, final int lower, final int upper) {
+        return UnmodifiableArrayList.wrap(array, lower, upper);
     }
 
     /**
@@ -149,8 +149,6 @@ public final class CollectionsExt extend
      *         converter, or {@code null} if {@code storage} was null.
      *
      * @see org.apache.sis.util.ObjectConverters#derivedSet(Set, ObjectConverter)
-     *
-     * @category converter
      */
     public static <S,E> Set<E> derivedSet(final Set<S> storage, final ObjectConverter<S,E> converter) {
         ArgumentChecks.ensureNonNull("converter", converter);
@@ -195,8 +193,6 @@ public final class CollectionsExt extend
      * @see org.apache.sis.util.ObjectConverters#derivedMap(Map, ObjectConverter, ObjectConverter)
      * @see org.apache.sis.util.ObjectConverters#derivedKeys(Map, ObjectConverter, Class)
      * @see org.apache.sis.util.ObjectConverters#derivedValues(Map, Class, ObjectConverter)
-     *
-     * @category converter
      */
     public static <SK,SV,K,V> Map<K,V> derivedMap(final Map<SK,SV> storage,
                                                   final ObjectConverter<SK,K> keyConverter,
@@ -211,437 +207,6 @@ public final class CollectionsExt extend
     }
 
     /**
-     * Returns the specified array as an immutable set, or {@code null} if the array is null.
-     * If the given array contains duplicated elements, i.e. elements that are equal in the
-     * 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}.
-     * @return A set containing the array elements, or {@code null} if the given array was null.
-     *
-     * @see Collections#unmodifiableSet(Set)
-     *
-     * @category converter
-     */
-    @SafeVarargs
-    public static <E> Set<E> immutableSet(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)));
-        }
-    }
-
-    /**
-     * Returns a unmodifiable version of the given set.
-     * This method is different than the standard {@link Collections#unmodifiableSet(Set)}
-     * in that it tries to returns a more efficient object when there is zero or one element.
-     * Such small set occurs frequently in Apache SIS, especially for
-     * {@link org.apache.sis.referencing.AbstractIdentifiedObject} names or identifiers.
-     *
-     * <p><em>The set returned by this method may or may not be a view of the given set</em>.
-     * Consequently this method shall be used <strong>only</strong> if the given set will
-     * <strong>not</strong> be modified after this method call. In case of doubt, use the
-     * standard {@link Collections#unmodifiableSet(Set)} method instead.</p>
-     *
-     * @param  <E>  The type of elements in the set.
-     * @param  set  The set to make unmodifiable, or {@code null}.
-     * @return A unmodifiable version of the given set, or {@code null} if the given set was null.
-     *
-     * @category converter
-     */
-    public static <E> Set<E> unmodifiableOrCopy(Set<E> set) {
-        if (set != null) {
-            switch (set.size()) {
-                case 0: {
-                    set = Collections.emptySet();
-                    break;
-                }
-                case 1: {
-                    set = Collections.singleton(set.iterator().next());
-                    break;
-                }
-                default: {
-                    set = Collections.unmodifiableSet(set);
-                    break;
-                }
-            }
-        }
-        return set;
-    }
-
-    /**
-     * Returns a unmodifiable version of the given map.
-     * This method is different than the standard {@link Collections#unmodifiableMap(Map)}
-     * in that it tries to returns a more efficient object when there is zero or one entry.
-     * Such small maps occur frequently in Apache SIS.
-     *
-     * <p><em>The map returned by this method may or may not be a view of the given map</em>.
-     * Consequently this method shall be used <strong>only</strong> if the given map will
-     * <strong>not</strong> be modified after this method call. In case of doubt, use the
-     * standard {@link Collections#unmodifiableMap(Map)} method instead.</p>
-     *
-     * @param  <K>  The type of keys in the map.
-     * @param  <V>  The type of values in the map.
-     * @param  map  The map to make unmodifiable, or {@code null}.
-     * @return A unmodifiable version of the given map, or {@code null} if the given map was null.
-     *
-     * @category converter
-     */
-    public static <K,V> Map<K,V> unmodifiableOrCopy(Map<K,V> map) {
-        if (map != null) {
-            switch (map.size()) {
-                case 0: {
-                    map = Collections.emptyMap();
-                    break;
-                }
-                case 1: {
-                    final Map.Entry<K,V> entry = map.entrySet().iterator().next();
-                    map = Collections.singletonMap(entry.getKey(), entry.getValue());
-                    break;
-                }
-                default: {
-                    map = Collections.unmodifiableMap(map);
-                    break;
-                }
-            }
-        }
-        return map;
-    }
-
-    /**
-     * Copies the content of the given collection to a new, unsynchronized, modifiable, in-memory
-     * collection. The implementation class of the returned collection may be different than the
-     * class of the collection given in argument. The following table gives the types mapping
-     * applied by this method:
-     *
-     * <table class="sis">
-     * <tr><th>Input type</th>                              <th class="sep">Output type</th></tr>
-     * <tr><td>{@link SortedSet}</td>                       <td class="sep">{@link TreeSet}</td></tr>
-     * <tr><td>{@link HashSet}</td>                         <td class="sep">{@link HashSet}</td></tr>
-     * <tr><td>{@link Set} other than above</td>            <td class="sep">{@link LinkedHashSet}</td></tr>
-     * <tr><td>{@link Queue}</td>                           <td class="sep">{@link LinkedList}</td></tr>
-     * <tr><td>{@link List} or other {@link Collection}</td><td class="sep">{@link ArrayList}</td></tr>
-     * </table>
-     *
-     * @param  <E> The type of elements in the collection.
-     * @param  collection The collection to copy, or {@code null}.
-     * @return A copy of the given collection, or {@code null} if the given collection was null.
-     *
-     * @category converter
-     */
-    @SuppressWarnings("unchecked")
-    public static <E> Collection<E> modifiableCopy(final Collection<E> collection) {
-        if (collection == null) {
-            return null;
-        }
-        /*
-         * We will use the clone() method when possible because they are
-         * implemented in a more efficient way than the copy constructors.
-         */
-        final Class<?> type = collection.getClass();
-        if (collection instanceof Set<?>) {
-            if (collection instanceof SortedSet<?>) {
-                if (type == TreeSet.class) {
-                    return (Collection<E>) ((TreeSet<E>) collection).clone();
-                }
-                return new TreeSet<>(collection);
-            }
-            if (type == HashSet.class || type == LinkedHashSet.class) {
-                return (Collection<E>) ((HashSet<E>) collection).clone();
-            }
-            return new LinkedHashSet<>(collection);
-        }
-        if (collection instanceof Queue<?>) {
-            if (type == LinkedList.class) {
-                return (Collection<E>) ((LinkedList<E>) collection).clone();
-            }
-            return new LinkedList<>(collection);
-        }
-        if (type == ArrayList.class) {
-            return (Collection<E>) ((ArrayList<E>) collection).clone();
-        }
-        return new ArrayList<>(collection);
-    }
-
-    /**
-     * Copies the content of the given map to a new unsynchronized, modifiable, in-memory map.
-     * The implementation class of the returned map may be different than the class of the map
-     * given in argument. The following table gives the types mapping applied by this method:
-     *
-     * <table class="sis">
-     * <tr><th>Input type</th>                  <th class="sep">Output type</th></tr>
-     * <tr><td>{@link SortedMap}</td>           <td class="sep">{@link TreeMap}</td></tr>
-     * <tr><td>{@link HashMap}</td>             <td class="sep">{@link HashMap}</td></tr>
-     * <tr><td>{@link Map} other than above</td><td class="sep">{@link LinkedHashMap}</td></tr>
-     * </table>
-     *
-     * @param  <K> The type of keys in the map.
-     * @param  <V> The type of values in the map.
-     * @param  map The map to copy, or {@code null}.
-     * @return A copy of the given map, or {@code null} if the given map was null.
-     *
-     * @category converter
-     */
-    @SuppressWarnings("unchecked")
-    public static <K,V> Map<K,V> modifiableCopy(final Map<K,V> map) {
-        if (map == null) {
-            return null;
-        }
-        /*
-         * We will use the clone() method when possible because they are
-         * implemented in a more efficient way than the copy constructors.
-         */
-        final Class<?> type = map.getClass();
-        if (map instanceof SortedMap<?,?>) {
-            if (type == TreeMap.class) {
-                return (Map<K,V>) ((TreeMap<K,V>) map).clone();
-            }
-            return new TreeMap<>(map);
-        }
-        if (type == HashMap.class || type == LinkedHashMap.class) {
-            return (Map<K,V>) ((HashMap<K,V>) map).clone();
-        }
-        return new LinkedHashMap<>(map);
-    }
-
-    /**
-     * Returns the given value as a collection. Special cases:
-     *
-     * <ul>
-     *   <li>If the value is null, then this method returns an {@linkplain Collections#emptyList() empty list}.</li>
-     *   <li>If the value is an instance of {@link Collection}, then it is returned unchanged.</li>
-     *   <li>If the value is an array of objects, then it is returned {@linkplain Arrays#asList(Object[]) as a list}.</li>
-     *   <li>If the value is an instance of {@link Iterable}, {@link Iterator} or {@link Enumeration}, copies the values in a new list.</li>
-     *   <li>Otherwise the value is returned as a {@linkplain Collections#singletonList(Object) singleton list}.</li>
-     * </ul>
-     *
-     * <p>Note that in the {@link Iterator} and {@link Enumeration} cases, the given value object
-     * is not valid anymore after this method call since it has been used for the iteration.</p>
-     *
-     * <p>If the returned object needs to be a list, then this method can be chained
-     * with {@link #toList(Collection)} as below:</p>
-     *
-     * {@preformat java
-     *     List<?> list = toList(toCollection(object));
-     * }
-     *
-     * @param  value The value to return as a collection, or {@code null}.
-     * @return The value as a collection, or wrapped in a collection (never {@code null}).
-     *
-     * @category converter
-     */
-    public static Collection<?> toCollection(final Object value) {
-        if (value == null) {
-            return Collections.emptyList();
-        }
-        if (value instanceof Collection<?>) {
-            return (Collection<?>) value;
-        }
-        if (value instanceof Object[]) {
-            return Arrays.asList((Object[]) value);
-        }
-        if (value instanceof Iterable<?>) {
-            final List<Object> list = new ArrayList<>();
-            for (final Object element : (Iterable<?>) value) {
-                list.add(element);
-            }
-            return list;
-        }
-        if (value instanceof Iterator<?>) {
-            final Iterator<?> it = (Iterator<?>) value;
-            final List<Object> list = new ArrayList<>();
-            while (it.hasNext()) {
-                list.add(it.next());
-            }
-            return list;
-        }
-        if (value instanceof Enumeration<?>) {
-            return Collections.list((Enumeration<?>) value);
-        }
-        return Collections.singletonList(value);
-    }
-
-    /**
-     * Casts or copies the given collection to a list. Special cases:
-     *
-     * <ul>
-     *   <li>If the given collection is {@code null}, then this method returns {@code null}.</li>
-     *   <li>If the given collection is already a list, then it is returned unchanged.</li>
-     *   <li>Otherwise the elements are copied in a new list, which is returned.</li>
-     * </ul>
-     *
-     * This method can be chained with {@link #toCollection(Object)}
-     * for handling a wider range of types:
-     *
-     * {@preformat java
-     *     List<?> list = toList(toCollection(object));
-     * }
-     *
-     * @param  <T> The type of elements in the given collection.
-     * @param  collection The collection to cast or copy to a list.
-     * @return The given collection as a list, or a copy of the given collection.
-     *
-     * @category converter
-     */
-    public static <T> List<T> toList(final Collection<T> collection) {
-        if (collection instanceof List<?>) {
-            return (List<T>) collection;
-        }
-        return new ArrayList<>(collection);
-    }
-
-    /**
-     * The comparator to be returned by {@link Collections#listComparator()} and similar methods.
-     */
-    private static final class Compare<T extends Comparable<T>>
-            implements Comparator<Collection<T>>, Serializable
-    {
-        /**
-         * For cross-version compatibility.
-         */
-        private static final long serialVersionUID = 7050753365408754641L;
-
-        /**
-         * The unique instance. Can not be public because of parameterized types: we need a method
-         * for casting to the expected type. This is the same trick than the one used by the JDK
-         * in the {@link Collections#emptySet()} method for instance.
-         */
-        @SuppressWarnings("rawtypes")
-        static final Comparator INSTANCE = new Compare();
-
-        /**
-         * Do not allow instantiation other than the unique {@link #INSTANCE}.
-         */
-        private Compare() {
-        }
-
-        /**
-         * Compares two collections of comparable objects.
-         */
-        @Override
-        public int compare(final Collection<T> c1, final Collection<T> c2) {
-            final Iterator<T> i1 = c1.iterator();
-            final Iterator<T> i2 = c2.iterator();
-            int c;
-            do {
-                final boolean h1 = i1.hasNext();
-                final boolean h2 = i2.hasNext();
-                if (!h1) return h2 ? -1 : 0;
-                if (!h2) return +1;
-                final T e1 = i1.next();
-                final T e2 = i2.next();
-                c = e1.compareTo(e2);
-            } while (c == 0);
-            return c;
-        }
-    };
-
-    /**
-     * Returns a comparator for lists of comparable elements. The first element of each list are
-     * {@linkplain Comparable#compareTo(Object) compared}. If one is <cite>greater than</cite> or
-     * <cite>less than</cite> the other, the result of that comparison is returned. Otherwise
-     * the second element are compared, and so on until either non-equal elements are found,
-     * or end-of-list are reached. In the later case, the shortest list is considered
-     * <cite>less than</cite> the longest one.
-     *
-     * <p>If both lists have the same length and equal elements in the sense of
-     * {@link Comparable#compareTo}, then the comparator returns 0.</p>
-     *
-     * @param  <T> The type of elements in both lists.
-     * @return The ordering between two lists.
-     *
-     * @category comparator
-     */
-    @SuppressWarnings("unchecked")
-    public static <T extends Comparable<T>> Comparator<List<T>> listComparator() {
-        return Compare.INSTANCE;
-    }
-
-    /**
-     * Returns a comparator for sorted sets of comparable elements. The first element of each set
-     * are {@linkplain Comparable#compareTo(Object) compared}. If one is <cite>greater than</cite>
-     * or <cite>less than</cite> the other, the result of that comparison is returned. Otherwise
-     * the second element are compared, and so on until either non-equal elements are found,
-     * or end-of-set are reached. In the later case, the smallest set is considered
-     * <cite>less than</cite> the largest one.
-     *
-     * {@note There is no method accepting an arbitrary <code>Set</code> or <code>Collection</code>
-     *        argument because this comparator makes sense only for collections having determinist
-     *        iteration order.}
-     *
-     * @param <T> The type of elements in both sets.
-     * @return The ordering between two sets.
-     *
-     * @category comparator
-     */
-    @SuppressWarnings("unchecked")
-    public static <T extends Comparable<T>> Comparator<SortedSet<T>> sortedSetComparator() {
-        return Compare.INSTANCE;
-    }
-
-    /**
-     * The comparator to be returned by {@link Collections#valueComparator()}.
-     */
-    private static final class ValueComparator<K,V extends Comparable<V>>
-            implements Comparator<Map.Entry<K,V>>, Serializable
-    {
-        /**
-         * For cross-version compatibility.
-         */
-        private static final long serialVersionUID = 807166038568740444L;
-
-        /**
-         * The unique instance. Can not be public because of parameterized types: we need a method
-         * for casting to the expected type. This is the same trick than the one used by the JDK
-         * in the {@link Collections#emptySet()} method for instance.
-         */
-        @SuppressWarnings("rawtypes")
-        static final ValueComparator INSTANCE = new ValueComparator();
-
-        /**
-         * Do not allow instantiation other than the unique {@link #INSTANCE}.
-         */
-        private ValueComparator() {
-        }
-
-        /**
-         * Compares the values of two entries.
-         */
-        @Override
-        public int compare(final Map.Entry<K,V> e1, final Map.Entry<K,V> e2) {
-            return e1.getValue().compareTo(e2.getValue());
-        }
-    }
-
-    /**
-     * Returns a comparator for map entries having comparable {@linkplain java.util.Map.Entry#getValue() values}.
-     * For any pair of entries {@code e1} and {@code e2}, this method performs the comparison as below:
-     *
-     * {@preformat java
-     *     return e1.getValue().compareTo(e2.getValue());
-     * }
-     *
-     * This comparator can be used as a complement to {@link SortedSet}. While {@code SortedSet}
-     * maintains keys ordering at all time, {@code valueComparator()} is typically used only at
-     * the end of a process in which the values are the numerical calculation results.
-     *
-     * @param <K> The type of keys in the map entries.
-     * @param <V> The type of values in the map entries.
-     * @return A comparator for the values of the given type.
-     *
-     * @category comparator
-     */
-    @SuppressWarnings("unchecked")
-    public static <K,V extends Comparable<V>> Comparator<Map.Entry<K,V>> valueComparator() {
-        return ValueComparator.INSTANCE;
-    }
-
-    /**
      * Returns the capacity to be given to the {@link HashMap#HashMap(int) HashMap}
      * constructor for holding the given number of elements. This method computes the capacity
      * for the default <cite>load factor</cite>, which is 0.75.

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.util.collection;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.LinkedHashMap;
@@ -25,6 +26,7 @@ import net.jcip.annotations.NotThreadSaf
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.Cloner;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
 
 import static org.apache.sis.util.CharSequences.trimWhitespaces;
 import static org.apache.sis.util.collection.CollectionsExt.isNullOrEmpty;
@@ -124,7 +126,9 @@ public class DefaultTreeTable implements
         if (columns.length == 0) {
             throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, "columns"));
         }
-        columns = columns.clone();
+        // Copy the array for safety against user changes, and also for forcing the element type
+        // to TableColumn, not a subclass, because of the UnmodifiableArrayList.wrap(E[]) contract.
+        columns = Arrays.copyOf(columns, columns.length, TableColumn[].class);
         this.columnIndices = createColumnIndices(columns);
         this.columns = UnmodifiableArrayList.wrap(columns);
     }
@@ -171,6 +175,10 @@ public class DefaultTreeTable implements
     /**
      * Returns all columns in the given map, sorted by increasing index value.
      * This method relies on {@link LinkedHashSet} preserving insertion order.
+     *
+     * @return The columns in an array of elements of type {@code TableColumn},
+     *         <strong>not a subtype</strong> for allowing usage in
+     *         {@link UnmodifiableArrayList#wrap(E[])}.
      */
     static TableColumn<?>[] getColumns(final Map<TableColumn<?>,Integer> columnIndices) {
         return columnIndices.keySet().toArray(new TableColumn<?>[columnIndices.size()]);

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -29,7 +29,7 @@ import org.opengis.util.ScopedName;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.collection.WeakValueHashMap;
-import org.apache.sis.util.collection.UnmodifiableArrayList;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -29,7 +29,7 @@ import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.collection.UnmodifiableArrayList;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
 
 
 
@@ -146,6 +146,7 @@ public class DefaultScopedName extends A
         if (i != size) { // Paranoiac check.
             throw new ConcurrentModificationException(Errors.format(Errors.Keys.UnexpectedChange_1, "names"));
         }
+        // Following line is safe because 'parsedNames' type is <? extends LocalName>.
         parsedNames = UnmodifiableArrayList.wrap(locals);
     }
 
@@ -210,6 +211,7 @@ public class DefaultScopedName extends A
         if (index != locals.length) { // Paranoiac check.
             throw new ConcurrentModificationException(Errors.format(Errors.Keys.UnexpectedChange_1, "tail"));
         }
+        // Following line is safe because 'parsedNames' type is <? extends LocalName>.
         parsedNames = UnmodifiableArrayList.wrap(locals);
         if (tail instanceof LocalName) {
             this.path = path;

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java?rev=1467267&r1=1467266&r2=1467267&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java [UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/xml/Pooled.java [UTF-8] Fri Apr 12 13:37:56 2013
@@ -31,7 +31,7 @@ import javax.xml.bind.annotation.adapter
 import org.apache.sis.util.Version;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.collection.CollectionsExt;
+import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.jaxb.MarshalContext;
 
 



Mime
View raw message