sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1627067 - in /sis/branches/JDK8/core/sis-metadata/src: main/java/org/apache/sis/metadata/ test/java/org/apache/sis/metadata/
Date Tue, 23 Sep 2014 15:48:30 GMT
Author: desruisseaux
Date: Tue Sep 23 15:48:30 2014
New Revision: 1627067

URL: http://svn.apache.org/r1627067
Log:
Added support for dependencies in MetadataStandard.
For example ISO 19111 standard depends on ISO 19115.

Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java?rev=1627067&r1=1627066&r2=1627067&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
[UTF-8] Tue Sep 23 15:48:30 2014
@@ -279,24 +279,7 @@ public abstract class AbstractMetadata i
      */
     @Override
     public boolean equals(final Object object, final ComparisonMode mode) {
-        if (object == this) {
-            return true;
-        }
-        if (object == null) {
-            return false;
-        }
-        if (mode == ComparisonMode.STRICT) {
-            if (object.getClass() != getClass()) {
-                return false;
-            }
-        }
-        final MetadataStandard standard = getStandard();
-        if (mode != ComparisonMode.STRICT) {
-            if (!getInterface().isInstance(object)) {
-                return false;
-            }
-        }
-        return standard.equals(this, object, mode);
+        return getStandard().equals(this, object, mode);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1627067&r1=1627066&r2=1627067&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
[UTF-8] Tue Sep 23 15:48:30 2014
@@ -18,10 +18,11 @@ package org.apache.sis.metadata;
 
 import java.util.Set;
 import java.util.Map;
-import java.util.IdentityHashMap;
 import java.util.LinkedHashSet;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
 import java.io.IOException;
 import java.io.Serializable;
 import java.io.ObjectInputStream;
@@ -40,6 +41,7 @@ import org.apache.sis.internal.system.Sy
 import org.apache.sis.internal.simple.SimpleCitation;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
+import static org.apache.sis.util.ArgumentChecks.ensureNonNullElement;
 
 
 /**
@@ -136,10 +138,10 @@ public class MetadataStandard implements
         final String[] acronyms = {"CoordinateSystem", "CS", "CoordinateReferenceSystem",
"CRS"};
 
         // If new StandardImplementation instances are added below, please update StandardImplementation.readResolve().
-        ISO_19111 = new StandardImplementation("ISO 19111", "org.opengis.referencing.", "org.apache.sis.referencing.",
acronyms);
-        ISO_19115 = new StandardImplementation("ISO 19115", "org.opengis.metadata.", "org.apache.sis.metadata.iso.",
null);
-        ISO_19119 = new MetadataStandard      ("ISO 19119", "org.opengis.service.");
-        ISO_19123 = new MetadataStandard      ("ISO 19123", "org.opengis.coverage.");
+        ISO_19115 = new StandardImplementation("ISO 19115", "org.opengis.metadata.", "org.apache.sis.metadata.iso.",
null, null);
+        ISO_19111 = new StandardImplementation("ISO 19111", "org.opengis.referencing.", "org.apache.sis.referencing.",
acronyms, new MetadataStandard[] {ISO_19115});
+        ISO_19119 = new MetadataStandard      ("ISO 19119", "org.opengis.service.", ISO_19111.dependencies);
+        ISO_19123 = new MetadataStandard      ("ISO 19123", "org.opengis.coverage.", new
MetadataStandard[] {ISO_19111});
         INSTANCES = new MetadataStandard[] {
             ISO_19111,
             ISO_19115,
@@ -161,37 +163,54 @@ public class MetadataStandard implements
     final Citation citation;
 
     /**
-     * The root packages for metadata interfaces. Must have a trailing {@code '.'}.
+     * The root package for metadata interfaces. Must have a trailing {@code '.'}.
      */
     final String interfacePackage;
 
     /**
+     * The dependencies, or {@code null} if none.
+     *
+     * Note: the {@code null} value is for serialization compatibility.
+     */
+    private final MetadataStandard[] dependencies;
+
+    /**
      * Accessors for the specified implementations.
      * The only legal value types are:
      *
      * <ul>
-     *   <li>{@link Class} if we have determined the standard interface for a given
type
-     *       but did not yet created the {@link PropertyAccessor} for it.</li>
+     *   <li>{@link MetadataStandard} if type is handled by {@linkplain #dependencies}
rather than this standard.</li>
+     *   <li>{@link Class} if we found the interface for the type but did not yet created
the {@link PropertyAccessor}.</li>
      *   <li>{@link PropertyAccessor} otherwise.</li>
      * </ul>
      */
-    private final transient Map<Class<?>, Object> accessors; // written by reflection
on deserialization.
+    private final transient ConcurrentMap<Class<?>, Object> accessors; // written
by reflection on deserialization.
 
     /**
      * Creates a new instance working on implementation of interfaces defined in the specified
package.
      *
-     * <p><b>Example:</b>: For the ISO 19115 standard reflected by GeoAPI
interfaces,
-     * {@code interfacePackage} shall be the {@link org.opengis.metadata} package.</p>
+     * <div class="note"><b>Example:</b>: For the ISO 19115 standard reflected
by GeoAPI interfaces,
+     * {@code interfacePackage} shall be the {@link org.opengis.metadata} package.</div>
      *
      * @param citation         Bibliographical reference to the international standard.
      * @param interfacePackage The root package for metadata interfaces.
+     * @param dependencies     The dependencies to other metadata standards.
      */
-    public MetadataStandard(final Citation citation, final Package interfacePackage) {
-        ensureNonNull("citation", citation);
+    public MetadataStandard(final Citation citation, final Package interfacePackage, MetadataStandard...
dependencies) {
+        ensureNonNull("citation",         citation);
         ensureNonNull("interfacePackage", interfacePackage);
+        ensureNonNull("dependencies",     dependencies);
         this.citation         = citation;
         this.interfacePackage = interfacePackage.getName() + '.';
-        this.accessors        = new IdentityHashMap<>(); // Also defined in readObject(…)
+        this.accessors        = new ConcurrentHashMap<>(); // Also defined in readObject(…)
+        if (dependencies.length == 0) {
+            this.dependencies = null;
+        } else {
+            this.dependencies = dependencies = dependencies.clone();
+            for (int i=0; i<dependencies.length; i++) {
+                ensureNonNullElement("dependencies", i, dependencies[i]);
+            }
+        }
     }
 
     /**
@@ -200,11 +219,25 @@ public class MetadataStandard implements
      *
      * @param citation         Bibliographical reference to the international standard.
      * @param interfacePackage The root package for metadata interfaces.
+     * @param dependencies     The dependencies to other metadata standards, or {@code null}
if none.
      */
-    MetadataStandard(final String citation, final String interfacePackage) {
+    MetadataStandard(final String citation, final String interfacePackage, final MetadataStandard[]
dependencies) {
         this.citation         = new SimpleCitation(citation);
         this.interfacePackage = interfacePackage;
-        this.accessors        = new IdentityHashMap<>();
+        this.accessors        = new ConcurrentHashMap<>();
+        this.dependencies     = dependencies; // No clone, since this constructor is for
internal use only.
+    }
+
+    /**
+     * Returns {@code true} if class or interface of the given name is supported by this
standard.
+     * This method verifies if the class is a member of the package given at construction
time or
+     * a sub-package. This method does not verify if the type is supported by a dependency.
+     *
+     * @param  classname The name of the type to verify.
+     * @return {@code true} if the given type is supported by this standard.
+     */
+    final boolean isSupported(final String classname) {
+        return classname.startsWith(interfacePackage);
     }
 
     /**
@@ -220,16 +253,16 @@ public class MetadataStandard implements
      * @return The metadata standard for the given type, or {@code null} if not found.
      */
     public static MetadataStandard forClass(final Class<?> type) {
-        String name = type.getName();
+        String classname = type.getName();
         for (final MetadataStandard candidate : INSTANCES) {
-            if (name.startsWith(candidate.interfacePackage)) {
+            if (candidate.isSupported(classname)) {
                 return candidate;
             }
         }
         for (final Class<?> interf : Classes.getAllInterfaces(type)) {
-            name = interf.getName();
+            classname = interf.getName();
             for (final MetadataStandard candidate : INSTANCES) {
-                if (name.startsWith(candidate.interfacePackage)) {
+                if (candidate.isSupported(classname)) {
                     return candidate;
                 }
             }
@@ -243,9 +276,7 @@ public class MetadataStandard implements
      */
     static void clearCache() {
         for (final MetadataStandard standard : INSTANCES) {
-            synchronized (standard.accessors) {
-                standard.accessors.clear();
-            }
+            standard.accessors.clear();
         }
     }
 
@@ -279,25 +310,53 @@ public class MetadataStandard implements
      *         of the expected package and {@code mandatory} is {@code true}.
      */
     final PropertyAccessor getAccessor(final Class<?> implementation, final boolean
mandatory) {
-        synchronized (accessors) {
-            // Check for previously created accessors.
-            final Object value = accessors.get(implementation);
-            if (value instanceof PropertyAccessor) {
-                return (PropertyAccessor) value;
-            }
-            // Check if we started some computation that we can finish.
-            final Class<?> type;
-            if (value != null) {
-                type = (Class<?>) value;
-            } else {
-                // Nothing were computed. Try to compute now.
-                type = findInterface(implementation);
-                if (type == null) {
-                    if (mandatory) {
-                        throw new ClassCastException(Errors.format(Errors.Keys.UnknownType_1,
implementation));
+        /*
+         * Check for accessors created by previous call to this method.
+         * Values are added to this cache but never cleared.
+         */
+        final Object value = accessors.get(implementation);
+        if (value instanceof PropertyAccessor) {
+            return (PropertyAccessor) value;
+        }
+        /*
+         * Check if we started some computation that we can finish. A partial computation
exists
+         * when we already found the Class<?> for the interface, but didn't created
the accessor.
+         */
+        final Class<?> type;
+        if (value instanceof Class<?>) {
+            type = (Class<?>) value; // Stored result of previous call to findInterface(…).
+            assert type == findInterface(implementation) : implementation;
+        } else {
+            /*
+             * Nothing was computed, we need to start from scratch. The first step is to
find
+             * the interface implemented by the given class. If we can not find an interface,
+             * we will delegate to the dependencies and store the result for avoiding redoing
+             * this search next time.
+             */
+            type = findInterface(implementation);
+            if (type == null) {
+                if (dependencies != null) {
+                    for (final MetadataStandard dependency : dependencies) {
+                        final PropertyAccessor accessor = dependency.getAccessor(implementation,
false);
+                        if (accessor != null) {
+                            accessors.put(implementation, accessor); // Ok to overwrite existing
instance here.
+                            return accessor;
+                        }
                     }
-                    return null;
                 }
+                if (mandatory) {
+                    throw new ClassCastException(Errors.format(Errors.Keys.UnknownType_1,
implementation));
+                }
+                return null;
+            }
+        }
+        /*
+         * Found the interface for which to create an accessor. Creates the accessor now,
unless an accessor
+         * has been created concurrently in another thread in which case the later will be
returned.
+         */
+        return (PropertyAccessor) accessors.compute(implementation, (k, v) -> {
+            if (v instanceof PropertyAccessor) {
+                return v;
             }
             final PropertyAccessor accessor;
             if (SpecialCases.isSpecialCase(type)) {
@@ -312,15 +371,14 @@ public class MetadataStandard implements
                 final boolean onlyUML = (type == implementation && !type.isInterface());
                 accessor = new PropertyAccessor(citation, type, implementation, onlyUML);
             }
-            accessors.put(implementation, accessor);
             return accessor;
-        }
+        });
     }
 
     /**
-     * Returns {@code true} if the given type is assignable to a type from this standard.
-     * If this method returns {@code true}, then invoking {@link #getInterface(Class)} is
-     * guaranteed to succeed without throwing an exception.
+     * Returns {@code true} if the given type is assignable to a type from this standard
or one of its dependencies.
+     * If this method returns {@code true}, then invoking {@link #getInterface(Class)} is
guaranteed to succeed
+     * without throwing an exception.
      *
      * @param  type The implementation class (can be {@code null}).
      * @return {@code true} if the given class is an interface of this standard,
@@ -328,16 +386,27 @@ public class MetadataStandard implements
      */
     public boolean isMetadata(final Class<?> type) {
         if (type != null) {
-            synchronized (accessors) {
-                if (accessors.containsKey(type)) {
-                    return true;
-                }
-                final Class<?> standardType = findInterface(type);
-                if (standardType != null) {
-                    accessors.put(type, standardType);
-                    return true;
+            if (accessors.containsKey(type)) {
+                return true;
+            }
+            if (dependencies != null) {
+                for (final MetadataStandard dependency : dependencies) {
+                    if (dependency.isMetadata(type)) {
+                        accessors.putIfAbsent(type, dependency);
+                        return true;
+                    }
                 }
             }
+            /*
+             * At this point, all cached values (including those in dependencies) have been
checked.
+             * Performs the 'findInterface' computation only in last resort. Current implementation
+             * does not store negative results in order to avoid filling the cache with unrelated
classes.
+             */
+            final Class<?> standardType = findInterface(type);
+            if (standardType != null) {
+                accessors.putIfAbsent(type, standardType);
+                return true;
+            }
         }
         return false;
     }
@@ -359,13 +428,15 @@ public class MetadataStandard implements
      * Only one metadata interface can be implemented. If the given type is already
      * an interface from the standard, then it is returned directly.
      *
+     * <p>This method ignores dependencies. Fallback on metadata standard dependencies
shall be done by the caller.</p>
+     *
      * @param  type The standard interface or the implementation class.
      * @return The single interface, or {@code null} if none where found.
      */
     private Class<?> findInterface(final Class<?> type) {
         if (type != null) {
             if (type.isInterface()) {
-                if (type.getName().startsWith(interfacePackage)) {
+                if (isSupported(type.getName())) {
                     return type;
                 }
             } else {
@@ -423,7 +494,7 @@ public class MetadataStandard implements
      */
     private void getInterfaces(final Class<?> type, final Collection<Class<?>>
interfaces) {
         for (final Class<?> candidate : type.getInterfaces()) {
-            if (candidate.getName().startsWith(interfacePackage)) {
+            if (isSupported(candidate.getName())) {
                 interfaces.add(candidate);
             }
             getInterfaces(candidate, interfaces);
@@ -452,25 +523,32 @@ public class MetadataStandard implements
     @SuppressWarnings("unchecked")
     public <T> Class<? super T> getInterface(final Class<T> type) throws
ClassCastException {
         ensureNonNull("type", type);
-        final Class<?> standard;
-        synchronized (accessors) {
-            final Object value = accessors.get(type);
-            if (value != null) {
-                if (value instanceof PropertyAccessor) {
-                    standard = ((PropertyAccessor) value).type;
-                } else {
-                    standard = (Class<?>) value;
-                }
+        final Class<?> interf;
+        final Object value = accessors.get(type);
+        if (value instanceof PropertyAccessor) {
+            interf = ((PropertyAccessor) value).type;
+        } else if (value instanceof Class<?>) {
+            interf = (Class<?>) value;
+        } else if (value instanceof MetadataStandard) {
+            interf = ((MetadataStandard) value).getInterface(type);
+        } else {
+            interf = findInterface(type);
+            if (interf != null) {
+                accessors.putIfAbsent(type, interf);
             } else {
-                standard = findInterface(type);
-                if (standard == null) {
-                    throw new ClassCastException(Errors.format(Errors.Keys.UnknownType_1,
type));
+                if (dependencies != null) {
+                    for (final MetadataStandard dependency : dependencies) {
+                        if (dependency.isMetadata(type)) {
+                            accessors.putIfAbsent(type, dependency);
+                            return dependency.getInterface(type);
+                        }
+                    }
                 }
-                accessors.put(type, standard);
+                throw new ClassCastException(Errors.format(Errors.Keys.UnknownType_1, type));
             }
         }
-        assert standard.isAssignableFrom(type) : type;
-        return (Class<? super T>) standard;
+        assert interf.isAssignableFrom(type) : type;
+        return (Class<? super T>) interf;
     }
 
     /**
@@ -793,8 +871,17 @@ public class MetadataStandard implements
         if (metadata1 == null || metadata2 == null) {
             return false;
         }
-        final PropertyAccessor accessor = getAccessor(metadata1.getClass(), true);
-        if (accessor.type != findInterface(metadata2.getClass())) {
+        final Class<?> type1 = metadata1.getClass();
+        final Class<?> type2 = metadata2.getClass();
+        if (type1 != type2 && mode == ComparisonMode.STRICT) {
+            return false;
+        }
+        final PropertyAccessor accessor = getAccessor(type1, true);
+        if (type1 != type2 && (!accessor.type.isAssignableFrom(type2) || accessor.type
!= getAccessor(type2, false).type)) {
+            /*
+             * Note: the check for (accessor.type != getAccessor(…).type) would have been
enough, but checking
+             * for isAssignableFrom(…) first can avoid the (relatively costly) creation
of new PropertyAccessor.
+             */
             return false;
         }
         /*
@@ -867,7 +954,7 @@ public class MetadataStandard implements
         try {
             final Field field = classe.getDeclaredField(name);
             field.setAccessible(true);
-            field.set(this, new IdentityHashMap<>());
+            field.set(this, new ConcurrentHashMap<>());
         } catch (ReflectiveOperationException e) {
             throw new AssertionError(e); // Should never happen (tested by MetadataStandardTest).
         }

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java?rev=1627067&r1=1627066&r2=1627067&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
[UTF-8] Tue Sep 23 15:48:30 2014
@@ -74,11 +74,12 @@ final class StandardImplementation exten
      * @param interfacePackage      The root package for metadata interfaces, with a trailing
{@code '.'}.
      * @param implementationPackage The root package for metadata implementations. with a
trailing {@code '.'}.
      * @param acronyms              An array of (full text, acronyms) pairs. This array is
not cloned.
+     * @param dependencies          The dependencies to other metadata standards, or {@code
null} if none.
      */
-    StandardImplementation(final String citation, final String interfacePackage,
-            final String implementationPackage, final String[] acronyms)
+    StandardImplementation(final String citation, final String interfacePackage, final String
implementationPackage,
+            final String[] acronyms, final MetadataStandard[] dependencies)
     {
-        super(citation, interfacePackage);
+        super(citation, interfacePackage, dependencies);
         this.implementationPackage = implementationPackage;
         this.acronyms              = acronyms;
         this.implementations       = new IdentityHashMap<>();
@@ -120,8 +121,8 @@ final class StandardImplementation exten
          * CodeLists, Enums and Exceptions.
          */
         if (type != null && type.isInterface()) {
-            String name = type.getName();
-            if (name.startsWith(interfacePackage)) {
+            String classname = type.getName();
+            if (isSupported(classname)) {
                 synchronized (implementations) {
                     Class<?> candidate = implementations.get(type);
                     if (candidate != null) {
@@ -133,7 +134,7 @@ final class StandardImplementation exten
                      * have been replaced by their acronym (if any).
                      */
                     final StringBuilder buffer = new StringBuilder(implementationPackage)
-                            .append(name, interfacePackage.length(), name.length());
+                            .append(classname, interfacePackage.length(), classname.length());
                     if (acronyms != null) {
                         for (int i=0; i<acronyms.length; i+=2) {
                             final String acronym = acronyms[i];
@@ -149,9 +150,9 @@ final class StandardImplementation exten
                      */
                     final int prefixPosition = buffer.lastIndexOf(".") + 1;
                     buffer.insert(prefixPosition, isAbstract(type) ? "Abstract" : "Default");
-                    name = buffer.toString();
+                    classname = buffer.toString();
                     try {
-                        candidate = Class.forName(name);
+                        candidate = Class.forName(classname);
                         implementations.put(type, candidate);
                         return candidate.asSubclass(type);
                     } catch (ClassNotFoundException e) {

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java?rev=1627067&r1=1627066&r2=1627067&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
[UTF-8] Tue Sep 23 15:48:30 2014
@@ -23,12 +23,15 @@ import java.util.HashSet;
 import java.util.Collection;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.quality.Completeness;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.coverage.grid.RectifiedGrid;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.metadata.iso.citation.HardCodedCitations;
 import org.apache.sis.metadata.iso.acquisition.DefaultPlatform;
 import org.apache.sis.metadata.iso.acquisition.DefaultInstrument;
 import org.apache.sis.metadata.iso.quality.AbstractCompleteness;
+import org.apache.sis.internal.simple.SimpleIdentifiedObject;
 import org.apache.sis.util.iso.SimpleInternationalString;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.test.DependsOnMethod;
@@ -67,13 +70,79 @@ import static org.apache.sis.test.TestUt
     ValueMapTest.class})
 public final strictfp class MetadataStandardTest extends TestCase {
     /**
+     * Tests {@link MetadataStandard#isMetadata(Class)}.
+     */
+    @Test
+    public void testIsMetadata() {
+        MetadataStandard std = MetadataStandard.ISO_19115;
+        assertFalse("isMetadata(String)",                 std.isMetadata(String.class));
+        assertTrue ("isMetadata(Citation)",               std.isMetadata(Citation.class));
+        assertTrue ("isMetadata(DefaultCitation)",        std.isMetadata(DefaultCitation.class));
+        assertFalse("isMetadata(IdentifiedObject)",       std.isMetadata(IdentifiedObject.class));
+        assertFalse("isMetadata(SimpleIdentifiedObject)", std.isMetadata(SimpleIdentifiedObject.class));
+        assertFalse("isMetadata(GeographicCRS)",          std.isMetadata(GeographicCRS.class));
+        assertFalse("isMetadata(RectifiedGrid)",          std.isMetadata(RectifiedGrid.class));
+
+        std = MetadataStandard.ISO_19111;
+        assertFalse("isMetadata(String)",                 std.isMetadata(String.class));
+        assertTrue ("isMetadata(Citation)",               std.isMetadata(Citation.class));
         // Dependency
+        assertTrue ("isMetadata(DefaultCitation)",        std.isMetadata(DefaultCitation.class));
  // Dependency
+        assertTrue ("isMetadata(IdentifiedObject)",       std.isMetadata(IdentifiedObject.class));
+        assertTrue ("isMetadata(SimpleIdentifiedObject)", std.isMetadata(SimpleIdentifiedObject.class));
+        assertTrue ("isMetadata(GeographicCRS)",          std.isMetadata(GeographicCRS.class));
+        assertFalse("isMetadata(RectifiedGrid)",          std.isMetadata(RectifiedGrid.class));
+
+        std = MetadataStandard.ISO_19123;
+        assertFalse("isMetadata(String)",                 std.isMetadata(String.class));
+        assertTrue ("isMetadata(Citation)",               std.isMetadata(Citation.class));
              // Transitive dependency
+        assertTrue ("isMetadata(DefaultCitation)",        std.isMetadata(DefaultCitation.class));
       // Transivive dependency
+        assertTrue ("isMetadata(IdentifiedObject)",       std.isMetadata(IdentifiedObject.class));
      // Dependency
+        assertTrue ("isMetadata(SimpleIdentifiedObject)", std.isMetadata(SimpleIdentifiedObject.class));
// Dependency
+        assertTrue ("isMetadata(GeographicCRS)",          std.isMetadata(GeographicCRS.class));
         // Dependency
+        assertTrue ("isMetadata(RectifiedGrid)",          std.isMetadata(RectifiedGrid.class));
+    }
+
+    /**
      * Tests {@link MetadataStandard#getInterface(Class)}.
      */
     @Test
+    @DependsOnMethod("testIsMetadata")
     public void testGetInterface() {
-        final MetadataStandard std = MetadataStandard.ISO_19115;
-        assertEquals(Citation.class,     std.getInterface(DefaultCitation.class));
-        assertEquals(Completeness.class, std.getInterface(AbstractCompleteness.class));
+        MetadataStandard std = MetadataStandard.ISO_19115;
+        assertEquals("getInterface(Citation)",             Citation.class,     std.getInterface(Citation.class));
+        assertEquals("getInterface(DefaultCitation)",      Citation.class,     std.getInterface(DefaultCitation.class));
+        assertEquals("getInterface(AbstractCompleteness)", Completeness.class, std.getInterface(AbstractCompleteness.class));
+
+        std = MetadataStandard.ISO_19111;
+        assertEquals("getInterface(Citation)",               Citation.class,         std.getInterface(Citation.class));
+        assertEquals("getInterface(DefaultCitation)",        Citation.class,         std.getInterface(DefaultCitation.class));
+        assertEquals("getInterface(AbstractCompleteness)",   Completeness.class,     std.getInterface(AbstractCompleteness.class));
+        assertEquals("getInterface(IdentifiedObject)",       IdentifiedObject.class, std.getInterface(IdentifiedObject.class));
+        assertEquals("getInterface(SimpleIdentifiedObject)", IdentifiedObject.class, std.getInterface(SimpleIdentifiedObject.class));
+        assertEquals("getInterface(GeographicCRS)",          GeographicCRS.class,    std.getInterface(GeographicCRS.class));
+
+        // Verify that the cache has not been updated in inconsistent way.
+        testIsMetadata();
+    }
+
+    /**
+     * Tests {@link MetadataStandard#getAccessor(Class, boolean)}.
+     */
+    @Test
+    @DependsOnMethod("testGetInterface")
+    public void testGetAccessor() {
+        MetadataStandard std = MetadataStandard.ISO_19115;
+        assertEquals("getAccessor(DefaultCitation)",      Citation.class,     std.getAccessor(DefaultCitation.class,
true).type);
+        assertEquals("getAccessor(AbstractCompleteness)", Completeness.class, std.getAccessor(AbstractCompleteness.class,
true).type);
+        assertNull  ("getAccessor(SimpleIdentifiedObject)",                   std.getAccessor(SimpleIdentifiedObject.class,
false));
+
+        std = MetadataStandard.ISO_19111;
+        assertEquals("getAccessor(DefaultCitation)",        Citation.class,         std.getAccessor(DefaultCitation.class,
true).type);
+        assertEquals("getAccessor(AbstractCompleteness)",   Completeness.class,     std.getAccessor(AbstractCompleteness.class,
true).type);
+        assertEquals("getAccessor(SimpleIdentifiedObject)", IdentifiedObject.class, std.getAccessor(SimpleIdentifiedObject.class,
true).type);
+
+        // Verify that the cache has not been updated in inconsistent way.
+        testGetInterface();
     }
 
     /**
@@ -81,8 +150,9 @@ public final strictfp class MetadataStan
      * A {@link ClassCastException} is expected.
      */
     @Test
+    @DependsOnMethod("testGetInterface")
     public void testGetWrongInterface() {
-        final MetadataStandard std = new MetadataStandard("SIS", "org.apache.sis.dummy.");
+        final MetadataStandard std = new MetadataStandard("SIS", "org.apache.sis.dummy.",
null);
         try {
             std.getInterface(DefaultCitation.class);
             fail("No dummy interface expected.");
@@ -96,6 +166,7 @@ public final strictfp class MetadataStan
      * Tests the {@link MetadataStandard#equals(Object, Object, ComparisonMode)} method.
      */
     @Test
+    @DependsOnMethod("testGetAccessor")
     public void testEquals() {
         final MetadataStandard std = MetadataStandard.ISO_19115;
 
@@ -150,6 +221,7 @@ public final strictfp class MetadataStan
      * {@code MetadataStandard} methods depend on it ({@code equals}, {@code hashCode}, {@code
prune}, <i>etc.</i>).
      */
     @Test
+    @DependsOnMethod("testGetAccessor")
     public void testValueMap() {
         final DefaultCitation instance = new DefaultCitation(HardCodedCitations.EPSG);
         final Map<String,Object> map = MetadataStandard.ISO_19115.asValueMap(instance,
@@ -224,10 +296,12 @@ public final strictfp class MetadataStan
      * be accessible even if there is no implementation on the classpath.
      */
     @Test
+    @DependsOnMethod("testGetAccessor")
     public void testWithoutImplementation() {
         final MetadataStandard std = MetadataStandard.ISO_19123;
-        assertFalse("isMetadata(Citation)",        std.isMetadata(Citation.class));
-        assertFalse("isMetadata(DefaultCitation)", std.isMetadata(DefaultCitation.class));
+        assertFalse("isMetadata(String)",          std.isMetadata(String.class));
+        assertTrue ("isMetadata(Citation)",        std.isMetadata(Citation.class));     
   // Transitive dependency
+        assertTrue ("isMetadata(DefaultCitation)", std.isMetadata(DefaultCitation.class));
 // Transitive dependency
         assertTrue ("isMetadata(RectifiedGrid)",   std.isMetadata(RectifiedGrid.class));
         /*
          * Ensure that the getters have been found.



Mime
View raw message