sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1452355 - in /sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata: MetadataStandard.java ModifiableMetadata.java
Date Mon, 04 Mar 2013 15:57:49 GMT
Author: desruisseaux
Date: Mon Mar  4 15:57:48 2013
New Revision: 1452355

URL: http://svn.apache.org/r1452355
Log:
Completed the port of a few methods.

Modified:
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1452355&r1=1452354&r2=1452355&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
[UTF-8] Mon Mar  4 15:57:48 2013
@@ -27,6 +27,7 @@ import org.opengis.metadata.citation.Cit
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.util.SystemListener;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
@@ -78,14 +79,6 @@ import static org.apache.sis.util.Argume
 @ThreadSafe
 public class MetadataStandard {
     /**
-     * The package of SIS implementation of ISO 19115.
-     * This package name has a trailing dot.
-     *
-     * @see #interfacePackage
-     */
-    static final String SIS_PACKAGE = "org.apache.sis.metadata.iso.";
-
-    /**
      * Metadata instances defined in this class. The current implementation does not yet
      * contains the user-defined instances. However this may be something we will need to
      * do in the future.
@@ -119,7 +112,7 @@ public class MetadataStandard {
         final String[] prefix = {"Default", "Abstract"};
         final String[] acronyms = {"CoordinateSystem", "CS", "CoordinateReferenceSystem",
"CRS"};
         ISO_19111 = new StandardImplementation("ISO 19111", "org.opengis.referencing.", "org.apache.sis.referencing.",
prefix, acronyms);
-        ISO_19115 = new StandardImplementation("ISO 19115", "org.opengis.metadata.", SIS_PACKAGE,
prefix, null);
+        ISO_19115 = new StandardImplementation("ISO 19115", "org.opengis.metadata.", "org.apache.sis.metadata.iso.",
prefix, null);
         ISO_19119 = new StandardImplementation("ISO 19119", "org.opengis.service.",  null,
null, null);
         ISO_19123 = new StandardImplementation("ISO 19123", "org.opengis.coverage.", null,
null, null);
         INSTANCES = new MetadataStandard[] {
@@ -128,6 +121,11 @@ public class MetadataStandard {
             ISO_19119,
             ISO_19123
         };
+        SystemListener.add(new SystemListener() {
+            @Override protected void classpathChanged() {
+                clearCache();
+            }
+        });
     }
 
     /**
@@ -214,6 +212,18 @@ public class MetadataStandard {
     }
 
     /**
+     * Clears the cache of accessors. This method is invoked when the classpath changed,
+     * in order to discard the references to classes that may need to be unloaded.
+     */
+    static void clearCache() {
+        for (final MetadataStandard standard : INSTANCES) {
+            synchronized (standard.accessors) {
+                standard.accessors.clear();
+            }
+        }
+    }
+
+    /**
      * Returns a bibliographical reference to the international standard.
      * The default implementation return the citation given at construction time.
      *
@@ -257,10 +267,10 @@ public class MetadataStandard {
                 // Nothing were computed. Try to compute now.
                 type = findInterface(implementation);
                 if (type == null) {
-                    if (!mandatory) {
-                        return null;
+                    if (mandatory) {
+                        throw new ClassCastException(Errors.format(Errors.Keys.UnknownType_1,
type));
                     }
-                    throw new ClassCastException(Errors.format(Errors.Keys.UnknownType_1,
type));
+                    return null;
                 }
             }
             final PropertyAccessor accessor = new PropertyAccessor(citation, type, implementation);
@@ -280,11 +290,6 @@ public class MetadataStandard {
      */
     public boolean isMetadata(final Class<?> type) {
         if (type != null) {
-            // Checks if the class is an interface from the standard.
-            if (type.isInterface() && type.getName().startsWith(interfacePackage))
{
-                return true;
-            }
-            // Checks if the class is an implementation of the standard.
             synchronized (accessors) {
                 if (accessors.containsKey(type)) {
                     return true;
@@ -384,10 +389,21 @@ public class MetadataStandard {
      */
     public Class<?> getInterface(final Class<?> type) throws ClassCastException
{
         ensureNonNull("type", type);
-        if (type.getName().startsWith(interfacePackage)) {
-            return type;
+        synchronized (accessors) {
+            final Object value = accessors.get(type);
+            if (value != null) {
+                if (value instanceof PropertyAccessor) {
+                    return ((PropertyAccessor) value).type;
+                }
+                return (Class<?>) value;
+            }
+            final Class<?> standard = findInterface(type);
+            if (standard == null) {
+                throw new ClassCastException(Errors.format(Errors.Keys.UnknownType_1, type));
+            }
+            accessors.put(type, standard);
+            return standard;
         }
-        throw new UnsupportedOperationException(); // TODO: port Geotk code here.
     }
 
     /**

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java?rev=1452355&r1=1452354&r2=1452355&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
[UTF-8] Mon Mar  4 15:57:48 2013
@@ -24,8 +24,10 @@ import java.util.NoSuchElementException;
 import net.jcip.annotations.ThreadSafe;
 import org.opengis.util.CodeList;
 import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.collection.CheckedHashSet;
 import org.apache.sis.util.collection.CheckedArrayList;
+import org.apache.sis.internal.jaxb.MarshalContext;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.util.collection.CollectionsExt.isNullOrEmpty;
@@ -83,6 +85,21 @@ import static org.apache.sis.util.collec
 @ThreadSafe
 public abstract class ModifiableMetadata extends AbstractMetadata implements Cloneable {
     /**
+     * A null implementation for the {@link #FREEZING} constant.
+     */
+    private static final class Null extends ModifiableMetadata {
+        @Override public MetadataStandard getStandard() {
+            return null;
+        }
+    }
+
+    /**
+     * A flag used for {@link #unmodifiable} in order to specify that
+     * {@link #freeze()} is under way.
+     */
+    private static final ModifiableMetadata FREEZING = new Null();
+
+    /**
      * An unmodifiable copy of this metadata, created only when first needed.
      * If {@code null}, then no unmodifiable entity is available.
      * If {@code this}, then this entity is itself unmodifiable.
@@ -182,7 +199,14 @@ public abstract class ModifiableMetadata
      */
     public synchronized void freeze() {
         if (isModifiable()) {
-            throw new UnsupportedOperationException("Not yet implemented."); // TODO
+            ModifiableMetadata success = null;
+            try {
+                unmodifiable = FREEZING;
+                getStandard().freeze(this);
+                success = this;
+            } finally {
+                unmodifiable = success;
+            }
         }
     }
 
@@ -199,7 +223,7 @@ public abstract class ModifiableMetadata
     protected void checkWritePermission() throws UnmodifiableMetadataException {
         assert Thread.holdsLock(this);
         if (!isModifiable()) {
-            throw new UnmodifiableMetadataException("Unmodifiable metadata"); // TODO: localize
+            throw new UnmodifiableMetadataException(Errors.format(Errors.Keys.UnmodifiableMetadata));
         }
         unmodifiable = null;
     }
@@ -227,12 +251,16 @@ public abstract class ModifiableMetadata
      *
      * @see #nonNullList(List, Class)
      */
+    @SuppressWarnings("unchecked")
     protected final <E> List<E> copyList(final Collection<? extends E>
source,
             List<E> target, final Class<E> elementType)
             throws UnmodifiableMetadataException
     {
         // See the comments in copyCollection(...) for implementation notes.
         if (source != target) {
+            if (unmodifiable == FREEZING) {
+                return (List<E>) source;
+            }
             checkWritePermission();
             if (isNullOrEmpty(source)) {
                 target = null;
@@ -271,12 +299,16 @@ public abstract class ModifiableMetadata
      *
      * @see #nonNullSet(Set, Class)
      */
+    @SuppressWarnings("unchecked")
     protected final <E> Set<E> copySet(final Collection<? extends E> source,
             Set<E> target, final Class<E> elementType)
             throws UnmodifiableMetadataException
     {
         // See the comments in copyCollection(...) for implementation notes.
         if (source != target) {
+            if (unmodifiable == FREEZING) {
+                return (Set<E>) source;
+            }
             checkWritePermission();
             if (isNullOrEmpty(source)) {
                 target = null;
@@ -321,6 +353,7 @@ public abstract class ModifiableMetadata
      *         elements, or {@code null} if the source was null.
      * @throws UnmodifiableMetadataException if this metadata is unmodifiable.
      */
+    @SuppressWarnings("unchecked")
     protected final <E> Collection<E> copyCollection(final Collection<? extends
E> source,
             Collection<E> target, final Class<E> elementType)
             throws UnmodifiableMetadataException
@@ -331,6 +364,14 @@ public abstract class ModifiableMetadata
          * This optimization is required for efficient working of PropertyAccessor.set(...).
          */
         if (source != target) {
+            if (unmodifiable == FREEZING) {
+                /*
+                 * freeze() method is under progress. The source collection is already
+                 * an unmodifiable instance created by unmodifiable(Object).
+                 */
+                assert collectionType(elementType).isAssignableFrom(source.getClass());
+                return (Collection<E>) source;
+            }
             checkWritePermission();
             if (isNullOrEmpty(source)) {
                 target = null;
@@ -352,6 +393,15 @@ public abstract class ModifiableMetadata
     }
 
     /**
+     * Returns {@code true} if the caller {@code nonNullCollection} method (or list, or set)
+     * is allowed to returns {@code null} instead than an empty list. This happen mostly
at
+     * XML marshalling time.
+     */
+    private static boolean isMarshaling() {
+        return MarshalContext.isFlagSet(MarshalContext.current(), MarshalContext.MARSHALING);
+    }
+
+    /**
      * Returns the specified list, or a new one if {@code c} is null.
      * This is a convenience method for implementation of {@code getFoo()}
      * methods.
@@ -365,7 +415,10 @@ public abstract class ModifiableMetadata
     protected final <E> List<E> nonNullList(final List<E> c, final Class<E>
elementType) {
         assert Thread.holdsLock(this);
         if (c != null) {
-            return c;
+            return c.isEmpty() && isMarshaling() ? null : c;
+        }
+        if (isMarshaling()) {
+            return null;
         }
         if (isModifiable()) {
             return new MutableList<>(elementType);
@@ -387,7 +440,10 @@ public abstract class ModifiableMetadata
     protected final <E> Set<E> nonNullSet(final Set<E> c, final Class<E>
elementType) {
         assert Thread.holdsLock(this);
         if (c != null) {
-            return c;
+            return c.isEmpty() && isMarshaling() ? null : c;
+        }
+        if (isMarshaling()) {
+            return null;
         }
         if (isModifiable()) {
             return new MutableSet<>(elementType);
@@ -419,7 +475,10 @@ public abstract class ModifiableMetadata
         assert Thread.holdsLock(this);
         if (c != null) {
             assert collectionType(elementType).isAssignableFrom(c.getClass());
-            return c;
+            return c.isEmpty() && isMarshaling() ? null : c;
+        }
+        if (isMarshaling()) {
+            return null;
         }
         final boolean isModifiable = isModifiable();
         if (useSet(elementType)) {
@@ -513,7 +572,7 @@ public abstract class ModifiableMetadata
         if (List.class.isAssignableFrom(type)) {
             return false;
         }
-        throw new NoSuchElementException("Unsupported data type");
+        throw new NoSuchElementException(Errors.format(Errors.Keys.UnsupportedType_1, type));
     }
 
     /**



Mime
View raw message