Author: desruisseaux
Date: Fri Sep 28 09:09:11 2012
New Revision: 1391370

URL: http://svn.apache.org/viewvc?rev=1391370&view=rev
Log:
Initial commit of org.apache.sis.util.collection.

Added:
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/
    
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/BackingStoreException.java
   (with props)
    
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java
   (with props)
    
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java
   (with props)
    
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java
   (with props)
    
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java
   (with props)
Modified:
    sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Static.java

Modified: sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Static.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Static.java?rev=1391370&r1=1391369&r2=1391370&view=diff
==============================================================================
--- sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Static.java 
(original)
+++ sis/trunk/sis-utility/src/main/java/org/apache/sis/util/Static.java Fri Sep 
28 09:09:11 2012
@@ -31,6 +31,8 @@ package org.apache.sis.util;
  *     <td>Methods working on {@link Class} instances.</td></tr>
  *
  * <tr><th colspan="2" class="hsep">Structures (trees, collections, arrays, 
parameters)</th></tr>
+ * <tr><td>{@link org.apache.sis.util.collection.Collections}</td>
+ *     <td>Additions to the JDK {@link java.util.Collections} 
methods.</td></tr>
  * <tr><td>{@link Arrays}</td>
  *     <td>Insert or remove elements in the middle of arrays.</td></tr>
  *

Added: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/BackingStoreException.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/BackingStoreException.java?rev=1391370&view=auto
==============================================================================
--- 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/BackingStoreException.java
 (added)
