Return-Path: X-Original-To: apmail-sis-commits-archive@www.apache.org Delivered-To: apmail-sis-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 864BD1163C for ; Tue, 6 May 2014 17:49:40 +0000 (UTC) Received: (qmail 99628 invoked by uid 500); 6 May 2014 16:57:09 -0000 Delivered-To: apmail-sis-commits-archive@sis.apache.org Received: (qmail 99559 invoked by uid 500); 6 May 2014 16:57:07 -0000 Mailing-List: contact commits-help@sis.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sis-dev@sis.apache.org Delivered-To: mailing list commits@sis.apache.org Received: (qmail 99535 invoked by uid 99); 6 May 2014 16:57:06 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 May 2014 16:57:06 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 May 2014 16:57:03 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 84FFB2388860; Tue, 6 May 2014 16:56:43 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r1592805 - in /sis/branches/JDK8/core: sis-feature/src/main/java/org/apache/sis/feature/ sis-feature/src/test/java/org/apache/sis/feature/ sis-utility/src/main/java/org/apache/sis/util/resources/ Date: Tue, 06 May 2014 16:56:43 -0000 To: commits@sis.apache.org From: desruisseaux@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140506165643.84FFB2388860@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: desruisseaux Date: Tue May 6 16:56:42 2014 New Revision: 1592805 URL: http://svn.apache.org/r1592805 Log: Added more verifications of attribute validity. Added: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/Validator.java (with props) Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonValue.java sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTest.java sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonValueTest.java sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java?rev=1592805&r1=1592804&r2=1592805&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java [UTF-8] Tue May 6 16:56:42 2014 @@ -19,6 +19,7 @@ package org.apache.sis.feature; import java.io.Serializable; import org.apache.sis.util.Debug; import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.resources.Errors; // Related to JDK7 import java.util.Objects; @@ -46,7 +47,7 @@ import java.util.Objects; * @version 0.5 * @module */ -public class DefaultAttribute implements Serializable { +public class DefaultAttribute implements Cloneable, Serializable { /** * For cross-version compatibility. */ @@ -125,7 +126,32 @@ public class DefaultAttribute impleme * @see DefaultFeature#validate() */ public void validate() { - // TODO: future SIS implementation shall check constraints here. + /* + * In theory, the following check is useless since the type was constrained by the setValue(T) method signature. + * However in practice the call to setValue(…) is sometime done after type erasure, so we are better to check. + */ + if (value != null && !type.getValueClass().isInstance(value)) { + throw new RuntimeException( // TODO: IllegalAttributeException, pending GeoAPI revision. + Errors.format(Errors.Keys.IllegalPropertyClass_2, type.getName(), value.getClass())); + } + } + + /** + * Returns a shallow copy of this attribute. + * The attribute {@linkplain #getValue() value} is not cloned. + * + * @return A clone of this attribute. + */ + @Override + @SuppressWarnings("unchecked") + public DefaultAttribute clone() { + final DefaultAttribute clone; + try { + clone = (DefaultAttribute) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); // Should never happen since we are cloneable. + } + return clone; } /** Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java?rev=1592805&r1=1592804&r2=1592805&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java [UTF-8] Tue May 6 16:56:42 2014 @@ -116,7 +116,7 @@ public class DefaultFeature implements S * @return All properties of the given name, or an empty list if none. * @throws IllegalArgumentException If the given argument is not a property name of this feature. */ - public List> getProperties(final String name) throws IllegalArgumentException { + public List> properties(final String name) throws IllegalArgumentException { ArgumentChecks.ensureNonNull("name", name); final DefaultAttributeType at = type.getProperty(name); if (at == null) { @@ -129,7 +129,7 @@ public class DefaultFeature implements S * a temporary object which will read and write the Attribute instance directly in the map. */ if (isSingleton(at.getCardinality())) { - return new SingletonValue(properties, name); + return new SingletonValue(at, properties, name); } /* * If the property allow more than one feature, then we need a real List implementation. @@ -143,7 +143,7 @@ public class DefaultFeature implements S /** * Returns the value(s) of all attribute of the given name. - * This convenience method combines a call to {@link #getProperties(String)} followed by calls to + * This convenience method combines a call to {@link #properties(String)} followed by calls to * {@link DefaultAttribute#getValue()} for each attribute, but may potentially be more efficient. * *

