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));
}
/**