This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 420564d  Remove (for now) the attempt to use unique metadata instances 
on invocation of ModifiableMetadata.apply(State.FINAL). The current attempt was 
incomplete. The MetadataVisitor now available should make easier to make a new 
attempt later. This may happen in the context of the GeoTIFF and netCDF readers 
development (consolidation of GeoTIFF and netCDF metadata was the trigger for 
this MetadataVisitor effort).
420564d is described below

commit 420564d81320b746053a67f352b276bd1bbec31e
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Mon Jul 2 19:16:16 2018 +0200

    Remove (for now) the attempt to use unique metadata instances on invocation 
of ModifiableMetadata.apply(State.FINAL).
    The current attempt was incomplete. The MetadataVisitor now available 
should make easier to make a new attempt later.
    This may happen in the context of the GeoTIFF and netCDF readers development
    (consolidation of GeoTIFF and netCDF metadata was the trigger for this 
MetadataVisitor effort).
---
 .../org/apache/sis/metadata/MetadataCopier.java    |  3 +-
 .../org/apache/sis/metadata/MetadataVisitor.java   | 21 +++++--
 .../java/org/apache/sis/metadata/StateChanger.java | 66 ++++++++--------------
 3 files changed, 40 insertions(+), 50 deletions(-)

diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java
index 329a6e9..b0ecffc 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java
@@ -197,7 +197,8 @@ public class MetadataCopier extends MetadataVisitor<Object> 
{
 
     /**
      * Returns the metadata instance resulting from the copy. This method is 
invoked <strong>before</strong>
-     * metadata properties are visited.
+     * metadata properties are visited. The returned value is a new, initially 
empty, metadata instance
+     * created by {@link #preVisit(PropertyAccessor)}.
      */
     @Override
     final Object result() {
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataVisitor.java 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataVisitor.java
index b64e160..d3423a7 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataVisitor.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataVisitor.java
@@ -266,12 +266,21 @@ abstract class MetadataVisitor<R> {
 
     /**
      * Returns the result of visiting all elements in a metadata instance.
-     * This method is invoked exactly once per metadata instance.
-     * It is usually invoked after all metadata properties have been visited
-     * (or after a {@link #visit(Class, Object)} method call returned {@link 
#SKIP_SIBLINGS}),
-     * unless {@link #preVisit(PropertyAccessor)} returned {@link 
Filter#WRITABLE_RESULT}
-     * in which case this method is invoked <strong>before</strong> metadata 
properties are visited.
+     * This method is invoked zero or one time per metadata instance.
+     * The invocation time depends on the value returned by {@link 
#preVisit(PropertyAccessor)}:
+     *
+     * <ul>
+     *   <li>If {@link Filter#NONE}, then this method is never invoked for the 
current metadata instance.</li>
+     *   <li>If {@link Filter#NON_EMPTY} or {@link Filter#WRITABLE}, then this 
method is invoked after all properties
+     *       have been visited or after {@link #visit(Class, Object)} returned 
{@link #SKIP_SIBLINGS}.</li>
+     *   <li>If {@link Filter#WRITABLE_RESULT}, then this method is invoked 
<strong>before</strong> metadata
+     *       properties are visited. In such case, this method should return 
an initially empty instance.</li>
+     * </ul>
+     *
      * The value returned by this method will be cached in case the same 
metadata instance is revisited again.
+     * This value can be {@code null}.
      */
-    abstract R result();
+    R result() {
+        return null;
+    }
 }
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/metadata/StateChanger.java 
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/StateChanger.java
index 8c25e3a..da08937 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/StateChanger.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/StateChanger.java
@@ -21,7 +21,6 @@ import java.util.Set;
 import java.util.EnumSet;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import org.apache.sis.internal.util.Cloner;
 import org.apache.sis.util.collection.CodeListSet;
@@ -56,12 +55,6 @@ final class StateChanger extends MetadataVisitor<Boolean> {
     private ModifiableMetadata.State target;
 
     /**
-     * All objects made immutable during iteration over children properties.
-     * Keys and values are the same instances. This is used for sharing unique 
instances when possible.
-     */
-    private final Map<Object,Object> existings;
-
-    /**
      * The cloner, created when first needed.
      */
     private Cloner cloner;
@@ -70,7 +63,6 @@ final class StateChanger extends MetadataVisitor<Boolean> {
      * Creates a new {@code StateChanger} instance.
      */
     private StateChanger() {
-        existings = new HashMap<>(32);
     }
 
     /**
@@ -104,29 +96,28 @@ final class StateChanger extends MetadataVisitor<Boolean> {
     }
 
     /**
-     * Returns a unique instance of the given object (metadata or value).
+     * Invoked for metadata instances on which to apply a change of state.
+     *
+     * @param  type    ignored (can be {@code null}).
+     * @param  object  the object to transition to a different state.
+     * @return the given object or a copy of the given object with its state 
changed.
      */
-    private Object unique(final Object object) {
-        if (object != null) {
-            final Object c = existings.putIfAbsent(object, object);
-            if (c != null) {
-                return c;
-            }
-        }
-        return object;
+    @Override
+    final Object visit(final Class<?> type, final Object object) throws 
CloneNotSupportedException {
+        return applyTo(object);
     }
 
     /**
      * Recursively change the state of all elements in the given array.
      */
-    private void applyTo(final Object[] array) throws 
CloneNotSupportedException {
+    private void applyToAll(final Object[] array) throws 
CloneNotSupportedException {
         for (int i=0; i < array.length; i++) {
-            array[i] = visit(null, array[i]);
+            array[i] = applyTo(array[i]);
         }
     }
 
     /**
-     * Returns an unmodifiable copy of the specified object.
+     * Returns the given object, or a copy of the given object, with its state 
changed.
      * This method performs the following heuristic tests:
      *
      * <ul>
@@ -140,26 +131,24 @@ final class StateChanger extends MetadataVisitor<Boolean> 
{
      *   <li>Otherwise, the object is assumed immutable and returned 
unchanged.</li>
      * </ul>
      *
-     * @param  type    ignored (can be {@code null}).
-     * @param  object  the object to convert in an immutable one.
-     * @return a presumed immutable view of the specified object.
+     * @param  object  the object to transition to a different state.
+     * @return the given object or a copy of the given object with its state 
changed.
      */
-    @Override
-    final Object visit(final Class<?> type, final Object object) throws 
CloneNotSupportedException {
+    private Object applyTo(final Object object) throws 
CloneNotSupportedException {
         /*
          * CASE 1 - The object is an org.apache.sis.metadata.* implementation.
-         *          It may have its own algorithm for freezing itself.
+         *          It may have its own algorithm for changing its state.
          */
         if (object instanceof ModifiableMetadata) {
             ((ModifiableMetadata) object).apply(target);
-            return unique(object);
+            return object;
         }
         if (target != ModifiableMetadata.State.FINAL) {
             return object;
         }
         if (object instanceof DefaultRepresentativeFraction) {
             ((DefaultRepresentativeFraction) object).freeze();
-            return unique(object);
+            return object;
         }
         /*
          * CASE 2 - The object is a collection. All elements are replaced by 
their
@@ -177,7 +166,7 @@ final class StateChanger extends MetadataVisitor<Boolean> {
                     break;
                 }
                 case 1: {
-                    final Object value = visit(null, array[0]);
+                    final Object value = applyTo(array[0]);
                     collection = isSet ? Collections.singleton(value)
                                        : Collections.singletonList(value);
                     break;
@@ -189,7 +178,7 @@ final class StateChanger extends MetadataVisitor<Boolean> {
                         } else if (collection instanceof CodeListSet<?>) {
                             collection = 
Collections.unmodifiableSet(((CodeListSet<?>) collection).clone());
                         } else {
-                            applyTo(array);
+                            applyToAll(array);
                             collection = CollectionsExt.immutableSet(false, 
array);
                         }
                     } else {
@@ -198,7 +187,7 @@ final class StateChanger extends MetadataVisitor<Boolean> {
                          * Conservatively assumes a List if we are not sure to 
have a Set since the list
                          * is less destructive (no removal of duplicated 
values).
                          */
-                        applyTo(array);
+                        applyToAll(array);
                         collection = UnmodifiableArrayList.wrap(array);
                     }
                     break;
@@ -213,7 +202,7 @@ final class StateChanger extends MetadataVisitor<Boolean> {
         if (object instanceof Map<?,?>) {
             final Map<Object,Object> map = new LinkedHashMap<>((Map<?,?>) 
object);
             for (final Map.Entry<Object,Object> entry : map.entrySet()) {
-                entry.setValue(visit(null, entry.getValue()));
+                entry.setValue(applyTo(entry.getValue()));
             }
             return CollectionsExt.unmodifiableOrCopy(map);
         }
@@ -224,20 +213,11 @@ final class StateChanger extends MetadataVisitor<Boolean> 
{
             if (cloner == null) {
                 cloner = new Cloner(false);
             }
-            return unique(cloner.clone(object));
+            return cloner.clone(object);
         }
         /*
          * CASE 5 - Any other case. The object is assumed immutable and 
returned unchanged.
          */
-        return unique(object);
-    }
-
-    /**
-     * Returns an arbitrary value used by {@link MetadataVisitor} for 
remembering that
-     * a metadata instance has been processed.
-     */
-    @Override
-    Boolean result() {
-        return Boolean.TRUE;
+        return object;
     }
 }

Reply via email to