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