Special cases:

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonValue.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonValue.java?rev=1592805&r1=1592804&r2=1592805&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonValue.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonValue.java [UTF-8] Tue May 6 16:56:42 2014 @@ -45,6 +45,16 @@ import static org.apache.sis.util.Argume */ final class SingletonValue extends AbstractList> { /** + * An empty list of attributes. + */ + private static final DefaultAttribute[] EMPTY = new DefaultAttribute[0]; + + /** + * The type of property elements in the list. + */ + private final AbstractIdentifiedType type; + + /** * The map of properties in which to look for the attributes. * This is the same reference than {@link DefaultFeature#properties}. */ @@ -58,9 +68,10 @@ final class SingletonValue extends Abstr /** * Creates a new list for the attribute associated to the given key in the given map. */ - SingletonValue(final Map properties, final String key) { + SingletonValue(final AbstractIdentifiedType type, final Map properties, final String key) { + this.type = type; this.properties = properties; - this.key = key; + this.key = key; } /** @@ -107,6 +118,7 @@ final class SingletonValue extends Abstr @Override public DefaultAttribute set(final int index, final DefaultAttribute element) { ensureNonNull("element", element); + Validator.ensureValidType(type, element); if (index == 0) { modCount++; final Object previous = properties.put(key, element); @@ -126,6 +138,7 @@ final class SingletonValue extends Abstr @Override public void add(final int index, final DefaultAttribute element) { ensureNonNull("element", element); + Validator.ensureValidType(type, element); if (index == 0) { if (properties.putIfAbsent(key, element) == null) { modCount++; @@ -192,6 +205,15 @@ final class SingletonValue extends Abstr } /** + * Returns an array wrapping the singleton value, or an empty array if none. + */ + @Override + public Object[] toArray() { + final Object element = properties.get(key); + return (element == null) ? EMPTY : new DefaultAttribute[] {(DefaultAttribute) element}; + } + + /** * Returns an iterator over the unique element in this list. */ @Override Added: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/Validator.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/Validator.java?rev=1592805&view=auto ============================================================================== --- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/Validator.java (added) +++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/Validator.java [UTF-8] Tue May 6 16:56:42 2014 @@ -0,0 +1,47 @@ +/* + * 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.feature; + +import org.apache.sis.util.resources.Errors; + + +/** + * Provides validation methods to be shared by different implementations. + * + * @author Martin Desruisseaux (Geomatys) + * @since 0.5 + * @version 0.5 + * @module + */ +final class Validator { + /** + * Do not allow (for now) instantiation of this class. + */ + private Validator() { + } + + /** + * Ensures that the give element is an instance of the expected type. + * The caller shall ensure that the element is non-null before to invoke this method. + */ + static void ensureValidType(final AbstractIdentifiedType type, final DefaultAttribute element) { + if (element.getType() != type) { + // TODO: replace RuntimeException by IllegalAttributeException after GeoAPI review. + throw new RuntimeException(Errors.format(Errors.Keys.MismatchedPropertyType_1, type.getName())); + } + } +} Propchange: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/Validator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/Validator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain;charset=UTF-8 Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTest.java?rev=1592805&r1=1592804&r2=1592805&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAttributeTest.java [UTF-8] Tue May 6 16:56:42 2014 @@ -71,7 +71,14 @@ public final strictfp class DefaultAttri public void testEquals() { final DefaultAttribute a1 = population(); final DefaultAttribute a2 = population(); - assertFalse ("equals", a1.equals(null)); + assertFalse("equals(null)", a1.equals(null)); + testEquals(a1, a2); + } + + /** + * Implementation of {@link #testEquals()} used also by {@link #testClone()}. + */ + private static void testEquals(final DefaultAttribute a1, final DefaultAttribute a2) { assertTrue ("equals", a1.equals(a2)); assertEquals("hashCode", a1.hashCode(), a2.hashCode()); a2.setValue(1000); @@ -80,6 +87,18 @@ public final strictfp class DefaultAttri } /** + * Tests {@link DefaultAttribute#clone()}. + */ + @Test + @DependsOnMethod("testEquals") + public void testClone() { + final DefaultAttribute a1 = population(); + final DefaultAttribute a2 = a1.clone(); + assertNotSame(a1, a2); + testEquals(a1, a2); + } + + /** * Tests serialization. */ @Test Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonValueTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonValueTest.java?rev=1592805&r1=1592804&r2=1592805&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonValueTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/SingletonValueTest.java [UTF-8] Tue May 6 16:56:42 2014 @@ -19,6 +19,7 @@ package org.apache.sis.feature; import java.util.Set; import java.util.Map; import java.util.HashMap; +import org.apache.sis.measure.NumberRange; import org.apache.sis.test.DependsOnMethod; import org.apache.sis.test.DependsOn; import org.apache.sis.test.TestCase; @@ -51,6 +52,11 @@ public final strictfp class SingletonVal private final SingletonValue singleton; /** + * The type of the attribute value in the {@link #singleton} list. + */ + private final DefaultAttributeType attributeType; + + /** * The map of properties given to the {@link #singleton} instance to test. */ private final Map properties; @@ -64,9 +70,11 @@ public final strictfp class SingletonVal * Creates a new test case. */ public SingletonValueTest() { - otherValues = singletonMap("other key", "other value"); - properties = new HashMap<>(otherValues); - singleton = new SingletonValue(properties, KEY); + otherValues = singletonMap("other key", "other value"); + properties = new HashMap<>(otherValues); + attributeType = new DefaultAttributeType<>(singletonMap(DefaultAttributeType.NAME_KEY, KEY), + Integer.class, null, NumberRange.create(0, true, 1, true)); + singleton = new SingletonValue(attributeType, properties, KEY); } /** @@ -74,10 +82,11 @@ public final strictfp class SingletonVal */ @Test public void testEmpty() { - assertEquals("size", 0, singleton.size()); - assertTrue("isEmpty", singleton.isEmpty()); - assertFalse("iterator.hasNext", singleton.iterator().hasNext()); - assertFalse("listIterator.hasNext", singleton.listIterator().hasNext()); + assertEquals("size", 0, singleton.size()); + assertTrue ("isEmpty", singleton.isEmpty()); + assertEquals("toArray", 0, singleton.toArray().length); + assertFalse ("iterator.hasNext", singleton.iterator().hasNext()); + assertFalse ("listIterator.hasNext", singleton.listIterator().hasNext()); try { singleton.get(0); fail("Element 0 is not expected to exist."); @@ -99,8 +108,8 @@ public final strictfp class SingletonVal @Test @DependsOnMethod("testEmpty") public void testSingleton() { - final DefaultAttribute a1 = DefaultAttributeTest.population(); - final DefaultAttribute a2 = DefaultAttributeTest.population(); + final DefaultAttribute a1 = new DefaultAttribute<>(attributeType); + final DefaultAttribute a2 = new DefaultAttribute<>(attributeType); a1.setValue(1000); a2.setValue(2000); assertEquals("indexOf", -1, singleton.indexOf(a1)); @@ -113,6 +122,8 @@ public final strictfp class SingletonVal assertSame ("set", a1, singleton.set(0, a2)); assertSame ("get", a2, singleton.get(0)); assertSame ("iterator", a2, getSingleton(singleton)); + assertArrayEquals("toArray", new DefaultAttribute[] {a2}, singleton.toArray()); + assertSame ("remove", a2, singleton.remove(0)); assertEquals("size", 0, singleton.size()); assertEquals("Other values shall be unmodified.", otherValues, properties); @@ -124,8 +135,8 @@ public final strictfp class SingletonVal @Test @DependsOnMethod("testSingleton") public void testMaximumOccurrence() { - final DefaultAttribute a1 = DefaultAttributeTest.population(); - final DefaultAttribute a2 = DefaultAttributeTest.population(); + final DefaultAttribute a1 = new DefaultAttribute<>(attributeType); + final DefaultAttribute a2 = new DefaultAttribute<>(attributeType); assertTrue("add", singleton.add(a1)); try { assertTrue("add", singleton.add(a2)); @@ -142,10 +153,26 @@ public final strictfp class SingletonVal @Test @DependsOnMethod("testSingleton") public void testRemoveAll() { - final Set> attributes = singleton(DefaultAttributeTest.population()); + final Set> attributes = singleton(new DefaultAttribute<>(attributeType)); assertTrue (singleton.addAll(attributes)); assertFalse(singleton.isEmpty()); assertTrue (singleton.removeAll(attributes)); assertTrue (singleton.isEmpty()); } + + /** + * Tests the attempt to add an attribute of the wrong type. + * {@link SingletonValue} shall not allow this operation. + */ + @Test + @DependsOnMethod("testSingleton") + public void testAddWrongType() { + final DefaultAttribute a1 = DefaultAttributeTest.population(); + try { + singleton.add(a1); + } catch (RuntimeException e) { // TODO: IllegalAttributeException after GeoAPI review. + final String message = e.getMessage(); + assertTrue(message, message.contains(KEY)); + } + } } Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1592805&r1=1592804&r2=1592805&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Tue May 6 16:56:42 2014 @@ -423,6 +423,11 @@ public final class Errors extends Indexe public static final short MismatchedParameterDescriptor_1 = 146; /** + * Mismatched type for “{0}” property. + */ + public static final short MismatchedPropertyType_1 = 154; + + /** * No authority was specified for code “{0}”. The expected syntax is “AUTHORITY:CODE”. */ public static final short MissingAuthority_1 = 135; Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1592805&r1=1592804&r2=1592805&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original) +++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Tue May 6 16:56:42 2014 @@ -91,10 +91,11 @@ KeyCollision_1 = A di MandatoryAttribute_2 = Attribute \u201c{0}\u201d is mandatory for an object of type \u2018{1}\u2019. MismatchedArrayLengths = Mismatched array lengths. MismatchedCRS = The coordinate reference system must be the same for all objects. -MismatchedParameterDescriptor_1 = Mismatched descriptor for \u201c{0}\u201d parameter. MismatchedDimension_2 = Mismatched object dimensions: {0}D and {1}D. MismatchedDimension_3 = Argument \u2018{0}\u2019 has {2} dimension{2,choice,1#|2#s}, while {1} was expected. MismatchedMatrixSize_4 = Mismatched matrix sizes: expected {0}\u00d7{1} but got {2}\u00d7{3}. +MismatchedParameterDescriptor_1 = Mismatched descriptor for \u201c{0}\u201d parameter. +MismatchedPropertyType_1 = Mismatched type for \u201c{0}\u201d property. MissingAuthority_1 = No authority was specified for code \u201c{0}\u201d. The expected syntax is \u201cAUTHORITY:CODE\u201d. MissingRequiredModule_1 = This operation requires the \u201c{0}\u201d module. MissingSchemeInURI = Missing scheme in URI. Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1592805&r1=1592804&r2=1592805&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original) +++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Tue May 6 16:56:42 2014 @@ -81,10 +81,11 @@ KeyCollision_1 = Une MandatoryAttribute_2 = L\u2019attribut \u00ab\u202f{0}\u202f\u00bb est obligatoire pour un objet de type \u2018{1}\u2019. MismatchedArrayLengths = Les dimensions des tableaux ne correspondent pas. MismatchedCRS = Le syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es doit \u00eatre le m\u00eame pour tous les objets. -MismatchedParameterDescriptor_1 = Le descripteur du param\u00e8tre \u00ab\u202f{0}\u202f\u00bb ne correspond pas. MismatchedDimension_2 = Les dimensions des objets ({0}D et {1}D) ne concordent pas. MismatchedDimension_3 = L\u2019argument \u2018{0}\u2019 a {2} dimension{2,choice,1#|2#s}, alors qu\u2019on en attendait {1}. MismatchedMatrixSize_4 = Une matrice de taille de {0}\u00d7{1} \u00e9tait attendue mais la matrice donn\u00e9es est de taille {2}\u00d7{3}. +MismatchedParameterDescriptor_1 = Le descripteur du param\u00e8tre \u00ab\u202f{0}\u202f\u00bb ne correspond pas. +MismatchedPropertyType_1 = Le type de la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb ne correspond pas. MissingAuthority_1 = Aucune autorit\u00e9 n\u2019a \u00e9t\u00e9 sp\u00e9cifi\u00e9e pour le code \u00ab\u202f{0}\u202f\u00bb. Le format attendu est \u00ab\u202fAUTORIT\u00c9:CODE\u202f\u00bb. MissingRequiredModule_1 = Cette op\u00e9ration requiert le module \u00ab\u202f{0}\u202f\u00bb. MissingSchemeInURI = Il manque le sch\u00e9ma d\u2019URI.