You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2014/07/03 18:25:40 UTC
svn commit: r1607689 - in /sis/branches/JDK8/core:
sis-metadata/src/main/java/org/apache/sis/metadata/
sis-metadata/src/test/java/org/apache/sis/metadata/
sis-utility/src/main/java/org/apache/sis/util/
sis-utility/src/test/java/org/apache/sis/test/
Author: desruisseaux
Date: Thu Jul 3 16:25:39 2014
New Revision: 1607689
URL: http://svn.apache.org/r1607689
Log:
Side effect of upgrade to ISO 19115:2014: PropertyAccessor shall been able to read/write
using deprecated getter/setter methods, while keeping the deprecated methods hidden from
the list of standard properties.
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TypeMap.java
sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1607689&r1=1607688&r2=1607689&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Thu Jul 3 16:25:39 2014
@@ -83,7 +83,7 @@ import static org.apache.sis.util.collec
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3 (derived from geotk-2.4)
- * @version 0.3
+ * @version 0.5
* @module
*/
class PropertyAccessor {
@@ -150,14 +150,26 @@ class PropertyAccessor {
final Class<?> implementation;
/**
- * Number of {@link #getters} methods to use. This is either {@code getters.length}
- * or {@code getters.length-1}, depending on whether the {@link #EXTRA_GETTER} method
- * needs to be skipped or not.
+ * Number of {@link #getters} methods that can be used, regardless of whether the methods are visible
+ * or hidden to the user. This is either {@code getters.length} or {@code getters.length-1}, depending
+ * on whether the {@link #EXTRA_GETTER} method needs to be skipped or not.
*/
- private final int standardCount, allCount;
+ private final int allCount;
/**
- * The getter methods. This array should not contain any null element.
+ * Numbers of methods to shown to the user. This is always equal or lower than {@link #allCount}.
+ * This count may be lower than {@code allCount} for two reasons:
+ *
+ * <ul>
+ * <li>The {@link #EXTRA_GETTER} method is not part of the international standard.</li>
+ * <li>The interface contains deprecated methods from an older international standard.
+ * Example: changes caused by the upgrade from ISO 19115:2003 to ISO 19115:2014.</li>
+ * </ul>
+ */
+ private final int standardCount;
+
+ /**
+ * The public getter methods. This array should not contain any null element.
* They are the methods defined in the interface, not the implementation class.
*
* <p>This array shall not contains any {@code null} elements.</p>
@@ -251,6 +263,12 @@ class PropertyAccessor {
}
standardCount--;
}
+ while (standardCount != 0) { // Skip deprecated methods.
+ if (!isDeprecated(standardCount - 1)) {
+ break;
+ }
+ standardCount--;
+ }
this.allCount = allCount;
this.standardCount = standardCount;
/*
@@ -359,8 +377,18 @@ class PropertyAccessor {
if (!name.isEmpty()) {
final Integer old = mapping.put(name, index);
if (old != null && !old.equals(index)) {
- throw new IllegalStateException(Errors.format(Errors.Keys.DuplicatedIdentifier_1,
- Classes.getShortName(type) + '.' + name));
+ /*
+ * Same identifier for two different properties. If one is deprecated while the
+ * other is not, then the non-deprecated identifier overwrite the deprecated one.
+ */
+ final boolean deprecated = isDeprecated(index);
+ if (deprecated == isDeprecated(old)) {
+ throw new IllegalStateException(Errors.format(Errors.Keys.DuplicatedIdentifier_1,
+ Classes.getShortName(type) + '.' + name));
+ }
+ if (deprecated) {
+ mapping.put(name, old); // Restore the undeprecated method.
+ }
}
}
}
@@ -448,6 +476,8 @@ class PropertyAccessor {
/**
* Returns the number of properties that can be read.
+ * This is the properties to show in map or tree, <strong>not</strong> including
+ * hidden properties like deprecated methods or {@link #EXTRA_GETTER} method.
*
* @see #count(Object, ValueExistencePolicy, int)
*/
@@ -539,7 +569,7 @@ class PropertyAccessor {
* @return The type of property values, or {@code null} if unknown.
*/
Class<?> type(final int index, final TypeValuePolicy policy) {
- if (index >= 0 && index < standardCount) {
+ if (index >= 0 && index < allCount) {
switch (policy) {
case ELEMENT_TYPE: {
return elementTypes[index];
@@ -570,13 +600,20 @@ class PropertyAccessor {
* Returns {@code true} if the type at the given index is {@link Collection}.
*/
final boolean isCollection(final int index) {
- if (index >= 0 && index < standardCount) {
+ if (index >= 0 && index < allCount) {
return Collection.class.isAssignableFrom(getters[index].getReturnType());
}
return false;
}
/**
+ * Returns {@code true} if the property at the given index is deprecated.
+ */
+ private boolean isDeprecated(final int index) {
+ return getters[index].isAnnotationPresent(Deprecated.class);
+ }
+
+ /**
* Returns the information for the property at the given index.
* The information are created when first needed.
*
@@ -621,7 +658,7 @@ class PropertyAccessor {
* Returns {@code true} if the property at the given index is writable.
*/
final boolean isWritable(final int index) {
- return (index >= 0) && (index < standardCount) && (setters != null) && (setters[index] != null);
+ return (index >= 0) && (index < allCount) && (setters != null) && (setters[index] != null);
}
/**
@@ -636,7 +673,7 @@ class PropertyAccessor {
* @throws BackingStoreException If the implementation threw a checked exception.
*/
Object get(final int index, final Object metadata) throws BackingStoreException {
- return (index >= 0 && index < standardCount) ? get(getters[index], metadata) : null;
+ return (index >= 0 && index < allCount) ? get(getters[index], metadata) : null;
}
/**
@@ -709,7 +746,7 @@ class PropertyAccessor {
Object set(final int index, final Object metadata, final Object value, final int mode)
throws UnmodifiableMetadataException, ClassCastException, BackingStoreException
{
- if (index < 0 || index >= standardCount) {
+ if (index < 0 || index >= allCount) {
return null;
}
if (setters != null) {
@@ -1021,7 +1058,7 @@ class PropertyAccessor {
return count();
}
int count = 0;
- for (int i=0; i<standardCount; i++) {
+ for (int i=0; i<standardCount; i++) { // Use 'standardCount' instead of 'allCount' for ignoring deprecated methods.
final Object value = get(getters[i], metadata);
if (!valuePolicy.isSkipped(value)) {
switch (mode) {
@@ -1097,7 +1134,7 @@ class PropertyAccessor {
final Cloner cloner = new Cloner();
for (int i=0; i<allCount; i++) {
final Method setter = setters[i];
- if (setter != null) {
+ if (setter != null && !setter.isAnnotationPresent(Deprecated.class)) {
final Method getter = getters[i];
final Object source = get(getter, metadata);
final Object target = cloner.clone(source);
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java?rev=1607689&r1=1607688&r2=1607689&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] Thu Jul 3 16:25:39 2014
@@ -33,6 +33,7 @@ import org.opengis.annotation.Obligation
*
* <p>This comparator uses the following criterion, in priority order:</p>
* <ol>
+ * <li>Deprecated properties are last.</li>
* <li>If the property order is specified by a {@link XmlType} annotation,
* then this comparator complies to that order.</li>
* <li>Otherwise this comparator sorts mandatory methods first, followed by
@@ -43,7 +44,7 @@ import org.opengis.annotation.Obligation
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3 (derived from geotk-2.4)
- * @version 0.4
+ * @version 0.5
* @module
*/
final class PropertyComparator implements Comparator<Method> {
@@ -115,6 +116,10 @@ final class PropertyComparator implement
*/
@Override
public int compare(final Method m1, final Method m2) {
+ final boolean deprecated = m1.isAnnotationPresent(Deprecated.class);
+ if (deprecated != m2.isAnnotationPresent(Deprecated.class)) {
+ return deprecated ? +1 : -1;
+ }
int c = indexOf(m2) - indexOf(m1); // indexOf(…) are sorted in descending order.
if (c == 0) {
final UML a1 = m1.getAnnotation(UML.class);
Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TypeMap.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TypeMap.java?rev=1607689&r1=1607688&r2=1607689&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TypeMap.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/TypeMap.java [UTF-8] Thu Jul 3 16:25:39 2014
@@ -69,12 +69,11 @@ final class TypeMap extends PropertyMap<
return new Iter() {
@Override
public Map.Entry<String,Class<?>> next() {
- final Class<?> value = accessor.type(index, valuePolicy);
- if (value == null) {
- // PropertyAccessor.type(int) never return null if the index is valid.
+ if (index >= accessor.count()) {
throw new NoSuchElementException();
}
- return new SimpleImmutableEntry<String,Class<?>>(accessor.name(index++, keyPolicy), value);
+ final Class<?> value = accessor.type(index, valuePolicy);
+ return new SimpleImmutableEntry<>(accessor.name(index++, keyPolicy), value);
}
};
}
Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java?rev=1607689&r1=1607688&r2=1607689&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java [UTF-8] Thu Jul 3 16:25:39 2014
@@ -33,6 +33,9 @@ import org.opengis.metadata.citation.Pre
import org.opengis.metadata.citation.ResponsibleParty;
import org.opengis.metadata.distribution.Format;
import org.opengis.metadata.constraint.Constraints;
+import org.opengis.metadata.content.AttributeGroup;
+import org.opengis.metadata.content.CoverageContentType;
+import org.opengis.metadata.content.CoverageDescription;
import org.opengis.metadata.identification.*; // Really using almost everything.
import org.opengis.metadata.maintenance.MaintenanceInformation;
import org.opengis.metadata.spatial.SpatialRepresentationType;
@@ -50,6 +53,7 @@ import org.apache.sis.util.ComparisonMod
import org.apache.sis.util.iso.SimpleInternationalString;
import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.apache.sis.metadata.iso.citation.HardCodedCitations;
+import org.apache.sis.metadata.iso.content.DefaultCoverageDescription;
import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
@@ -76,7 +80,7 @@ import static org.apache.sis.metadata.Pr
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3 (derived from geotk-2.4)
- * @version 0.4
+ * @version 0.5
* @module
*/
@DependsOn(PropertyInformationTest.class)
@@ -346,6 +350,40 @@ public final strictfp class PropertyAcce
}
/**
+ * Tests setting a deprecated properties. This properties should not be visible in the map,
+ * but still be accepted by the map views.
+ */
+ @Test
+ @DependsOnMethod("testSet")
+ public void testSetDeprecated() {
+ final PropertyAccessor accessor = new PropertyAccessor(HardCodedCitations.ISO_19115,
+ CoverageDescription.class, DefaultCoverageDescription.class);
+ final int indexOfDeprecated = accessor.indexOf("contentType", true);
+ final int indexOfReplacement = accessor.indexOf("attributeGroup", true);
+ assertTrue("Deprecated elements shall be sorted after non-deprecated ones.",
+ indexOfDeprecated > indexOfReplacement);
+ /*
+ * Writes a value using the deprecated property.
+ */
+ final DefaultCoverageDescription instance = new DefaultCoverageDescription();
+ assertNull("Shall be initially empty.", accessor.set(indexOfDeprecated, instance,
+ CoverageContentType.IMAGE, PropertyAccessor.RETURN_PREVIOUS));
+ assertEquals(CoverageContentType.IMAGE, accessor.get(indexOfDeprecated, instance));
+ /*
+ * Compares with the non-deprecated property.
+ */
+ final Collection<AttributeGroup> groups = instance.getAttributeGroups();
+ assertSame(groups, accessor.get(indexOfReplacement, instance));
+ assertEquals(CoverageContentType.IMAGE, getSingleton(getSingleton(groups).getContentTypes()));
+ /*
+ * While we can read/write the value through two properties,
+ * only one should be visible.
+ */
+ assertEquals("Deprecated property shall not be visible.", 1, accessor.count(
+ instance, ValueExistencePolicy.NON_EMPTY, PropertyAccessor.COUNT_SHALLOW));
+ }
+
+ /**
* Tests the {@link PropertyAccessor#set(int, Object, Object, int)} method
* with a value that will need to be converted. The conversion will be from
* {@link String} to {@link InternationalString}. The created metadata object is:
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java?rev=1607689&r1=1607688&r2=1607689&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Classes.java [UTF-8] Thu Jul 3 16:25:39 2014
@@ -51,7 +51,7 @@ import static org.apache.sis.util.collec
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.3 (derived from geotk-2.5)
- * @version 0.3
+ * @version 0.5
* @module
*/
public final class Classes extends Static {
@@ -696,7 +696,6 @@ cmp: for (final Class<?> c : c1) {
* {@link Object#hashCode() hashCode}, {@link Object#toString() toString} or
* {@link org.opengis.referencing.IdentifiedObject#toWKT() toWKT}.</li>
* <li>The method is not {@linkplain Method#isSynthetic() synthetic}.</li>
- * <li>The method is not {@linkplain Deprecated deprecated}.</li>
* </ul>
*
* <p>Those conditions may be updated in any future SIS version.</p>
@@ -708,7 +707,6 @@ cmp: for (final Class<?> c : c1) {
return method.getReturnType() != Void.TYPE &&
method.getParameterTypes().length == 0 &&
!method.isSynthetic() &&
- !method.isAnnotationPresent(Deprecated.class) &&
!ArraysExt.contains(EXCLUDES, method.getName());
}
}
Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java?rev=1607689&r1=1607688&r2=1607689&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/AnnotationsTestCase.java [UTF-8] Thu Jul 3 16:25:39 2014
@@ -276,8 +276,10 @@ public abstract strictfp class Annotatio
} else {
namespace = schemaNamespace;
}
- assertEquals("Wrong namespace for the ISO specification.",
- getExpectedNamespace(impl, (uml != null) ? uml.specification() : null), namespace);
+ if (uml != null) {
+ assertEquals("Wrong namespace for the ISO specification.",
+ getExpectedNamespace(impl, uml.specification()), namespace);
+ }
return namespace;
}
@@ -350,18 +352,11 @@ public abstract strictfp class Annotatio
/**
* Returns {@code true} if the given method should be ignored.
- * This method returns {@code true} of deprecated methods and
- * some standard methods from the JDK.
+ * This method returns {@code true} for some standard methods from the JDK.
*/
private static boolean isIgnored(final Method method) {
- if (method.isAnnotationPresent(Deprecated.class)) {
- return true;
- }
final String name = method.getName();
- if (name.equals("equals") || name.equals("hashCode") || name.equals("doubleValue")) {
- return true;
- }
- return false;
+ return name.equals("equals") || name.equals("hashCode") || name.equals("doubleValue");
}
/**
@@ -387,7 +382,9 @@ public abstract strictfp class Annotatio
testingMethod = method.getName();
if (!isIgnored(method)) {
uml = method.getAnnotation(UML.class);
- assertNotNull("Missing @UML annotation.", uml);
+ if (!method.isAnnotationPresent(Deprecated.class)) {
+ assertNotNull("Missing @UML annotation.", uml);
+ }
}
}
}