sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1597136 [2/2] - in /sis/branches/JDK6: ./ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/test/java/org/apache/sis/feature/ core/sis-feature/src/test/java/org/apache/sis/test/suite/ core/sis-referencing/src/main...
Date Fri, 23 May 2014 17:36:14 GMT
Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTypeTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTypeTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTypeTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -42,6 +42,15 @@ public final strictfp class DefaultAttri
     /**
      * Creates an attribute type for city name.
      *
+     * @return An attribute type for a city name.
+     */
+    public static DefaultAttributeType<String> city() {
+        return city(new HashMap<String,Object>());
+    }
+
+    /**
+     * Implementation of {@link #city()} using the given map (for reusing existing objects).
+     *
      * @param identification An empty temporary map (provided only for recycling existing instances).
      */
     static DefaultAttributeType<String> city(final Map<String,Object> identification) {
@@ -66,6 +75,8 @@ public final strictfp class DefaultAttri
      */
     static DefaultAttributeType<Integer> population(final Map<String,Object> identification) {
         assertNull(identification.put(DefaultAttributeType.NAME_KEY, "population"));
+        // We may add more properties here in a future version.
+
         final DefaultAttributeType<Integer> population = new DefaultAttributeType<Integer>(
                 identification, Integer.class, 1, 1, null);
         identification.clear();
@@ -74,10 +85,27 @@ public final strictfp class DefaultAttri
 
     /**
      * Creates an attribute type for a parliament name.
+     * This applies only to features of type "Capital".
+     * This is used for testing feature type inheritance.
+     *
+     * @return An attribute type for the name of the parliament in a capital.
+     */
+    public static DefaultAttributeType<String> parliament() {
+        return new DefaultAttributeType<String>(
+                singletonMap(DefaultAttributeType.NAME_KEY, "parliament"),
+                String.class, 1, 1, null);
+    }
+
+    /**
+     * Creates an attribute type for a list of universities.
+     * The cardinality is [0 … ∞].
+     *
+     * @return An attribute type for university names.
      */
-    static DefaultAttributeType<String> parliament() {
-        return new DefaultAttributeType<String>(singletonMap(DefaultAttributeType.NAME_KEY, "parliament"),
-                        String.class, 1, 1, null);
+    public static DefaultAttributeType<String> universities() {
+        return new DefaultAttributeType<String>(
+                singletonMap(DefaultAttributeType.NAME_KEY, "universities"),
+                String.class, 0, Integer.MAX_VALUE, null);
     }
 
     /**
@@ -85,7 +113,7 @@ public final strictfp class DefaultAttri
      */
     @Test
     public void testMandatorySingleton() {
-        final DefaultAttributeType<String> city = city(new HashMap<String,Object>());
+        final DefaultAttributeType<String> city = city();
         final GenericName name = city.getName();
         assertInstanceOf("city.name", LocalName.class, name);
         assertEquals("city.name", "city", name.toString());
@@ -129,7 +157,7 @@ public final strictfp class DefaultAttri
     @Test
     @DependsOnMethod("testEquals")
     public void testSerialization() {
-        final DefaultAttributeType<String> attribute = city(new HashMap<String,Object>(4));
+        final DefaultAttributeType<String> attribute = city();
         assertSerializedEquals(attribute);
     }
 
@@ -138,7 +166,7 @@ public final strictfp class DefaultAttri
      */
     @Test
     public void testToString() {
-        final DefaultAttributeType<String> city = city(new HashMap<String,Object>());
+        final DefaultAttributeType<String> city = city();
         assertEquals("AttributeType[“city” : String]", city.toString());
     }
 }

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -63,6 +63,23 @@ public final strictfp class DefaultFeatu
     }
 
     /**
+     * Creates a sub-type of the "city" type with only one additional property, an arbitrary amount of strings.
+     * The feature contains the following attribute:
+     *
+     * <ul>
+     *   <li>{@code city}         as a  {@link String}  (mandatory)</li>
+     *   <li>{@code population}   as an {@link Integer} (mandatory)</li>
+     *   <li>{@code universities} as an arbitrary amount of {@link String}</li>
+     * </ul>
+     *
+     * @return The feature for an university city.
+     */
+    public static DefaultFeatureType universityCity() {
+        return new DefaultFeatureType(singletonMap(DefaultFeatureType.NAME_KEY, "University city"), false,
+                new DefaultFeatureType[] {city()}, DefaultAttributeTypeTest.universities());
+    }
+
+    /**
      * Creates a sub-type of the "city" type with only one additional property, a string giving the parliament name.
      * The feature contains the following attribute:
      *
@@ -106,19 +123,21 @@ public final strictfp class DefaultFeatu
 
     /**
      * Creates a sub-type of the "metropolis" type with the "region" attribute overridden to
-     * {@link InternationalString}.
+     * {@link InternationalString} and an arbitrary amount of universities.
      */
     static DefaultFeatureType worldMetropolis() {
-        return worldMetropolis(metropolis(), InternationalString.class);
+        return worldMetropolis(metropolis(), universityCity(), InternationalString.class);
     }
 
     /**
      * Creates a sub-type of the "metropolis" type with the "region" attribute overridden to the given type.
      * The given type should be {@link InternationalString}, but we allow other type for testing argument checks.
      */
-    private static <T> DefaultFeatureType worldMetropolis(final DefaultFeatureType metropolis, final Class<T> regionType) {
+    private static <T> DefaultFeatureType worldMetropolis(final DefaultFeatureType metropolis,
+            final DefaultFeatureType universityCity, final Class<T> regionType)
+    {
         return new DefaultFeatureType(singletonMap(DefaultFeatureType.NAME_KEY, "World metropolis"), false,
-                new DefaultFeatureType[] {metropolis},
+                new DefaultFeatureType[] {metropolis, universityCity},
                 new DefaultAttributeType<T>(singletonMap(DefaultAttributeType.NAME_KEY, "region"),
                         regionType, 1, 1, null));
 
@@ -359,26 +378,27 @@ public final strictfp class DefaultFeatu
     @Test
     @DependsOnMethod({"testMultiInheritance", "testNameCollision"})
     public void testPropertyOverride() {
-        final DefaultFeatureType metropolis = metropolis();
+        final DefaultFeatureType metropolis     = metropolis();
+        final DefaultFeatureType universityCity = universityCity();
         try {
-            worldMetropolis(metropolis, Integer.class);
+            worldMetropolis(metropolis, universityCity, Integer.class);
             fail("Shall not be allowed to override a 'CharSequence' attribute with an 'Integer' one.");
         } catch (IllegalArgumentException e) {
             final String message = e.getMessage();
             assertTrue(message, message.contains("region"));
             assertTrue(message, message.contains("Metropolis"));
         }
-        final DefaultFeatureType worldMetropolis = worldMetropolis(metropolis, InternationalString.class);
+        final DefaultFeatureType worldMetropolis = worldMetropolis(metropolis, universityCity, InternationalString.class);
         assertUnmodifiable(worldMetropolis);
         assertEquals     ("name", "World metropolis", worldMetropolis.getName().toString());
-        assertArrayEquals("superTypes", new Object[] {metropolis}, worldMetropolis.getSuperTypes().toArray());
+        assertArrayEquals("superTypes", new Object[] {metropolis, universityCity}, worldMetropolis.getSuperTypes().toArray());
         assertFalse      ("isAbstract",      worldMetropolis.isAbstract());
         assertFalse      ("isSparse",        worldMetropolis.isSparse());
-        assertTrue       ("isSimple",        worldMetropolis.isSimple());
-        assertEquals     ("instanceSize", 4, worldMetropolis.indices().size());
+        assertFalse      ("isSimple",        worldMetropolis.isSimple()); // Because of the arbitrary amount of universities.
+        assertEquals     ("instanceSize", 5, worldMetropolis.indices().size());
 
         assertPropertiesEquals(worldMetropolis, false, "region");
-        assertPropertiesEquals(worldMetropolis, true, "city", "population", "region", "isGlobal");
+        assertPropertiesEquals(worldMetropolis, true, "city", "population", "region", "isGlobal", "universities");
         assertEquals("property(“region”).valueClass", InternationalString.class,
                 ((DefaultAttributeType) worldMetropolis.getProperty("region")).getValueClass());
 

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultOperationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultOperationTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultOperationTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultOperationTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.feature;
 
-import java.util.HashMap;
 import org.opengis.parameter.ParameterDescriptor;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.test.DependsOn;
@@ -35,7 +34,7 @@ import static org.apache.sis.test.Assert
  * @version 0.5
  * @module
  */
-@DependsOn(DefaultAttributeTest.class)
+@DependsOn(SingletonAttributeTest.class)
 public final strictfp class DefaultOperationTest extends TestCase {
     /**
      * Returns an operation that found new cities.
@@ -47,7 +46,7 @@ public final strictfp class DefaultOpera
         };
         return new DefaultOperation(singletonMap(DefaultOperation.NAME_KEY, "found city"),
                 builder.addName("found city").createGroup(parameters),
-                DefaultAttributeTypeTest.city(new HashMap<String,Object>(4)));
+                DefaultAttributeTypeTest.city());
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DenseFeatureTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DenseFeatureTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DenseFeatureTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/DenseFeatureTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -21,6 +21,7 @@ import org.apache.sis.test.DependsOn;
 
 /**
  * Tests {@link DenseFeature}.
+ * This class inherits all tests defined in {@link FeatureTestCase}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
@@ -29,7 +30,7 @@ import org.apache.sis.test.DependsOn;
  */
 @DependsOn({
     DefaultFeatureTypeTest.class,
-    DefaultAttributeTest.class,
+    SingletonAttributeTest.class,
     PropertySingletonTest.class
 })
 public final strictfp class DenseFeatureTest extends FeatureTestCase {
@@ -41,5 +42,13 @@ public final strictfp class DenseFeature
         return new DenseFeature(type);
     }
 
+    /**
+     * Clones the {@link #feature} instance.
+     */
+    @Override
+    final AbstractFeature cloneFeature() throws CloneNotSupportedException {
+        return ((DenseFeature) feature).clone();
+    }
+
     // Inherit all tests from the super-class.
 }

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -41,18 +41,19 @@ public final strictfp class FeatureForma
      */
     @Test
     public void testFeatureType() {
-        final DefaultFeatureType feature = DefaultFeatureTypeTest.metropolis();
+        final DefaultFeatureType feature = DefaultFeatureTypeTest.worldMetropolis();
         final FeatureFormat format = new FeatureFormat(Locale.US, null);
         final String text = format.format(feature);
-        assertMultilinesEquals("Metropolis\n" +
-                "┌────────────┬──────────────┬─────────────┬───────────────┐\n" +
-                "│ Name       │ Type         │ Cardinality │ Default value │\n" +
-                "├────────────┼──────────────┼─────────────┼───────────────┤\n" +
-                "│ city       │ String       │ [1 … 1]     │ Utopia        │\n" +
-                "│ population │ Integer      │ [1 … 1]     │               │\n" +
-                "│ region     │ CharSequence │ [1 … 1]     │               │\n" +
-                "│ isGlobal   │ Boolean      │ [1 … 1]     │               │\n" +
-                "└────────────┴──────────────┴─────────────┴───────────────┘\n", text);
+        assertMultilinesEquals("World metropolis\n" +
+                "┌──────────────┬─────────────────────┬─────────────┬───────────────┐\n" +
+                "│ Name         │ Type                │ Cardinality │ Default value │\n" +
+                "├──────────────┼─────────────────────┼─────────────┼───────────────┤\n" +
+                "│ city         │ String              │ [1 … 1]     │ Utopia        │\n" +
+                "│ population   │ Integer             │ [1 … 1]     │               │\n" +
+                "│ region       │ InternationalString │ [1 … 1]     │               │\n" +
+                "│ isGlobal     │ Boolean             │ [1 … 1]     │               │\n" +
+                "│ universities │ String              │ [0 … ∞]     │               │\n" +
+                "└──────────────┴─────────────────────┴─────────────┴───────────────┘\n", text);
     }
 
     /**
@@ -70,7 +71,7 @@ public final strictfp class FeatureForma
                 "├────────────┼─────────┼─────────────┼───────────┤\n" +
                 "│ city       │ String  │ [1 … 1]     │ Paderborn │\n" +
                 "│ population │ Integer │ [1 … 1]     │ 143,174   │\n" +
-                "│ twin town  │ City    │ [0 … ∞]     │ Le Mans   │\n" +
+                "│ twin town  │ City    │ [0 … 1]     │ Le Mans   │\n" +
                 "└────────────┴─────────┴─────────────┴───────────┘\n", text);
     }
 }

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java [UTF-8] Fri May 23 17:36:12 2014
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.feature;
 
+import java.util.Collection;
+import java.util.Collections;
 import org.opengis.metadata.quality.DataQuality;
 import org.opengis.metadata.quality.Element;
 import org.opengis.metadata.quality.Result;
@@ -43,7 +45,7 @@ public abstract strictfp class FeatureTe
     /**
      * The feature being tested.
      */
-    private AbstractFeature feature;
+    AbstractFeature feature;
 
     /**
      * {@code true} if {@link #getAttributeValue(String)} should invoke {@link AbstractFeature#getProperty(String)},
@@ -84,19 +86,31 @@ public abstract strictfp class FeatureTe
     abstract AbstractFeature createFeature(final DefaultFeatureType type);
 
     /**
+     * Clones the {@link #feature} instance.
+     */
+    abstract AbstractFeature cloneFeature() throws CloneNotSupportedException;
+
+    /**
      * Returns the attribute value of the current {@link #feature} for the given name.
      */
     private Object getAttributeValue(final String name) {
         final Object value = feature.getPropertyValue(name);
         if (getValuesFromProperty) {
-            final Property property = (Property) feature.getProperty(name);
-            assertInstanceOf(name, DefaultAttribute.class, property);
+            final AbstractAttribute<?> property = (AbstractAttribute<?>) feature.getProperty(name);
 
             // The AttributeType shall be the same than the one provided by FeatureType for the given name.
-            assertSame(name, feature.getType().getProperty(name), ((DefaultAttribute<?>) property).getType());
+            assertSame(name, feature.getType().getProperty(name), property.getType());
 
             // Attribute value shall be the same than the one provided by FeatureType convenience method.
-            assertSame(name, feature.getPropertyValue(name), ((DefaultAttribute<?>) property).getValue());
+            assertSame(name, value, property.getValue());
+
+            // Collection view shall contains the same value, or be empty.
+            final Collection<?> values = property.getValues();
+            if (value != null) {
+                assertSame(name, value, TestUtilities.getSingleton(values));
+            } else {
+                assertTrue(name, values.isEmpty());
+            }
 
             // Invoking getProperty(name) twice shall return the same Property instance.
             assertSame(name, property, feature.getProperty(name));
@@ -169,7 +183,7 @@ public abstract strictfp class FeatureTe
 
     /**
      * Tests {@link AbstractFeature#getProperty(String)} and {@link AbstractFeature#getPropertyValue(String)}
-     * on a "complex" feature, involving inheritance and property overriding.
+     * on a "complex" feature, involving multi-valued properties, inheritances and property overriding.
      */
     @Test
     @DependsOnMethod({"testSimpleValues", "testSimpleProperties"})
@@ -178,6 +192,13 @@ public abstract strictfp class FeatureTe
         setAttributeValue("city", "Utopia", "New York");
         setAttributeValue("population", null, 8405837); // Estimation for 2013.
         /*
+         * Set the attribute value on a property having [0 … ∞] cardinality.
+         * The feature implementation should put the value in a list.
+         */
+        assertEquals("universities", Collections.emptyList(), getAttributeValue("universities"));
+        feature.setPropertyValue("universities", "University of arts");
+        assertEquals("universities", Collections.singletonList("University of arts"), getAttributeValue("universities"));
+        /*
          * Switch to 'getProperty' mode only after we have set at least one value,
          * in order to test the conversion of existing values to property instances.
          */
@@ -185,6 +206,13 @@ public abstract strictfp class FeatureTe
         final SimpleInternationalString region = new SimpleInternationalString("State of New York");
         setAttributeValue("region", null, region);
         /*
+         * Adds more universities.
+         */
+        @SuppressWarnings("unchecked")
+        final Collection<String> universities = (Collection<String>) feature.getPropertyValue("universities");
+        assertTrue(universities.add("University of sciences"));
+        assertTrue(universities.add("University of international development"));
+        /*
          * In our 'metropolis' feature type, the region can be any CharSequence. But 'worldMetropolis'
          * feature type overrides the region property with a restriction to InternationalString.
          * Verifiy that this restriction is checked.
@@ -223,7 +251,7 @@ public abstract strictfp class FeatureTe
     @DependsOnMethod({"testSimpleValues", "testSimpleProperties"})
     public void testCustomAttribute() {
         feature = createFeature(DefaultFeatureTypeTest.city());
-        final DefaultAttribute<String> wrong = DefaultAttributeTest.parliament();
+        final AbstractAttribute<String> wrong = SingletonAttributeTest.parliament();
         final CustomAttribute<String> city = new CustomAttribute<String>(Features.cast(
                 (DefaultAttributeType<?>) feature.getType().getProperty("city"), String.class));
 
@@ -294,7 +322,7 @@ public abstract strictfp class FeatureTe
     private void testClone(final String property, final Object oldValue, final Object newValue)
             throws CloneNotSupportedException
     {
-        final AbstractFeature clone = feature.clone();
+        final AbstractFeature clone = cloneFeature();
         assertNotSame("clone",      clone, feature);
         assertTrue   ("equals",     clone.equals(feature));
         assertTrue   ("hashCode",   clone.hashCode() == feature.hashCode());

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeaturesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeaturesTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeaturesTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeaturesTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -31,7 +31,7 @@ import static org.junit.Assert.*;
  * @version 0.5
  * @module
  */
-@DependsOn(DefaultAttributeTest.class)
+@DependsOn(SingletonAttributeTest.class)
 public final strictfp class FeaturesTest extends TestCase {
     /**
      * Tests {@link Features#cast(AttributeType, Class)}.
@@ -56,7 +56,7 @@ public final strictfp class FeaturesTest
      */
     @Test
     public void testCastAttributeInstance() {
-        final DefaultAttribute<String> parliament = DefaultAttributeTest.parliament();
+        final AbstractAttribute<String> parliament = SingletonAttributeTest.parliament();
         assertSame(parliament, Features.cast(parliament, String.class));
         try {
             Features.cast(parliament, CharSequence.class);

Copied: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/MultiValuedAttributeTest.java (from r1597134, sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/MultiValuedAttributeTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/MultiValuedAttributeTest.java?p2=sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/MultiValuedAttributeTest.java&p1=sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/MultiValuedAttributeTest.java&r1=1597134&r2=1597136&rev=1597136&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/MultiValuedAttributeTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/MultiValuedAttributeTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -41,7 +41,7 @@ public final strictfp class MultiValuedA
      * The cardinality is [0 … ∞].
      */
     static MultiValuedAttribute<String> universities() {
-        return new MultiValuedAttribute<>(DefaultAttributeTypeTest.universities());
+        return new MultiValuedAttribute<String>(DefaultAttributeTypeTest.universities());
     }
 
     /**
@@ -49,7 +49,7 @@ public final strictfp class MultiValuedA
      * This attribute has no default value.
      */
     private static MultiValuedAttribute<Integer> population() {
-        return new MultiValuedAttribute<>(DefaultAttributeTypeTest.population(new HashMap<String,Object>(4)));
+        return new MultiValuedAttribute<Integer>(DefaultAttributeTypeTest.population(new HashMap<String,Object>(4)));
     }
 
     /**
@@ -106,7 +106,7 @@ public final strictfp class MultiValuedA
     @Test
     @DependsOnMethod("testValue")
     public void testDefaultValue() {
-        final AbstractAttribute<String> attribute = new MultiValuedAttribute<>(DefaultAttributeTypeTest.city());
+        final AbstractAttribute<String> attribute = new MultiValuedAttribute<String>(DefaultAttributeTypeTest.city());
         assertEquals     ("value",                "Utopia",  attribute.getValue());
         assertArrayEquals("values", new String[] {"Utopia"}, attribute.getValues().toArray());
 

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/PropertySingletonTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/PropertySingletonTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/PropertySingletonTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/PropertySingletonTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -18,7 +18,6 @@ package org.apache.sis.feature;
 
 import java.util.Set;
 import org.apache.sis.test.DependsOnMethod;
-import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -36,7 +35,6 @@ import static org.apache.sis.test.TestUt
  * @version 0.5
  * @module
  */
-@DependsOn(DefaultAttributeTest.class)
 public final strictfp class PropertySingletonTest extends TestCase {
     /**
      * The instance to test.
@@ -46,13 +44,13 @@ public final strictfp class PropertySing
     /**
      * The attribute wrapped by the {@link #singleton} list.
      */
-    private final DefaultAttribute<Integer> attribute;
+    private final AbstractAttribute<Integer> attribute;
 
     /**
      * Creates a new test case.
      */
     public PropertySingletonTest() {
-        attribute = new DefaultAttribute<Integer>(new DefaultAttributeType<Integer>(
+        attribute = new SingletonAttribute<Integer>(new DefaultAttributeType<Integer>(
                 singletonMap(DefaultAttributeType.NAME_KEY, "test"), Integer.class, 0, 1, null));
         singleton = new PropertySingleton<Integer>(attribute);
     }

Copied: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonAttributeTest.java (from r1597134, sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonAttributeTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonAttributeTest.java?p2=sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonAttributeTest.java&p1=sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonAttributeTest.java&r1=1597134&r2=1597136&rev=1597136&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonAttributeTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonAttributeTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -49,7 +49,7 @@ public final strictfp class SingletonAtt
      * This attribute has a default value.
      */
     static SingletonAttribute<String> city() {
-        return new SingletonAttribute<>(DefaultAttributeTypeTest.city());
+        return new SingletonAttribute<String>(DefaultAttributeTypeTest.city());
     }
 
     /**
@@ -57,7 +57,7 @@ public final strictfp class SingletonAtt
      * This attribute has no default value.
      */
     static SingletonAttribute<Integer> population() {
-        return new SingletonAttribute<>(DefaultAttributeTypeTest.population(new HashMap<String,Object>(4)));
+        return new SingletonAttribute<Integer>(DefaultAttributeTypeTest.population(new HashMap<String,Object>(4)));
     }
 
     /**
@@ -65,7 +65,7 @@ public final strictfp class SingletonAtt
      * This applies only to features of type "Capital".
      */
     static SingletonAttribute<String> parliament() {
-        return new SingletonAttribute<>(DefaultAttributeTypeTest.parliament());
+        return new SingletonAttribute<String>(DefaultAttributeTypeTest.parliament());
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/SparseFeatureTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/SparseFeatureTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/SparseFeatureTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/SparseFeatureTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -21,6 +21,7 @@ import org.apache.sis.test.DependsOn;
 
 /**
  * Tests {@link SparseFeature}.
+ * This class inherits all tests defined in {@link FeatureTestCase}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
@@ -29,7 +30,7 @@ import org.apache.sis.test.DependsOn;
  */
 @DependsOn({
     DefaultFeatureTypeTest.class,
-    DefaultAttributeTest.class,
+    SingletonAttributeTest.class,
     PropertySingletonTest.class
 })
 public final strictfp class SparseFeatureTest extends FeatureTestCase {
@@ -41,5 +42,13 @@ public final strictfp class SparseFeatur
         return new SparseFeature(type);
     }
 
+    /**
+     * Clones the {@link #feature} instance.
+     */
+    @Override
+    final AbstractFeature cloneFeature() throws CloneNotSupportedException {
+        return ((SparseFeature) feature).clone();
+    }
+
     // Inherit all tests from the super-class.
 }

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java [UTF-8] Fri May 23 17:36:12 2014
@@ -32,12 +32,13 @@ import org.junit.BeforeClass;
 @Suite.SuiteClasses({
     org.apache.sis.feature.DefaultAttributeTypeTest.class,
     org.apache.sis.feature.DefaultFeatureTypeTest.class,
-    org.apache.sis.feature.DefaultAttributeTest.class,
     org.apache.sis.feature.PropertySingletonTest.class,
+    org.apache.sis.feature.SingletonAttributeTest.class,
+    org.apache.sis.feature.MultiValuedAttributeTest.class,
     org.apache.sis.feature.DenseFeatureTest.class,
     org.apache.sis.feature.SparseFeatureTest.class,
     org.apache.sis.feature.DefaultAssociationRoleTest.class,
-    org.apache.sis.feature.DefaultAssociationTest.class,
+    org.apache.sis.feature.SingletonAssociationTest.class,
     org.apache.sis.feature.DefaultOperationTest.class,
     org.apache.sis.feature.FeatureFormatTest.class,
     org.apache.sis.feature.FeaturesTest.class

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterValueList.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterValueList.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterValueList.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterValueList.java [UTF-8] Fri May 23 17:36:12 2014
@@ -208,9 +208,10 @@ final class ParameterValueList extends A
                 count++;
             }
         }
-        if (count >= desc.getMaximumOccurs()) {
+        final int max = desc.getMaximumOccurs();
+        if (count >= max) {
             throw new InvalidParameterCardinalityException(Errors.format(
-                    Errors.Keys.TooManyOccurrences_2, count, name), name.getCode());
+                    Errors.Keys.TooManyOccurrences_2, max, name), name.getCode());
         }
         addUnchecked(parameter);
         modCount++;
@@ -263,9 +264,10 @@ final class ParameterValueList extends A
                 count++;
             }
         }
-        if (count >= desc.getMaximumOccurs()) {
+        final int max = desc.getMaximumOccurs();
+        if (count >= max) {
             throw new InvalidParameterCardinalityException(Errors.format(
-                    Errors.Keys.TooManyOccurrences_2, count, name), name.getCode());
+                    Errors.Keys.TooManyOccurrences_2, max, name), name.getCode());
         }
     }
 

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java [UTF-8] Fri May 23 17:36:12 2014
@@ -90,6 +90,31 @@ public final class CheckedArrayList<E> e
     }
 
     /**
+     * Returns the given collection as a {@code CheckedArrayList} instance of the given element type.
+     *
+     * @param  <E>        The element type.
+     * @param  collection The collection or {@code null}.
+     * @param  type       The element type.
+     * @return The given collection as a {@code CheckedArrayList}, or {@code null} if the given collection was null.
+     * @throws ClassCastException if an element is not of the expected type.
+     *
+     * @since 0.5
+     */
+    @SuppressWarnings("unchecked")
+    public static <E> CheckedArrayList<E> castOrCopy(final Collection<?> collection, final Class<E> type) {
+        if (collection == null) {
+            return null;
+        }
+        if (collection instanceof CheckedArrayList<?> && ((CheckedArrayList<?>) collection).type == type) {
+            return (CheckedArrayList<E>) collection;
+        } else {
+            final CheckedArrayList<E> list = new CheckedArrayList<E>(type, collection.size());
+            list.addAll((Collection) collection); // addAll will perform the type checks.
+            return list;
+        }
+    }
+
+    /**
      * Returns the element type given at construction time.
      */
     @Override

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Cloner.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Cloner.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Cloner.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/Cloner.java [UTF-8] Fri May 23 17:36:12 2014
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.util;
 
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.lang.reflect.InvocationTargetException;
 import org.apache.sis.util.Workaround;
 import org.apache.sis.util.resources.Errors;
@@ -28,7 +29,7 @@ import org.apache.sis.util.resources.Err
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
- * @version 0.3
+ * @version 0.5
  * @module
  */
 @Workaround(library="JDK", version="1.7")
@@ -85,15 +86,40 @@ public class Cloner {
         if (object == null) {
             return null;
         }
+        SecurityException security = null;
         final Class<?> valueType = object.getClass();
         try {
             if (valueType != type) {
                 method = valueType.getMethod("clone", (Class<?>[]) null);
                 type = valueType; // Set only if the above line succeed.
-            }
-            if (method != null) { // May be null if previous call threw NoSuchMethodException.
+                /*
+                 * If the class implementing the 'clone()' method is not public, we may not be able to access that
+                 * method even if it is public. Try to make the method accessible. If we fail for security reason,
+                 * we will still attempt to clone (maybe a parent class is public), but we remember the exception
+                 * in order to report it in case of failure.
+                 */
+                if (!Modifier.isPublic(method.getDeclaringClass().getModifiers())) try {
+                    method.setAccessible(true);
+                } catch (SecurityException e) {
+                    security = e;
+                }
+            }
+            /*
+             * 'method' may be null if a previous call to this clone(Object) method threw NoSuchMethodException
+             * (see the first 'catch' block below). In this context, 'null' means "no public clone() method".
+             */
+            if (method != null) {
                 return method.invoke(object, (Object[]) null);
             }
+        } catch (NoSuchMethodException e) {
+            if (isCloneRequired(object)) {
+                throw fail(e);
+            }
+            method = null;
+            type = valueType;
+        } catch (IllegalAccessException e) {
+            // JDK7 branch has the following: e.addSuppressed(security);
+            throw fail(e);
         } catch (InvocationTargetException e) {
             final Throwable cause = e.getCause();
             if (cause instanceof CloneNotSupportedException) {
@@ -106,13 +132,7 @@ public class Cloner {
                 throw (Error) cause;
             }
             throw fail(e);
-        } catch (NoSuchMethodException e) {
-            if (isCloneRequired(object)) {
-                throw fail(e);
-            }
-            method = null;
-            type = valueType;
-        } catch (Exception e) { // (ReflectiveOperationException) on JDK7
+        } catch (SecurityException e) {
             throw fail(e);
         }
         return object;

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Fri May 23 17:36:12 2014
@@ -64,6 +64,11 @@ public final class Errors extends Indexe
         }
 
         /**
+         * Type ‘{0}’ is abstract.
+         */
+        public static final short AbstractType_1 = 159;
+
+        /**
          * Name “{2}” is ambiguous because it can be understood as either “{0}” or “{1}”.
          */
         public static final short AmbiguousName_3 = 151;
@@ -593,6 +598,11 @@ public final class Errors extends Indexe
         public static final short NotAPrimitiveWrapper_1 = 90;
 
         /**
+         * The “{0}” collection is not a singleton.
+         */
+        public static final short NotASingleton_1 = 158;
+
+        /**
          * Matrix is not skew-symmetric.
          */
         public static final short NotASkewSymmetricMatrix = 91;
@@ -693,7 +703,7 @@ public final class Errors extends Indexe
         public static final short TooManyArguments_2 = 105;
 
         /**
-         * Too many occurrences of “{1}”. There is already {0} of them.
+         * Too many occurrences of “{1}”. The maximum is {0}.
          */
         public static final short TooManyOccurrences_2 = 149;
 

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Fri May 23 17:36:12 2014
@@ -24,6 +24,7 @@
 # programmatic parameters do not have to be last in the formatted text, since each localized message
 # can reorder the parameters as they want.
 #
+AbstractType_1                    = Type \u2018{0}\u2019 is abstract.
 AmbiguousName_3                   = Name \u201c{2}\u201d is ambiguous because it can be understood as either \u201c{0}\u201d or \u201c{1}\u201d.
 CanNotAddToExclusiveSet_2         = No element can be added to this set because properties \u2018{0}\u2019 and \u2018{1}\u2019 are mutually exclusive.
 CanNotConnectTo_1                 = Can not connect to \u201c{0}\u201d.
@@ -128,6 +129,7 @@ NonUniformScale                   = Scal
 NotAnAffineTransform              = Transform is not affine.
 NotANumber_1                      = Argument \u2018{0}\u2019 shall not be NaN (Not-a-Number).
 NotAPrimitiveWrapper_1            = Class \u2018{0}\u2019 is not a primitive type wrapper.
+NotASingleton_1                   = The \u201c{0}\u201d collection is not a singleton.
 NotASkewSymmetricMatrix           = Matrix is not skew-symmetric.
 NotAUnicodeIdentifier_1           = Text \u201c{0}\u201d is not a Unicode identifier.
 NotComparableClass_1              = Class \u2018{0}\u2019 is not a comparable.
@@ -150,7 +152,7 @@ StreamIsForwardOnly_1             = Can 
 TooFewArguments_2                 = Expected at least {0} argument{0,choice,1#|2#s}, but got {1}.
 TooFewOccurrences_2               = Too few occurrences of \u201c{1}\u201d. Expected at least {0} of them.
 TooManyArguments_2                = Expected at most {0} argument{0,choice,1#|2#s}, but got {1}.
-TooManyOccurrences_2              = Too many occurrences of \u201c{1}\u201d. There is already {0} of them.
+TooManyOccurrences_2              = Too many occurrences of \u201c{1}\u201d. The maximum is {0}.
 TreeDepthExceedsMaximum           = Tree depth exceeds the maximum.
 UndefinedOrderingForElements_2    = Ordering between \u201c{0}\u201d and \u201c{1}\u201d elements is undefined.
 UnexpectedArrayLength_2           = Expected an array of length {0}, but got {1}.

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Fri May 23 17:36:12 2014
@@ -14,6 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+AbstractType_1                    = Le type \u2018{0}\u2019 est abstrait.
 AmbiguousName_3                   = Le nom \u00ab\u202f{2}\u202f\u00bb est ambigu\u00eb car il peut \u00eatre interpr\u00e9t\u00e9 comme \u00ab\u202f{0}\u202f\u00bb ou \u00ab\u202f{1}\u202f\u00bb.
 CanNotAddToExclusiveSet_2         = Aucun \u00e9l\u00e9ment ne peut \u00eatre ajout\u00e9 \u00e0 cet ensemble car les propri\u00e9t\u00e9s \u2018{0}\u2019 et \u2018{1}\u2019 sont mutuellement exclusives.
 CanNotConnectTo_1                 = Ne peut pas se connecter \u00e0 \u00ab\u202f{0}\u202f\u00bb.
@@ -118,6 +119,7 @@ NonUniformScale                   = L\u2
 NotAnAffineTransform              = La transformation n\u2019est pas affine.
 NotANumber_1                      = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre NaN (Not-a-Number).
 NotAPrimitiveWrapper_1            = La classe \u2018{0}\u2019 n\u2019est pas un adaptateur d\u2019un type primitif.
+NotASingleton_1                   = La collection de \u00ab\u202f{0}\u202f\u00bb n\u2019est pas un singleton.
 NotASkewSymmetricMatrix           = La matrice n\u2019est pas antisym\u00e9trique.
 NotAUnicodeIdentifier_1           = Le texte \u00ab\u202f{0}\u202f\u00bb n\u2019est pas un identifiant Unicode.
 NotComparableClass_1              = La classe \u2018{0}\u2019 n\u2019est pas comparable.
@@ -139,7 +141,7 @@ StreamIsForwardOnly_1             = Ne p
 TooFewArguments_2                 = Au moins {0} argument{0,choice,1# \u00e9tait attendu|2#s \u00e9taient attendus}, mais seulement {1} {1,choice,1#a \u00e9t\u00e9 sp\u00e9cifi\u00e9|2#ont \u00e9t\u00e9 sp\u00e9cifi\u00e9s}.
 TooFewOccurrences_2               = Trop peu d\u2019occurrences de \u00ab\u202f{1}\u202f\u00bb. Il en faut au moins {0}.
 TooManyArguments_2                = Au plus {0} argument{0,choice,1# \u00e9tait attendu|2#s \u00e9taient attendus}, mais {1} {1,choice,1#a \u00e9t\u00e9 sp\u00e9cifi\u00e9|2#ont \u00e9t\u00e9 sp\u00e9cifi\u00e9s}.
-TooManyOccurrences_2              = Trop d\u2019occurrences de \u00ab\u202f{1}\u202f\u00bb. Il en existe d\u00e9j\u00e0 {0}.
+TooManyOccurrences_2              = Trop d\u2019occurrences de \u00ab\u202f{1}\u202f\u00bb. Le maximum est {0}.
 TreeDepthExceedsMaximum           = La profondeur de l\u2019arbre exc\u00e8de le maximum.
 UndefinedOrderingForElements_2    = L\u2019ordre entre les \u00e9l\u00e9ments \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb n\u2019est pas d\u00e9fini.
 UnexpectedArrayLength_2           = Un tableau de longueur {0} \u00e9tait attendu, mais le tableau re\u00e7u est de longueur {1}.

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/util/CheckedArrayListTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/util/CheckedArrayListTest.java?rev=1597136&r1=1597135&r2=1597136&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/util/CheckedArrayListTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/util/CheckedArrayListTest.java [UTF-8] Fri May 23 17:36:12 2014
@@ -128,4 +128,34 @@ public final strictfp class CheckedArray
         testAddWrongType(list.subList(1, 3));
         // Exception message is JDK-dependent, so we can not test it.
     }
+
+    /**
+     * Tests {@link CheckedArrayList#castOrCopy(Collection, Class)}.
+     */
+    @Test
+    @DependsOnMethod("testAddAll")
+    public void testCastOrCopy() {
+        assertNull(CheckedArrayList.castOrCopy(null, String.class));
+        final List<String> fruits = Arrays.asList("Apple", "Orange", "Raisin");
+        final CheckedArrayList<String> asStrings = CheckedArrayList.castOrCopy(fruits, String.class);
+        assertEquals ("Should have the given element type.", String.class, asStrings.getElementType());
+        assertNotSame("Should have created a new instance.", fruits, asStrings);
+        assertEquals ("Should contain the same data.",       fruits, asStrings);
+        assertSame   ("Should cast existing instance.", asStrings, CheckedArrayList.castOrCopy(asStrings, String.class));
+
+        final CheckedArrayList<CharSequence> asChars = CheckedArrayList.castOrCopy(asStrings, CharSequence.class);
+        assertEquals ("Should have the given element type.", CharSequence.class, asChars.getElementType());
+        assertNotSame("Should have created a new instance.", asStrings, asChars);
+        assertEquals ("Should contain the same data.",       asStrings, asChars);
+        assertEquals ("Should contain the same data.",       fruits,    asChars);
+
+        try {
+            CheckedArrayList.castOrCopy(asChars, Integer.class);
+            fail("Should not be allowed to cast String to Integer.");
+        } catch (ClassCastException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("String"));
+            assertTrue(message, message.contains("Integer"));
+        }
+    }
 }



Mime
View raw message