sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1404883 - in /sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis: internal/jaxb/ util/ util/collection/
Date Fri, 02 Nov 2012 06:55:40 GMT
Author: desruisseaux
Date: Fri Nov  2 06:55:39 2012
New Revision: 1404883

URL: http://svn.apache.org/viewvc?rev=1404883&view=rev
Log:
Added static factory methods for creating derived collections,
renamed internal variables for consistency and updated javadoc.

Added:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/IdentityConverter.java   (with props)
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java   (with props)
Modified:
    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/ObjectConverter.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Static.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedMap.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/WeakEntry.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java

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=1404883&r1=1404882&r2=1404883&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/jaxb/NonMarshalledAuthority.java Fri Nov  2 06:55:39 2012
@@ -27,8 +27,6 @@ import org.apache.sis.internal.simple.Si
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.xml.IdentifierSpace;
 
-import static org.apache.sis.util.collection.Collections.addIfNonNull;
-
 
 /**
  * The {@linkplain Identifier#getAuthority() authority of identifiers} that are not expected to be
@@ -160,7 +158,9 @@ public final class NonMarshalledAuthorit
             }
             it.remove();
         }
-        addIfNonNull(identifiers, id);
+        if (id != null) {
+            identifiers.add(id);
+        }
     }
 
     /**

Added: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/IdentityConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/IdentityConverter.java?rev=1404883&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/IdentityConverter.java (added)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/IdentityConverter.java Fri Nov  2 06:55:39 2012
@@ -0,0 +1,133 @@
+/*
+ * 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;
+
+import java.util.Set;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import net.jcip.annotations.Immutable;
+import org.apache.sis.math.FunctionProperty;
+
+
+/**
+ * An object converter which returns the source unchanged.
+ *
+ * @param <T> The base type of source and converted objects.
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.3 (derived from geotk-3.01)
+ * @version 0.3
+ * @module
+ */
+@Immutable
+final class IdentityConverter<T> implements ObjectConverter<T,T>, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -7203549932226245206L;
+
+    /**
+     * Identity converters created in the JVM, for sharing unique instances.
+     * Use weak keys in order to allow class unloading.
+     */
+    private static final Map<Class<?>, IdentityConverter<?>> CACHE = new WeakHashMap<>();
+
+    /**
+     * Returns an identity converter for the given type.
+     */
+    public static synchronized <T> IdentityConverter<T> create(final Class<T> type) {
+        @SuppressWarnings("unchecked")
+        IdentityConverter<T> converter = (IdentityConverter<T>) CACHE.get(type);
+        if (converter == null) {
+            converter = new IdentityConverter<>(type);
+            CACHE.put(type, converter);
+        }
+        return converter;
+    }
+
+    /**
+     * The type of source and converted objects.
+     */
+    private final Class<T> type;
+
+    /**
+     * Creates a new identity converter.
+     *
+     * @param type The type of source and converted objects.
+     */
+    private IdentityConverter(final Class<T> type) {
+        this.type = type;
+    }
+
+    /**
+     * Returns the properties of this converter.
+     */
+    @Override
+    public Set<FunctionProperty> properties() {
+        return EnumSet.allOf(FunctionProperty.class);
+    }
+
+    /**
+     * Returns the type for source objects.
+     */
+    @Override
+    public Class<T> getSourceClass() {
+        return type;
+    }
+
+    /**
+     * Returns the type of converted objects.
+     */
+    @Override
+    public Class<T> getTargetClass() {
+        return type;
+    }
+
+    /**
+     * Returns the given object unchanged.
+     */
+    @Override
+    public T convert(final T source) {
+        return source;
+    }
+
+    /**
+     * Returns {@code this}, since this converter is its own inverse.
+     */
+    @Override
+    public ObjectConverter<T,T> inverse() {
+        return this;
+    }
+
+    /**
+     * Invoked on deserialization for resolving to a unique instance.
+     */
+    private Object readResolve() throws ObjectStreamException {
+        synchronized (IdentityConverter.class) {
+            @SuppressWarnings("unchecked")
+            final IdentityConverter<T> converter = (IdentityConverter<T>) CACHE.get(type);
+            if (converter != null) {
+                return converter;
+            }
+            CACHE.put(type, this);
+        }
+        return this;
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/IdentityConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/IdentityConverter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverter.java?rev=1404883&r1=1404882&r2=1404883&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverter.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverter.java Fri Nov  2 06:55:39 2012
@@ -39,7 +39,7 @@ import org.apache.sis.math.FunctionPrope
  * that this converter can declare:</p>
  *
  * <ul>
- *   <li>IF {@code convert(S)} returns {@code null} for unconvertible objects, then this {@code ObjectConverter}
+ *   <li>If {@code convert(S)} returns {@code null} for unconvertible objects, then this {@code ObjectConverter}
  *       can not declare {@link FunctionProperty#INJECTIVE} in its set of {@linkplain #properties() properties},
  *       because more than one source value can produce the same target value (namely {@code null}).</li>
  *   <li>If {@code convert(S)} throws an exception for unconvertible objects, then this {@code ObjectConverter}

Added: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java?rev=1404883&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java (added)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java Fri Nov  2 06:55:39 2012
@@ -0,0 +1,158 @@
+/*
+ * 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;
+
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Creates {@link ObjectConverter} instances, or uses them for creating collection views.
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.3 (derived from geotk-3.00)
+ * @version 0.3
+ * @module
+ */
+public final class ObjectConverters extends Static {
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private ObjectConverters() {
+    }
+
+    /**
+     * Returns an identity converter for objects of the given type.
+     *
+     * @param  <T>  The object type.
+     * @param  type The object type.
+     * @return An identity converter for objects of the given type.
+     */
+    public static <T> ObjectConverter<T,T> identity(final Class<T> type) {
+        ArgumentChecks.ensureNonNull("type", type);
+        return IdentityConverter.create(type);
+    }
+
+    /**
+     * 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.
+     *
+     * <p>This convenience method delegates to
+     * {@link org.apache.sis.util.collection.Collections#derivedSet Collections.derivedSet(…)}.
+     * See the javadoc of the above method for more information.
+     *
+     * @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.collection.Collections#derivedSet(Set, ObjectConverter)
+     */
+    public static <S,E> Set<E> derivedSet(final Set<S> storage, final ObjectConverter<S,E> converter) {
+        return org.apache.sis.util.collection.Collections.derivedSet(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.
+     *
+     * <p>This convenience method delegates to
+     * {@link org.apache.sis.util.collection.Collections#derivedMap Collections.derivedMap(…)}.
+     * See the javadoc of the above method for more information.
+     *
+     * @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.collection.Collections#derivedMap(Map, ObjectConverter, ObjectConverter)
+     */
+    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)
+    {
+        return org.apache.sis.util.collection.Collections.derivedMap(storage, keyConverter, valueConverter);
+    }
+
+    /**
+     * Returns a map whose whose keys are derived <cite>on-the-fly</cite> from the given map.
+     * Conversions from the original keys to the derived keys are performed when needed by
+     * invoking the {@link ObjectConverter#convert(Object)} method on the given converter.
+     *
+     * <p>This convenience method delegates to
+     * {@link org.apache.sis.util.collection.Collections#derivedMap Collections.derivedMap(…)}.
+     * See the javadoc of the above method for more information.
+     *
+     * @param <SK>         The type of keys   in the storage map.
+     * @param <K>          The type of keys   in the derived map.
+     * @param <V>          The type of values in the storage and 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 valueType    The type of values in the storage and derived map.
+     * @return A view over the {@code storage} map containing all entries with the keys converted
+     *         by the given converter, or {@code null} if {@code storage} was null.
+     *
+     * @see org.apache.sis.util.collection.Collections#derivedMap(Map, ObjectConverter, ObjectConverter)
+     */
+    public static <SK,K,V> Map<K,V> derivedKeys(final Map<SK,V> storage,
+                                                final ObjectConverter<SK,K> keyConverter,
+                                                final Class<V> valueType)
+    {
+        ArgumentChecks.ensureNonNull("valueType", valueType);
+        return org.apache.sis.util.collection.Collections.derivedMap(storage,
+                keyConverter, IdentityConverter.create(valueType));
+    }
+
+    /**
+     * Returns a map whose whose values are derived <cite>on-the-fly</cite> from the given map.
+     * Conversions from the original values to the derived values are performed when needed by
+     * invoking the {@link ObjectConverter#convert(Object)} method on the given converter.
+     *
+     * <p>This convenience method delegates to
+     * {@link org.apache.sis.util.collection.Collections#derivedMap Collections.derivedMap(…)}.
+     * See the javadoc of the above method for more information.
+     *
+     * @param <K>          The type of keys in the storage and derived map.
+     * @param <SV>         The type of values in the storage map.
+     * @param <V>          The type of values in the derived map.
+     * @param storage      The storage map containing the original entries, or {@code null}.
+     * @param keyType      The type of keys in the storage and 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 with the values converted
+     *         by the given converter, or {@code null} if {@code storage} was null.
+     *
+     * @see org.apache.sis.util.collection.Collections#derivedMap(Map, ObjectConverter, ObjectConverter)
+     */
+    public static <K,SV,V> Map<K,V> derivedValues(final Map<K,SV> storage,
+                                                  final Class<K> keyType,
+                                                  final ObjectConverter<SV,V> valueConverter)
+    {
+        ArgumentChecks.ensureNonNull("keyType", keyType);
+        return org.apache.sis.util.collection.Collections.derivedMap(storage,
+                IdentityConverter.create(keyType), valueConverter);
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/ObjectConverters.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Static.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Static.java?rev=1404883&r1=1404882&r2=1404883&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Static.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/Static.java Fri Nov  2 06:55:39 2012
@@ -40,6 +40,10 @@ package org.apache.sis.util;
  * <tr><td>{@link Arrays}</td>
  *     <td>Insert or remove elements in the middle of arrays.</td></tr>
  *
+ * <tr><th colspan="2" class="hsep">Input / Output (including CRS, XML, images)</th></tr>
+ * <tr><td>{@link org.apache.sis.io.IO}</td>
+ *     <td>Methods working on {@link Appendable} instances.</td></tr>
+ *
  * <tr><th colspan="2" class="hsep">Loggings and exceptions</th></tr>
  * <tr><td>{@link ArgumentChecks}</td>
  *     <td>Perform argument checks and throw {@link IllegalArgumentException} if needed.</td></tr>
@@ -48,6 +52,10 @@ package org.apache.sis.util;
  * <tr><td>{@link org.apache.sis.util.logging.Logging}</td>
  *     <td>Get a JDK {@linkplain java.util.logging.Logger logger}, which may be a wrapper around
  *         the <cite>Apache Commons Logging</cite> or <cite>Log4J</cite> framework.</td></tr>
+ *
+ * <tr><th colspan="2" class="hsep">Factories</th></tr>
+ * <tr><td>{@link ObjectConverters}</td>
+ *     <td>Creates {@link ObjectConverter} instances, or collection views using object converters.</td></tr>
  * </table>
  *
  * @author Martin Desruisseaux (Geomatys)

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java?rev=1404883&r1=1404882&r2=1404883&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/Collections.java Fri Nov  2 06:55:39 2012
@@ -18,9 +18,9 @@ package org.apache.sis.util.collection;
 
 import java.util.*;
 import java.io.Serializable;
-import java.util.logging.Logger;
 import org.apache.sis.util.Static;
-import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.ObjectConverter;
 
 import static java.util.Collections.list;
 import static java.util.Collections.emptySet;
@@ -38,9 +38,8 @@ import static java.util.Collections.unmo
  * This is an extension to the Java {@link java.util.Collections} utility class providing:
  *
  * <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>Null-safe {@link #isNullOrEmpty(Collection) isNullOrEmpty} method,
+ *       for the convenience of classes using the <cite>lazy instantiation</cite> pattern.</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) modifiableCopy} method for taking a snapshot of an arbitrary
@@ -57,54 +56,21 @@ import static java.util.Collections.unmo
  */
 public final class Collections extends Static {
     /**
-     * The logger where to logs collection events, if logging at the finest level is enabled.
-     */
-    static final Logger LOGGER = Logging.getLogger(Collections.class);
-
-    /**
      * 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}.</p>
-     *
-     * @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}.</p>
-     *
-     * @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.
      *
+     * <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.
      */
@@ -117,6 +83,10 @@ public final class Collections extends S
      * 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.
      */
@@ -125,19 +95,6 @@ public final class Collections extends S
     }
 
     /**
-     * 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.
@@ -169,6 +126,95 @@ public final class Collections extends S
     }
 
     /**
+     * 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 #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)
+     */
+    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)
+     */
+    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
@@ -533,14 +579,14 @@ public final class Collections extends S
      * <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}.</p>
      *
-     * @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.
+     * @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(int elements) {
-        final int r = elements >>> 2;
-        if (elements != (r << 2)) {
-            elements++;
+    public static int hashMapCapacity(final int count) {
+        int r = count >>> 2;
+        if ((count & 0x3) != 0) {
+            r++;
         }
-        return elements + r;
+        return count + r;
     }
 }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedMap.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedMap.java?rev=1404883&r1=1404882&r2=1404883&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedMap.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedMap.java Fri Nov  2 06:55:39 2012
@@ -23,12 +23,13 @@ import java.util.AbstractMap;
 import java.io.Serializable;
 import org.apache.sis.util.Decorator;
 import org.apache.sis.util.ObjectConverter;
-import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.UnconvertibleObjectException;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.math.FunctionProperty;
 
 
 /**
- * A map whose keys are derived <cite>on-the-fly</cite> from an other map.
+ * A map whose keys and values are derived <cite>on-the-fly</cite> from an other map.
  * Conversions are performed when needed by the following methods:
  *
  * <ul>
@@ -44,21 +45,21 @@ import org.apache.sis.math.FunctionPrope
  * {@section Constraints}
  * <ul>
  *   <li>This map does not support {@code null} keys, since {@code null} is used as a
- *       sentinel value when no mapping from {@linkplain #base} to {@code this} exists.</li>
- *   <li>Instances of this class are serializable if their underlying {@linkplain #base} map
+ *       sentinel value when no mapping from {@linkplain #storage} to {@code this} exists.</li>
+ *   <li>Instances of this class are serializable if their underlying {@linkplain #storage} map
  *       is serializable.</li>
  *   <li>This class is not thread-safe.</li>
  * </ul>
  *
  * {@section Performance considerations}
- * This class does not cache any value, since the {@linkplain #base} map is presumed modifiable.
- * If the base map is known to be immutable, then sub-classes may consider to cache some values,
+ * This class does not cache any value, since the {@linkplain #storage} map is presumed modifiable.
+ * If the storage map is known to be immutable, then sub-classes may consider to cache some values,
  * especially the result of the {@link #size()} method.
  *
- * @param <BK> The type of keys in the backing map.
- * @param <BV> The type of values in the backing map.
+ * @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 this map.
- * @param <V>  The type of values in both this map and the underlying map.
+ * @param <V>  The type of values in this map.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3 (derived from geotk-2.0)
@@ -66,8 +67,8 @@ import org.apache.sis.math.FunctionPrope
  * @module
  */
 @Decorator(Map.class)
-class DerivedMap<BK,BV,K,V> extends AbstractMap<K,V> implements
-        ObjectConverter<Map.Entry<BK,BV>, Map.Entry<K,V>>, Serializable
+class DerivedMap<SK,SV,K,V> extends AbstractMap<K,V> implements
+        ObjectConverter<Map.Entry<SK,SV>, Map.Entry<K,V>>, Serializable
 {
     /**
      * Serial number for inter-operability with different versions.
@@ -75,19 +76,19 @@ class DerivedMap<BK,BV,K,V> extends Abst
     private static final long serialVersionUID = -6994867383669885934L;
 
     /**
-     * The base map whose keys are derived from.
+     * The storage map whose keys are derived from.
      */
-    protected final Map<BK,BV> base;
+    protected final Map<SK,SV> storage;
 
     /**
-     * The converter from the base to the derived keys.
+     * The converter from the storage to the derived keys.
      */
-    protected final ObjectConverter<BK,K> keyConverter;
+    protected final ObjectConverter<SK,K> keyConverter;
 
     /**
-     * The converter from the base to the derived values.
+     * The converter from the storage to the derived values.
      */
-    protected final ObjectConverter<BV,V> valueConverter;
+    protected final ObjectConverter<SV,V> valueConverter;
 
     /**
      * Key set. Will be constructed only when first needed.
@@ -104,42 +105,42 @@ class DerivedMap<BK,BV,K,V> extends Abst
     private transient Set<Map.Entry<K,V>> entrySet;
 
     /**
-     * Creates a new derived map from the specified base map.
+     * Creates a new derived map from the specified storage map.
      *
-     * @param base           The base map.
+     * @param storage        The map which actually store the entries.
      * @param keyConverter   The converter for the keys.
      * @param valueConverter The converter for the values.
      */
-    static <BK,BV,K,V> Map<K,V> create(final Map<BK,BV> base,
-                                       final ObjectConverter<BK,K> keyConverter,
-                                       final ObjectConverter<BV,V> valueConverter)
+    static <SK,SV,K,V> Map<K,V> create(final Map<SK,SV> storage,
+                                       final ObjectConverter<SK,K> keyConverter,
+                                       final ObjectConverter<SV,V> valueConverter)
     {
         final Set<FunctionProperty> kp =   keyConverter.properties();
         final Set<FunctionProperty> vp = valueConverter.properties();
         if (kp.contains(FunctionProperty.INVERTIBLE)) {
             if (vp.contains(FunctionProperty.INVERTIBLE)) {
-                return new Invertible<>(base, keyConverter, valueConverter);
+                return new Invertible<>(storage, keyConverter, valueConverter);
             }
-            return new InvertibleKey<>(base, keyConverter, valueConverter);
+            return new InvertibleKey<>(storage, keyConverter, valueConverter);
         }
         if (vp.contains(FunctionProperty.INVERTIBLE)) {
-            return new InvertibleValue<>(base, keyConverter, valueConverter);
+            return new InvertibleValue<>(storage, keyConverter, valueConverter);
         }
-        return new DerivedMap<>(base, keyConverter, valueConverter);
+        return new DerivedMap<>(storage, keyConverter, valueConverter);
     }
 
     /**
-     * Creates a new derived map from the specified base map.
+     * Creates a new derived map from the specified storage map.
      *
-     * @param base           The base map.
+     * @param storage        The map which actually store the entries.
      * @param keyConverter   The converter for the keys.
      * @param valueConverter The converter for the values.
      */
-    private DerivedMap(final Map<BK,BV> base,
-                       final ObjectConverter<BK,K> keyConverter,
-                       final ObjectConverter<BV,V> valueConverter)
+    private DerivedMap(final Map<SK,SV> storage,
+                       final ObjectConverter<SK,K> keyConverter,
+                       final ObjectConverter<SV,V> valueConverter)
     {
-        this.base           = base;
+        this.storage        = storage;
         this.keyConverter   = keyConverter;
         this.valueConverter = valueConverter;
     }
@@ -161,7 +162,7 @@ class DerivedMap<BK,BV,K,V> extends Abst
      */
     @Override
     public boolean isEmpty() {
-        return base.isEmpty() || keySet().isEmpty();
+        return storage.isEmpty() || keySet().isEmpty();
     }
 
     /**
@@ -172,116 +173,127 @@ class DerivedMap<BK,BV,K,V> extends Abst
      * @return previous value associated with specified key, or {@code null}
      *         if there was no mapping for key.
      * @throws UnsupportedOperationException if the converters are not invertible,
-     *         or the {@linkplain #base} map doesn't supports the {@code put} operation.
+     *         or the {@linkplain #storage} map doesn't supports the {@code put} operation.
      */
     @Override
     public V put(final K key, final V value) throws UnsupportedOperationException {
-        ArgumentChecks.ensureNonNull("key", key);
-        return valueConverter.convert(base.put(
-                 keyConverter.inverse().convert(key),
-               valueConverter.inverse().convert(value)));
+        return put(key, keyConverter.inverse().convert(key),
+                      valueConverter.inverse().convert(value));
+    }
+
+    /**
+     * Implementation of the {@link #put(Object,Object)} method storing the given converted entry
+     * to the storage map. The {@code original} key is used only for formatting an error message
+     * in case of failure.
+     */
+    final V put(final K original, final SK key, final SV value) {
+        if (key == null) {
+            throw new UnconvertibleObjectException(Errors.format(
+                    Errors.Keys.IllegalArgumentValue_2, "key", original));
+        }
+        return valueConverter.convert(storage.put(key, value));
     }
 
     /**
      * A {@link DerivedMap} used when the {@link #keyConverter} is invertible.
      * Availability of the inverse conversion allows us to delegate some operations
-     * to the {@linkplain #base} map instead than iterating over all entries.
+     * to the {@linkplain #storage} map instead than iterating over all entries.
      */
-    private static class InvertibleKey<BK,BV,K,V> extends DerivedMap<BK,BV,K,V> {
+    private static class InvertibleKey<SK,SV,K,V> extends DerivedMap<SK,SV,K,V> {
         private static final long serialVersionUID = -7770446176017835821L;
 
         /** The inverse of {@link #keyConverter}. */
-        protected final ObjectConverter<K,BK> keyInverse;
+        protected final ObjectConverter<K,SK> keyInverse;
 
-        InvertibleKey(final Map<BK,BV> base,
-                      final ObjectConverter<BK,K> keyConverter,
-                      final ObjectConverter<BV,V> valueConverter)
+        InvertibleKey(final Map<SK,SV> storage,
+                      final ObjectConverter<SK,K> keyConverter,
+                      final ObjectConverter<SV,V> valueConverter)
         {
-            super(base, keyConverter, valueConverter);
+            super(storage, keyConverter, valueConverter);
             keyInverse = keyConverter.inverse();
         }
 
         @Override
         public final V get(final Object key) {
             final Class<K> type = keyConverter.getTargetClass();
-            return type.isInstance(key) ? valueConverter.convert(base.get(keyInverse.convert(type.cast(key)))) : null;
+            return type.isInstance(key) ? valueConverter.convert(storage.get(keyInverse.convert(type.cast(key)))) : null;
         }
 
         @Override
         public final V remove(final Object key) throws UnsupportedOperationException {
             final Class<K> type = keyConverter.getTargetClass();
-            return type.isInstance(key) ? valueConverter.convert(base.remove(keyInverse.convert(type.cast(key)))) : null;
+            return type.isInstance(key) ? valueConverter.convert(storage.remove(keyInverse.convert(type.cast(key)))) : null;
         }
 
         @Override
         public final boolean containsKey(final Object key) {
             final Class<K> type = keyConverter.getTargetClass();
-            return type.isInstance(key) && base.containsKey(keyInverse.convert(type.cast(key)));
+            return type.isInstance(key) && storage.containsKey(keyInverse.convert(type.cast(key)));
         }
     }
 
     /**
      * A {@link DerivedMap} used when the {@link #valueConverter} is invertible.
      * Availability of the inverse conversion allows us to delegate some operations
-     * to the {@linkplain #base} map instead than iterating over all entries.
+     * to the {@linkplain #storage} map instead than iterating over all entries.
      */
-    private static final class InvertibleValue<BK,BV,K,V> extends DerivedMap<BK,BV,K,V> {
+    private static final class InvertibleValue<SK,SV,K,V> extends DerivedMap<SK,SV,K,V> {
         private static final long serialVersionUID = 6249800498911409046L;
 
         /** The inverse of {@link #valueConverter}. */
-        private final ObjectConverter<V,BV> valueInverse;
+        private final ObjectConverter<V,SV> valueInverse;
 
-        InvertibleValue(final Map<BK,BV> base,
-                        final ObjectConverter<BK,K> keyConverter,
-                        final ObjectConverter<BV,V> valueConverter)
+        InvertibleValue(final Map<SK,SV> storage,
+                        final ObjectConverter<SK,K> keyConverter,
+                        final ObjectConverter<SV,V> valueConverter)
         {
-            super(base, keyConverter, valueConverter);
+            super(storage, keyConverter, valueConverter);
             valueInverse = valueConverter.inverse();
         }
 
         @Override
         public boolean containsValue(final Object value) {
             final Class<V> type = valueConverter.getTargetClass();
-            return type.isInstance(value) && base.containsValue(valueInverse.convert(type.cast(value)));
+            return type.isInstance(value) && storage.containsValue(valueInverse.convert(type.cast(value)));
         }
     }
 
     /**
      * A {@link DerivedMap} used when both the {@link #keyConverter} and {@link #valueConverter}
      * are invertible. Availability of the inverse conversion allows us to delegate some operations
-     * to the {@linkplain #base} map instead than iterating over all entries.
+     * to the {@linkplain #storage} map instead than iterating over all entries.
      */
-    private static final class Invertible<BK,BV,K,V> extends InvertibleKey<BK,BV,K,V> {
+    private static final class Invertible<SK,SV,K,V> extends InvertibleKey<SK,SV,K,V> {
         private static final long serialVersionUID = 3830322680676020356L;
 
         /** The inverse of {@link #valueConverter}. */
-        private final ObjectConverter<V,BV> valueInverse;
+        private final ObjectConverter<V,SV> valueInverse;
 
         /** The inverse of this entry converter. */
-        private transient ObjectConverter<Entry<K,V>, Entry<BK,BV>> inverse;
+        private transient ObjectConverter<Entry<K,V>, Entry<SK,SV>> inverse;
 
-        Invertible(final Map<BK,BV> base,
-                   final ObjectConverter<BK,K> keyConverter,
-                   final ObjectConverter<BV,V> valueConverter)
+        Invertible(final Map<SK,SV> storage,
+                   final ObjectConverter<SK,K> keyConverter,
+                   final ObjectConverter<SV,V> valueConverter)
         {
-            super(base, keyConverter, valueConverter);
+            super(storage, keyConverter, valueConverter);
             valueInverse = valueConverter.inverse();
         }
 
         @Override
         public boolean containsValue(final Object value) {
             final Class<V> type = valueConverter.getTargetClass();
-            return type.isInstance(value) && base.containsValue(valueInverse.convert(type.cast(value)));
+            return type.isInstance(value) && storage.containsValue(valueInverse.convert(type.cast(value)));
         }
 
         @Override
         public V put(final K key, final V value) {
-            ArgumentChecks.ensureNonNull("key", key);
-            return valueConverter.convert(base.put(keyInverse.convert(key), valueInverse.convert(value)));
+            return put(key, keyInverse.convert(key),
+                          valueInverse.convert(value));
         }
 
         @Override
-        public ObjectConverter<Entry<K,V>, Entry<BK,BV>> inverse() {
+        public ObjectConverter<Entry<K,V>, Entry<SK,SV>> inverse() {
             if (inverse == null) {
                 inverse = new DerivedMap<>(null, keyInverse, valueInverse);
             }
@@ -295,7 +307,7 @@ class DerivedMap<BK,BV,K,V> extends Abst
     @Override
     public final Set<K> keySet() {
         if (keySet == null) {
-            keySet = DerivedSet.create(base.keySet(), keyConverter);
+            keySet = DerivedSet.create(storage.keySet(), keyConverter);
         }
         return keySet;
     }
@@ -306,7 +318,7 @@ class DerivedMap<BK,BV,K,V> extends Abst
     @Override
     public final Set<Map.Entry<K,V>> entrySet() {
         if (entrySet == null) {
-            entrySet = DerivedSet.create(base.entrySet(), this);
+            entrySet = DerivedSet.create(storage.entrySet(), this);
         }
         return entrySet;
     }
@@ -332,7 +344,7 @@ class DerivedMap<BK,BV,K,V> extends Abst
      */
     @Override
     @SuppressWarnings({"unchecked","rawtypes"})
-    public final Class<Entry<BK,BV>> getSourceClass() {
+    public final Class<Entry<SK,SV>> getSourceClass() {
         return (Class) Entry.class;
     }
 
@@ -350,7 +362,7 @@ class DerivedMap<BK,BV,K,V> extends Abst
      * Converts the given entry.
      */
     @Override
-    public final Entry<K,V> convert(final Entry<BK,BV> entry) {
+    public final Entry<K,V> convert(final Entry<SK,SV> entry) {
         final K key   =   keyConverter.convert(entry.getKey());
         final V value = valueConverter.convert(entry.getValue());
         return (key != null) ? new SimpleEntry<>(key, value) : null;
@@ -360,7 +372,7 @@ class DerivedMap<BK,BV,K,V> extends Abst
      * To be defined in the {@link Invertible} sub-class only.
      */
     @Override
-    public ObjectConverter<Entry<K,V>, Entry<BK,BV>> inverse() throws UnsupportedOperationException {
+    public ObjectConverter<Entry<K,V>, Entry<SK,SV>> inverse() throws UnsupportedOperationException {
         throw new UnsupportedOperationException();
     }
 }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java?rev=1404883&r1=1404882&r2=1404883&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java Fri Nov  2 06:55:39 2012
@@ -22,8 +22,9 @@ import java.util.AbstractSet;
 import java.io.Serializable;
 import org.apache.sis.util.Decorator;
 import org.apache.sis.util.ObjectConverter;
-import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.math.FunctionProperty;
+import org.apache.sis.util.UnconvertibleObjectException;
+import org.apache.sis.util.resources.Errors;
 
 
 /**
@@ -39,21 +40,21 @@ import org.apache.sis.math.FunctionPrope
  * {@section Constraints}
  * <ul>
  *   <li>This set does not support {@code null} values, since {@code null} is used as a
- *       sentinel value when no mapping from {@linkplain #base} to {@code this} exists.</li>
- *   <li>Instances of this class are serializable if their underlying {@linkplain #base} set
+ *       sentinel value when no mapping from {@linkplain #storage} to {@code this} exists.</li>
+ *   <li>Instances of this class are serializable if their underlying {@linkplain #storage} set
  *       and the {@linkplain #converter} are serializable.</li>
  *   <li>This class performs no synchronization by itself. Nevertheless instances of this class
  *       may be thread-safe (depending on the sub-class implementation) if the underlying
- *       {@linkplain #base} set (including its iterator) and the {@linkplain #converter}
+ *       {@linkplain #storage} set (including its iterator) and the {@linkplain #converter}
  *       are thread-safe.</li>
  * </ul>
  *
  * {@section Performance considerations}
- * This class does not cache any value, since the {@linkplain #base} set is presumed modifiable.
- * If the base set is known to be immutable, then sub-classes may consider to cache some values,
+ * This class does not cache any value, since the {@linkplain #storage} set is presumed modifiable.
+ * If the storage set is known to be immutable, then sub-classes may consider to cache some values,
  * especially the result of the {@link #size()} method.
  *
- * @param <B> The type of elements in the backing set.
+ * @param <S> The type of elements in the storage set.
  * @param <E> The type of elements in this set.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
@@ -62,47 +63,47 @@ import org.apache.sis.math.FunctionPrope
  * @module
  */
 @Decorator(Set.class)
-class DerivedSet<B,E> extends AbstractSet<E> implements CheckedContainer<E>, Serializable {
+class DerivedSet<S,E> extends AbstractSet<E> implements CheckedContainer<E>, Serializable {
     /**
      * Serial number for inter-operability with different versions.
      */
     private static final long serialVersionUID = -4662336508586424581L;
 
     /**
-     * The base set whose values are derived from.
+     * The storage set whose values are derived from.
      */
-    protected final Set<B> base;
+    protected final Set<S> storage;
 
     /**
-     * The converter from the base to the derived type.
+     * The converter from the storage to the derived type.
      */
-    protected final ObjectConverter<B,E> converter;
+    protected final ObjectConverter<S,E> converter;
 
     /**
-     * Creates a new derived set from the specified base set.
+     * Creates a new derived set from the specified storage set.
      *
-     * @param base      The base set.
-     * @param converter The converter from the type in the base set to the type in the derived set.
+     * @param storage   The set which actually store the elements.
+     * @param converter The converter from the type in the storage set to the type in the derived set.
      */
-    static <B,E> Set<E> create(final Set<B> base, final ObjectConverter<B,E> converter) {
+    static <S,E> Set<E> create(final Set<S> storage, final ObjectConverter<S,E> converter) {
         final Set<FunctionProperty> properties = converter.properties();
         if (properties.contains(FunctionProperty.INVERTIBLE)) {
             if (FunctionProperty.isBijective(properties)) {
-                return new Bijective<>(base, converter);
+                return new Bijective<>(storage, converter);
             }
-            return new Invertible<>(base, converter);
+            return new Invertible<>(storage, converter);
         }
-        return new DerivedSet<>(base, converter);
+        return new DerivedSet<>(storage, converter);
     }
 
     /**
-     * Creates a new derived set from the specified base set.
+     * Creates a new derived set from the specified storage set.
      *
-     * @param base The base set.
+     * @param storage   The set which actually store the elements.
      * @param converter The type of elements in this derived set.
      */
-    private DerivedSet(final Set<B> base, final ObjectConverter<B,E> converter) {
-        this.base      = base;
+    private DerivedSet(final Set<S> storage, final ObjectConverter<S,E> converter) {
+        this.storage   = storage;
         this.converter = converter;
     }
 
@@ -122,14 +123,14 @@ class DerivedSet<B,E> extends AbstractSe
      */
     @Override
     public final Iterator<E> iterator() {
-        return new DerivedIterator<>(base.iterator(), converter);
+        return new DerivedIterator<>(storage.iterator(), converter);
     }
 
     /**
      * Returns the number of elements in this set. The default implementation counts
      * the number of elements returned by the {@link #iterator() iterator}.
      * Subclasses are encouraged to cache this value if they know that the
-     * {@linkplain #base} set is immutable.
+     * {@linkplain #storage} set is immutable.
      *
      * @return the number of elements in this set.
      */
@@ -150,56 +151,68 @@ class DerivedSet<B,E> extends AbstractSe
      */
     @Override
     public boolean isEmpty() {
-        return !base.isEmpty() || !iterator().hasNext();
+        return !storage.isEmpty() || !iterator().hasNext();
     }
 
     /**
      * Ensures that this set contains the specified element.
      * This method first checks if the given element is non-null,
-     * then delegates to the {@link #base} set like below:
+     * then delegates to the {@link #storage} set like below:
      *
      * {@preformat java
-     *     return base.add(inverse.convert(element));
+     *     return storage.add(inverse.convert(element));
      * }
      *
      * @param  element element whose presence in this set is to be ensured.
      * @return {@code true} if the set changed as a result of the call.
-     * @throws UnsupportedOperationException if the {@linkplain #base} set doesn't
+     * @throws UnsupportedOperationException if the {@linkplain #storage} set doesn't
      *         supports the {@code add} operation.
      */
     @Override
     public boolean add(final E element) throws UnsupportedOperationException {
-        ArgumentChecks.ensureNonNull("element", element);
-        return base.add(converter.inverse().convert(element));
+        return add(element, converter.inverse().convert(element));
+    }
+
+    /**
+     * Implementation of the {@link #add(Object)} method adding the given converted value
+     * to the storage set. The {@code original} value is used only for formatting an error
+     * message in case of failure.
+     */
+    final boolean add(final E original, final S element) {
+        if (element == null) {
+            throw new UnconvertibleObjectException(Errors.format(
+                    Errors.Keys.IllegalArgumentValue_2, "element", original));
+        }
+        return storage.add(element);
     }
 
     /**
      * A {@link DerivedSet} for invertible converters. Availability of the inverse conversion
      * allows us to delegate the {@link #contains(Object)} and {@linkplain #remove(Object)}
-     * operations to the {@linkplain #base} set instead than iterating over all elements.
+     * operations to the {@linkplain #storage} set instead than iterating over all elements.
      *
-     * @param <B> The type of elements in the backing set.
+     * @param <S> The type of elements in the storage set.
      * @param <E> The type of elements in this set.
      */
-    private static class Invertible<B,E> extends DerivedSet<B,E> {
+    private static class Invertible<S,E> extends DerivedSet<S,E> {
         /**
          * For cross-version compatibility.
          */
         private static final long serialVersionUID = 5957167307119709856L;
 
         /**
-         * The converter from the derived to the base type.
+         * The converter from the derived to the storage type.
          */
-        private final ObjectConverter<E,B> inverse;
+        private final ObjectConverter<E,S> inverse;
 
         /**
-         * Creates a new derived set from the specified base set.
+         * Creates a new derived set from the specified storage set.
          *
-         * @param base The base set.
+         * @param storage   The set which actually store the elements.
          * @param converter The type of elements in this derived set.
          */
-        Invertible(final Set<B> base, final ObjectConverter<B,E> converter) {
-            super(base, converter);
+        Invertible(final Set<S> storage, final ObjectConverter<S,E> converter) {
+            super(storage, converter);
             inverse = converter.inverse();
         }
 
@@ -208,17 +221,16 @@ class DerivedSet<B,E> extends AbstractSe
          */
         @Override
         public final boolean add(final E element) throws UnsupportedOperationException {
-            ArgumentChecks.ensureNonNull("element", element);
-            return base.add(inverse.convert(element));
+            return add(element, inverse.convert(element));
         }
 
         /**
          * Returns {@code true} if this set contains the specified element.
          * This method first checks if the given element is an instance of {@link #getElementType()},
-         * then delegates to the {@link #base} set like below:
+         * then delegates to the {@link #storage} set like below:
          *
          * {@preformat java
-         *     return base.contains(inverse.convert(element));
+         *     return storage.contains(inverse.convert(element));
          * }
          *
          * @param  element object to be checked for containment in this set.
@@ -227,52 +239,52 @@ class DerivedSet<B,E> extends AbstractSe
         @Override
         public final boolean contains(final Object element) {
             final Class<? extends E> type = getElementType();
-            return type.isInstance(element) && base.contains(inverse.convert(type.cast(element)));
+            return type.isInstance(element) && storage.contains(inverse.convert(type.cast(element)));
         }
 
         /**
          * Removes a single instance of the specified element from this set.
          * This method first checks if the given element is an instance of {@link #getElementType},
-         * then delegates to the {@link #base} set like below:
+         * then delegates to the {@link #storage} set like below:
          *
          * {@preformat java
-         *     return base.remove(inverse.convert(element));
+         *     return storage.remove(inverse.convert(element));
          * }
          *
          * @param  element element to be removed from this set, if present.
          * @return {@code true} if the set contained the specified element.
-         * @throws UnsupportedOperationException if the {@linkplain #base} set doesn't
+         * @throws UnsupportedOperationException if the {@linkplain #storage} set doesn't
          *         supports the {@code remove} operation.
          */
         @Override
         public final boolean remove(final Object element) throws UnsupportedOperationException {
             final Class<? extends E> type = getElementType();
-            return type.isInstance(element) && base.remove(inverse.convert(type.cast(element)));
+            return type.isInstance(element) && storage.remove(inverse.convert(type.cast(element)));
         }
     }
 
     /**
      * A {@link DerivedSet} for converters that are both invertible and bijective.
-     * The bijection allows us to query the {@linkplai #base} set size directly
+     * The bijection allows us to query the {@linkplai #storage} set size directly
      * instead than iterating over all elements.
      *
-     * @param <B> The type of elements in the backing set.
+     * @param <S> The type of elements in the storage set.
      * @param <E> The type of elements in this set.
      */
-    private static final class Bijective<B,E> extends Invertible<B,E> {
+    private static final class Bijective<S,E> extends Invertible<S,E> {
         /**
          * For cross-version compatibility.
          */
         private static final long serialVersionUID = -7601944988804380342L;
 
         /**
-         * Creates a new derived set from the specified base set.
+         * Creates a new derived set from the specified storage set.
          *
-         * @param base The base set.
+         * @param storage   The set which actually store the elements.
          * @param converter The type of elements in this derived set.
          */
-        Bijective(final Set<B> base, final ObjectConverter<B,E> converter) {
-            super(base, converter);
+        Bijective(final Set<S> storage, final ObjectConverter<S,E> converter) {
+            super(storage, converter);
         }
 
         /**
@@ -280,7 +292,7 @@ class DerivedSet<B,E> extends AbstractSe
          */
         @Override
         public int size() {
-            return base.size();
+            return storage.size();
         }
 
         /**
@@ -288,7 +300,7 @@ class DerivedSet<B,E> extends AbstractSe
          */
         @Override
         public boolean isEmpty() {
-            return base.isEmpty();
+            return storage.isEmpty();
         }
     }
 }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/WeakEntry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/WeakEntry.java?rev=1404883&r1=1404882&r2=1404883&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/WeakEntry.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/WeakEntry.java Fri Nov  2 06:55:39 2012
@@ -23,6 +23,7 @@ import java.lang.ref.WeakReference;
 import java.lang.reflect.Array;
 
 import org.apache.sis.util.Disposable;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Messages;
 import org.apache.sis.internal.util.ReferenceQueueConsumer;
 import org.apache.sis.math.MathFunctions;
@@ -61,6 +62,11 @@ abstract class WeakEntry<E> extends Weak
     static final long REHASH_DELAY = 4000000000L;
 
     /**
+     * The logger where to logs collection events, if logging at the finest level is enabled.
+     */
+    private static final Logger LOGGER = Logging.getLogger(WeakEntry.class);
+
+    /**
      * The next entry, or {@code null} if there is none.
      */
     WeakEntry<E> next;
@@ -166,14 +172,13 @@ abstract class WeakEntry<E> extends Weak
         /*
          * We are done. Log the operation if logging is enabled at that level.
          */
-        final Logger logger = Collections.LOGGER;
-        if (logger.isLoggable(Level.FINEST)) {
+        if (LOGGER.isLoggable(Level.FINEST)) {
             final LogRecord record = Messages.getResources(null).getLogRecord(Level.FINEST,
                     Messages.Keys.ChangedContainerCapacity_2, oldTable.length, table.length);
             record.setSourceMethodName(callerMethod);
             record.setSourceClassName(entryType.getEnclosingClass().getName());
-            record.setLoggerName(logger.getName());
-            logger.log(record);
+            record.setLoggerName(LOGGER.getName());
+            LOGGER.log(record);
         }
         return table;
     }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java?rev=1404883&r1=1404882&r2=1404883&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/package-info.java Fri Nov  2 06:55:39 2012
@@ -44,9 +44,9 @@
  *     a hook for making the collections read-only and allow the caller to specify the synchronization
  *     lock of his choice.
  *   </li><li>
- *     {@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.
+ *     {@linkplain org.apache.sis.util.collection.Collections#derivedMap Derived Map} and
+ *     {@linkplain org.apache.sis.util.collection.Collections#derivedSet derived Set} are wrapper collections
+ *     in which the keys or the values are derived on-the-fly from the content of an other collection.
  *   </li><li>
  *     {@link org.apache.sis.util.collection.IntegerList} and
  *     {@link org.apache.sis.util.collection.RangeSet} are collections specialized for a particular kind



Mime
View raw message