+++ 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/BackingStoreException.java
 Fri Sep 28 09:09:11 2012
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.collection;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+
+/**
+ * Thrown to indicate that an operation could not complete because of a 
failure in the backing
+ * store (a file or a database). This exception is thrown by collection 
implementations that are
+ * not allowed to throw checked exceptions. This exception usually has an 
{@link IOException} or
+ * a {@link SQLException} as its {@linkplain #getCause() cause}.
+ * <p>
+ * This method provides a {@link #unwrapOrRethrow(Class)} convenience method 
which can be used
+ * for re-throwing the cause as in the example below. This allows client code 
to behave as if a
+ * {@link java.util.Collection} interface was allowed to declare checked 
exceptions.
+ *
+ * {@preformat java
+ *     void myMethod() throws IOException {
+ *         Collection c = ...;
+ *         try {
+ *             c.doSomeStuff();
+ *         } catch (BackingStoreException e) {
+ *             throw e.unwrapOrRethrow(IOException.class);
+ *         }
+ *     }
+ * }
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.3 (derived from geotk-2.3)
+ * @version 0.3
+ * @module
+ */
+public class BackingStoreException extends RuntimeException {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -1714319767053628606L;
+
+    /**
+     * Constructs a new exception with no detail message.
+     */
+    public BackingStoreException() {
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     *
+     * @param message The detail message, saved for later retrieval by the 
{@link #getMessage()} method.
+     */
+    public BackingStoreException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause.
+     *
+     * @param cause The cause, saved for later retrieval by the {@link 
#getCause()} method.
+     */
+    public BackingStoreException(final Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and cause.
+     *
+     * @param message The detail message, saved for later retrieval by the 
{@link #getMessage()} method.
+     * @param cause The cause, saved for later retrieval by the {@link 
#getCause()} method.
+     */
+    public BackingStoreException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Returns the underlying {@linkplain #getCause() cause} as an exception 
of the given type,
+     * or re-throw the exception. More specifically, this method makes the 
following choices:
+     * <p>
+     * <ul>
+     *   <li>If the cause {@linkplain Class#isInstance(Object) is an instance} 
of the given
+     *       type, returns the cause.</li>
+     *   <li>Otherwise if the cause is an instance of {@link 
RuntimeException}, throws
+     *       that exception.</li>
+     *   <li>Otherwise re-throws {@code this}.</li>
+     * </ul>
+     * <p>
+     * This method should be used as in the example below:
+     *
+     * {@preformat java
+     *     void myMethod() throws IOException {
+     *         Collection c = ...;
+     *         try {
+     *             c.doSomeStuff();
+     *         } catch (BackingStoreException e) {
+     *             throw e.unwrapOrRethrow(IOException.class);
+     *         }
+     *     }
+     * }
+     *
+     * @param  <E>  The type of the exception to unwrap.
+     * @param  type The type of the exception to unwrap.
+     * @return The cause as an exception of the given type (never {@code 
null}).
+     * @throws RuntimeException If the cause is an instance of {@code 
RuntimeException},
+     *         in which case that instance is re-thrown.
+     * @throws BackingStoreException if the cause is neither the given type or 
an instance
+     *         of {@link RuntimeException}, in which case {@code this} 
exception is re-thrown.
+     */
+    @SuppressWarnings("unchecked")
+    public <E extends Exception> E unwrapOrRethrow(final Class<E> type)
+            throws RuntimeException, BackingStoreException
+    {
+        final Throwable cause = getCause();
+        if (type.isInstance(cause)) {
+            return (E) cause;
+        } else if (cause instanceof RuntimeException) {
+            throw (RuntimeException) cause;
+        } else {
+            throw this;
+        }
+    }
+}

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/BackingStoreException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/BackingStoreException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java?rev=1391370&view=auto
==============================================================================
--- 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java
 (added)
+++ 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java
 Fri Sep 28 09:09:11 2012
@@ -0,0 +1,540 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.collection;
+
+import java.util.*;
+import java.io.Serializable;
+import org.apache.sis.util.Static;
+
+import static java.util.Collections.list;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singleton;
+import static java.util.Collections.singletonMap;
+import static java.util.Collections.singletonList;
+import static java.util.Collections.unmodifiableSet;
+import static java.util.Collections.unmodifiableMap;
+
+
+/**
+ * Static methods working on {@link Collection} objects.
+ * This is an extension to the Java {@link java.util.Collections} utility 
class providing:
+ * <p>
+ * <ul>
+ *   <li>Null-safe {@link #clear(Collection) clear}, {@link 
#isNullOrEmpty(Collection) isNullOrEmpty}
+ *       and {@link #addIfNonNull(Collection, Object) addIfNonNull} methods, 
for the convenience of
+ *       classes using the <cite>lazy instantiation</cite> pattern.</li>
+ *   <li>{@link #unmodifiableOrCopy(Set) unmodifiableOrCopy} methods, which 
may be slightly more
+ *       compact than the standard {@link 
java.util.Collections#unmodifiableSet(Set)} equivalent
+ *       when the unmodifiable collection is not required to be a view over 
the original collection.</li>
+ *   <li>{@link #asCollection(Object) asCollection} for wrapping arbitrary 
objects to list or collection.</li>
+ *   <li>List and collection {@linkplain #listComparator() comparators}.</li>
+ *   <li>{@link #modifiableCopy(Collection) copy} method for taking a snapshot 
of an arbitrary
+ *       implementation into an unsynchronized, modifiable, in-memory 
object.</li>
+ * </ul>
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.3 (derived from geotk-3.00)
+ * @version 0.3
+ * @module
+ */
+public final class Collections extends Static {
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private Collections() {
+    }
+
+    /**
+     * Clears the given collection, if non-null.
+     * If the given collection is null, then this method does nothing.
+     * <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}.
+     *
+     * @param collection The collection to clear, or {@code null}.
+     */
+    public static void clear(final Collection<?> collection) {
+        if (collection != null) {
+            collection.clear();
+        }
+    }
+
+    /**
+     * Clears the given map, if non-null.
+     * If the given map is null, then this method does nothing.
+     * <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}.
+     *
+     * @param map The map to clear, or {@code null}.
+     */
+    public static void clear(final Map<?,?> map) {
+        if (map != null) {
+            map.clear();
+        }
+    }
+
+    /**
+     * 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.
+     *
+     * @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.
+     *
+     * @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();
+    }
+
+    /**
+     * Adds the given element to the given collection only if the element is 
non-null.
+     * If any of the given argument is null, then this method does nothing.
+     *
+     * @param  <E>        The type of elements in the collection.
+     * @param  collection The collection in which to add elements, or {@code 
null}.
+     * @param  element    The element to add in the collection, or {@code 
null}.
+     * @return {@code true} if the given element has been added, or {@code 
false} otherwise.
+     */
+    public static <E> boolean addIfNonNull(final Collection<E> collection, 
final E element) {
+        return (collection != null && element != null) && 
collection.add(element);
+    }
+
+    /**
+     * 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 java.util.Collections#emptyList()
+     * @see java.util.Collections#emptySet()
+     */
+    @SuppressWarnings({"unchecked","rawtype"})
+    public static <E> Queue<E> emptyQueue() {
+        return EmptyQueue.INSTANCE;
+    }
+
+    /**
+     * 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 java.util.Collections#emptyList()
+     * @see java.util.Collections#emptySet()
+     */
+    @SuppressWarnings({"unchecked","rawtype"})
+    public static <E> SortedSet<E> emptySortedSet() {
+        return EmptySortedSet.INSTANCE;
+    }
+
+    /**
+     * 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 java.util.Collections#unmodifiableSet(Set)
+     */
+    public static <E> Set<E> immutableSet(final E... array) {
+        if (array == null) {
+            return null;
+        }
+        switch (array.length) {
+            case 0:  return emptySet();
+            case 1:  return singleton(array[0]);
+            default: return unmodifiableSet(new 
LinkedHashSet<E>(Arrays.asList(array)));
+        }
+    }
+
+    /**
+     * Returns a unmodifiable version of the given set.
+     * This method is different than the standard {@link 
java.util.Collections#unmodifiableSet(Set)}
+     * in that it tries to returns a more efficient object when there is zero 
or one element.
+     * <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 java.util.Collections#unmodifiableSet(Set)} method 
instead.
+     * <p>
+     * This method is provided because sets of zero or one element are very 
frequent in Apache
+     * SIS, especially for {@link 
org.apache.sis.referencing.AbstractIdentifiedObject} names
+     * or identifiers.
+     *
+     * @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.
+     */
+    public static <E> Set<E> unmodifiableOrCopy(Set<E> set) {
+        if (set != null) {
+            switch (set.size()) {
+                case 0: {
+                    set = emptySet();
+                    break;
+                }
+                case 1: {
+                    set = singleton(set.iterator().next());
+                    break;
+                }
+                default: {
+                    set = unmodifiableSet(set);
+                    break;
+                }
+            }
+        }
+        return set;
+    }
+
+    /**
+     * Returns a unmodifiable version of the given map.
+     * This method is different than the standard {@link 
java.util.Collections#unmodifiableMap(Map)}
+     * in that it tries to returns a more efficient object when there is zero 
or one entry.
+     * <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 java.util.Collections#unmodifiableMap(Map)} method 
instead.
+     * <p>
+     * This method is provided because maps of zero or one element are very 
frequent
+     * in Apache SIS.
+     *
+     * @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.
+     */
+    public static <K,V> Map<K,V> unmodifiableOrCopy(Map<K,V> map) {
+        if (map != null) {
+            switch (map.size()) {
+                case 0: {
+                    map = emptyMap();
+                    break;
+                }
+                case 1: {
+                    final Map.Entry<K,V> entry = 
map.entrySet().iterator().next();
+                    map = singletonMap(entry.getKey(), entry.getValue());
+                    break;
+                }
+                default: {
+                    map = 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:
+     * <p>
+     * <table class="sis">
+     * <tr><th>Input type</th><th>Output type</th></tr>
+     * <tr><td>{@link SortedSet}</td><td>{@link TreeSet}</td></tr>
+     * <tr><td>{@link HashSet}</td><td>{@link HashSet}</td></tr>
+     * <tr><td>Other {@link Set}</td><td>{@link LinkedHashSet}</td></tr>
+     * <tr><td>{@link Queue}</td><td>{@link LinkedList}</td></tr>
+     * <tr><td>{@link List} or other {@link Collection}</td><td>{@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.
+     */
+    @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<E>(collection);
+            }
+            if (type == HashSet.class || type == LinkedHashSet.class) {
+                return (Collection<E>) ((HashSet<E>) collection).clone();
+            }
+            return new LinkedHashSet<E>(collection);
+        }
+        if (collection instanceof Queue<?>) {
+            if (type == LinkedList.class) {
+                return (Collection<E>) ((LinkedList<E>) collection).clone();
+            }
+            return new LinkedList<E>(collection);
+        }
+        if (type == ArrayList.class) {
+            return (Collection<E>) ((ArrayList<E>) collection).clone();
+        }
+        return new ArrayList<E>(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:
+     * <p>
+     * <table class="sis">
+     * <tr><th>Input type</th><th>Output type</th></tr>
+     * <tr><td>{@link SortedMap}</td><td>{@link TreeMap}</td></tr>
+     * <tr><td>{@link HashMap}</td><td>{@link HashMap}</td></tr>
+     * <tr><td>Other {@link Map}</td><td>{@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.
+     */
+    @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<K,V>(map);
+        }
+        if (type == HashMap.class || type == LinkedHashMap.class) {
+            return (Map<K,V>) ((HashMap<K,V>) map).clone();
+        }
+        return new LinkedHashMap<K,V>(map);
+    }
+
+    /**
+     * Returns the given value as a collection. Special cases:
+     * <p>
+     * <ul>
+     *   <li>If the value is null, then this method returns an {@linkplain 
java.util.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 
java.util.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>
+     * If the returned object needs to be a list, then this method can be 
chained
+     * with {@link #asList(Collection)} as below:
+     *
+     * {@preformat java
+     *     List<?> list = asList(asCollection(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}).
+     */
+    public static Collection<?> asCollection(final Object value) {
+        if (value == null) {
+            return 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<Object>();
+            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<Object>();
+            while (it.hasNext()) {
+                list.add(it.next());
+            }
+            return list;
+        }
+        if (value instanceof Enumeration<?>) {
+            return list((Enumeration<?>) value);
+        }
+        return singletonList(value);
+    }
+
+    /**
+     * Casts or copies the given collection to a list. Special cases:
+     * <p>
+     * <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>
+     * <p>
+     * This method can be chained with {@link #asCollection(Object)}
+     * for handling a wider range of types:
+     *
+     * {@preformat java
+     *     List<?> list = asList(asCollection(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.
+     */
+    public static <T> List<T> asList(final Collection<T> collection) {
+        if (collection instanceof List<?>) {
+            return (List<T>) collection;
+        }
+        return new ArrayList<T>(collection);
+    }
+
+    /**
+     * The comparator to be returned by {@code #listComparator} and similar 
methods. Can not be
+     * public because of parameterized types: we need a method for casting to 
the expected type.
+     * This is the same trick than {@link Collections#emptySet()} for example.
+     */
+    @SuppressWarnings("rawtypes")
+    private static final class Compare implements 
Comparator<Collection<Comparable>>, Serializable {
+        /**
+         * The unique instance.
+         */
+        static final Comparator<Collection<Comparable>> INSTANCE = new 
Compare();
+
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = -8926770873102046405L;
+
+        /**
+         * Compares to collections of comparable objects.
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        public int compare(final Collection<Comparable> c1, final 
Collection<Comparable> c2) {
+            final Iterator<Comparable> i1 = c1.iterator();
+            final Iterator<Comparable> 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 Comparable e1 = i1.next();
+                final Comparable 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 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.
+     *
+     * @param  <T> The type of elements in both lists.
+     * @return The ordering between two lists.
+     */
+    @SuppressWarnings({"unchecked","rawtypes"})
+    public static <T extends Comparable<T>> Comparator<List<T>> 
listComparator() {
+        return (Comparator) Compare.INSTANCE;
+    }
+
+    /**
+     * Returns a comparator for sorted sets of comparable elements. The 
elements are compared in
+     * iteration order as for the {@linkplain #listComparator list comparator}.
+     *
+     * @param <T> The type of elements in both sets.
+     * @return The ordering between two sets.
+     */
+    @SuppressWarnings({"unchecked","rawtypes"})
+    public static <T extends Comparable<T>> Comparator<SortedSet<T>> 
sortedSetComparator() {
+        return (Comparator) Compare.INSTANCE;
+    }
+
+    /**
+     * Returns a comparator for arbitrary collections of comparable elements. 
The elements are
+     * compared in iteration order as for the {@linkplain #listComparator list 
comparator}.
+     * <p>
+     * <em>This comparator make sense only for collections having determinist 
order</em>
+     * like {@link java.util.TreeSet}, {@link java.util.LinkedHashSet} or 
queues.
+     * Do <strong>not</strong> use it with {@link java.util.HashSet}.
+     *
+     * @param <T> The type of elements in both collections.
+     * @return The ordering between two collections.
+     */
+    @SuppressWarnings({"unchecked","rawtypes"})
+    public static <T extends Comparable<T>> Comparator<Collection<T>> 
collectionComparator() {
+        return (Comparator) Compare.INSTANCE;
+    }
+
+    /**
+     * Returns the capacity to be given to the {@link 
java.util.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 java.util.LinkedHashMap} and
+     * {@link java.util.HashSet} as well, which are built on top of {@code 
HashMap}.
+     *
+     * @param elements The number of elements to be put into the hash map or 
hash set.
+     * @return The optimal initial capacity to be given to the hash map 
constructor.
+     */
+    public static int hashMapCapacity(int elements) {
+        final int r = elements >>> 2;
+        if (elements != (r << 2)) {
+            elements++;
+        }
+        return elements + r;
+    }
+}

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java?rev=1391370&view=auto
==============================================================================
--- 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java
 (added)
+++ 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java
 Fri Sep 28 09:09:11 2012
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.collection;
+
+import java.io.Serializable;
+import java.util.AbstractQueue;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Queue;
+
+
+/**
+ * An immutable and serializable empty queue.
+ *
+ * @param  <E> Type of elements in the collection.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3 (derived from geotk-3.10)
+ * @version 0.3
+ * @module
+ */
+final class EmptyQueue<E> extends AbstractQueue<E> implements Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -6147951199761870325L;
+
+    /**
+     * The singleton instance to be returned by {@link 
Collections#emptyQueue()}.
+     * This is not parameterized on intend.
+     */
+    @SuppressWarnings("rawtypes")
+    static final Queue INSTANCE = new EmptyQueue();
+
+    /**
+     * Do not allow instantiation except for the singleton.
+     */
+    private EmptyQueue() {
+    }
+
+    @Override public void        clear()    {}
+    @Override public boolean     isEmpty()  {return true;}
+    @Override public int         size()     {return 0;}
+    @Override public Iterator<E> iterator() {return 
Collections.<E>emptySet().iterator();}
+    @Override public boolean     offer(E e) {return false;}
+    @Override public E           poll()     {return null;}
+    @Override public E           peek()     {return null;}
+
+    /**
+     * Returns the singleton instance on deserialization.
+     */
+    protected Object readResolve() {
+        return INSTANCE;
+    }
+}

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptyQueue.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java?rev=1391370&view=auto
==============================================================================
--- 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java
 (added)
+++ 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java
 Fri Sep 28 09:09:11 2012
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.collection;
+
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.SortedSet;
+
+
+/**
+ * An immutable, serializable empty sorted set.
+ * This class exists only on the JDK6 and JDK7 branches;
+ * it will be removed on the JDK8 branch.
+ *
+ * @param  <E> Type of elements in the collection.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3 (derived from geotk-3.10)
+ * @version 0.3
+ * @module
+ */
+final class EmptySortedSet<E> extends AbstractSet<E> implements SortedSet<E>, 
Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 4684832991264788298L;
+
+    /**
+     * The unique instance of this set.
+     */
+    @SuppressWarnings({"unchecked","rawtypes"})
+    static final SortedSet INSTANCE = new EmptySortedSet();
+
+    /**
+     * Do not allow instantiation except for the unique instance.
+     */
+    private EmptySortedSet() {
+    }
+
+    @Override public void          clear()                      {}
+    @Override public Comparator<E> comparator()                 {return null;}
+    @Override public Iterator<E>   iterator()                   {return 
Collections.<E>emptySet().iterator();}
+    @Override public int           size()                       {return 0;}
+    @Override public boolean       isEmpty()                    {return true;}
+    @Override public boolean       contains(Object obj)         {return false;}
+    @Override public boolean       containsAll(Collection<?> c) {return 
c.isEmpty();}
+    @Override public E             first()                      {throw new 
NoSuchElementException();}
+    @Override public E             last()                       {throw new 
NoSuchElementException();}
+    @Override public SortedSet<E>  subSet(E from, E to)         {return this;}
+    @Override public SortedSet<E>  headSet(E toElement)         {return this;}
+    @Override public SortedSet<E>  tailSet(E fromElement)       {return this;}
+
+    /**
+     * Returns the unique instance on deserialization.
+     */
+    private Object readResolve() {
+        return INSTANCE;
+    }
+}

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/EmptySortedSet.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java?rev=1391370&view=auto
==============================================================================
--- 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java
 (added)
+++ 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java
 Fri Sep 28 09:09:11 2012
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Addition to the collection framework. Most classes in this package 
implement interfaces
+ * from the <cite>Java Collection Framework</cite> defined in the {@link 
java.util} package.
+ * <ul>
+ *   <li><p>
+ *     {@link org.apache.sis.util.collection.WeakHashSet} provides a way to 
ensure that
+ *     a factory returns unique instances for all values that are equal in the 
sense of
+ *     {@link java.lang.Object#equals Object.equals(Object)}. The values that 
were created
+ *     in previous factory operations are retained by {@linkplain 
java.lang.ref.WeakReference
+ *     weak references} for reuse.
+ *   </p></li><li><p>
+ *     {@link org.apache.sis.util.collection.Cache} and
+ *     {@link org.apache.sis.util.collection.WeakValueHashMap} are {@link 
java.util.Map java.util.Map}
+ *     implementations that may be used for some caching or pseudo-caching 
functionalities. The
+ *     {@link org.apache.sis.util.collection.Cache} implementation is the most 
full-featured one
+ *     and supports concurrency, while the other implementations are more 
lightweight, sometime
+ *     thread-safe but without concurrency support.
+ *   </p></li><li><p>
+ *     {@link org.apache.sis.util.collection.CheckedCollection},
+ *     {@link org.apache.sis.util.collection.CheckedArrayList},
+ *     {@link org.apache.sis.util.collection.CheckedHashSet} and
+ *     {@link org.apache.sis.util.collection.CheckedHashMap} can be used for 
combining <em>runtime</em>
+ *     type safety with thread-safety (without concurrency). They are similar 
in functionalities to
+ *     the wrappers provided by the standard {@link java.util.Collections} 
methods, except that they
+ *     combine both functionalities in a single class (so reducing the amount 
of indirection), provide
+ *     a hook for making the collections read-only and allow the caller to 
specify the synchronization
+ *     lock of his choice.
+ *   </p></li><li><p>
+ *     {@link org.apache.sis.util.collection.DerivedMap} and
+ *     {@link org.apache.sis.util.collection.DerivedSet} are wrapper 
collections in which the
+ *     keys or the values are derived on-the-fly from the content of an other 
collection.
+ *   </p></li><li><p>
+ *     {@link org.apache.sis.util.collection.IntegerList} and
+ *     {@link org.apache.sis.util.collection.RangeSet} are collections 
specialized for a particular kind
+ *     of content, providing more efficient storage than what we would get 
with the general-purpose
+ *     collection implementations.
+ *   </p></li><li><p>
+ *     {@link org.apache.sis.util.collection.DisjointSet},
+ *     {@link org.apache.sis.util.collection.KeySortedList} and
+ *     {@link org.apache.sis.util.collection.FrequencySortedSet} provides 
specialized ways to
+ *     organize their elements.
+ *   </p></li>
+ * </ul>
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.3 (derived from geotk-1.0)
+ * @version 0.3
+ * @module
+ */
+package org.apache.sis.util.collection;

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sis/trunk/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain


Reply via email to