Author: desruisseaux
Date: Tue Feb 13 14:56:15 2018
New Revision: 1824147

URL: http://svn.apache.org/viewvc?rev=1824147&view=rev
Log:
Clarification of FilteredNamespaces role. First test on property renaming.

Modified:
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilterVersion.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredNamespaces.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredWriter.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/NamespaceContent.txt
    
sis/branches/ISO-19115-3/core/sis-utility/src/test/java/org/apache/sis/xml/FilteredNamespacesTest.java

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilterVersion.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilterVersion.java?rev=1824147&r1=1824146&r2=1824147&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilterVersion.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilterVersion.java
 [UTF-8] Tue Feb 13 14:56:15 2018
@@ -18,6 +18,7 @@ package org.apache.sis.xml;
 
 import java.util.Map;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Collections;
 import javax.xml.namespace.QName;
 import org.apache.sis.internal.jaxb.LegacyNamespaces;
@@ -92,8 +93,7 @@ final class FilterVersion {
 
     /**
      * GML using the legacy {@code "http://www.opengis.net/gml"} namespace.
-     * Note that the use of GML 3.2 may imply the use of ISO 19139:2007,
-     * which requires the use of {@link #ALL}.
+     * Note that the use of GML 3.2 implies the use of ISO 19139:2007.
      */
     static final FilterVersion GML31 = new FilterVersion(ISO19139);
     static {
@@ -170,11 +170,11 @@ final class FilterVersion {
     /**
      * The URI replacements to apply when going from the filtered 
reader/writer to the
      * model implemented by Apache SIS. This map is the converse of {@link 
#exports}.
+     * It does not contain the map of properties to rename because that map is 
handled
+     * by {@link FilteredReader} instead, as part of {@code 
NamespaceContent.txt} file.
      *
      * <p>This map shall not be modified after construction.
      * We do not wrap in {@link Collections#unmodifiableMap(Map)} for 
efficiency.</p>
-     *
-     * @see #imports()
      */
     private final Map<String, String> imports;
 
@@ -248,38 +248,36 @@ final class FilterVersion {
 
     /**
      * Converts a namespace used in JAXB annotation to the namespace used in 
XML document.
+     * Returns the same URI if there is no replacement.
      */
     final String exportNS(final String uri) {
         final FilterVersion.Replacement r = exports.get(uri);
         return (r != null) ? r.namespace : uri;
     }
 
-    final Replacement export(final String uri) {
-        return exports.get(uri);
-    }
-
     /**
      * Converts a namespace used in XML document to the namespace used in JAXB 
annotation.
+     * Returns the same URI if there is no replacement.
      */
     final String importNS(final String uri) {
         return imports.getOrDefault(uri, uri);
     }
 
     /**
-     * Returns the URI replacements to apply when going from the model 
implemented by Apache SIS to the
-     * filtered reader/writer. Used only for more sophisticated work than what 
{@link #exportNS(String)}
-     * does. Wrapped in a {@link Collections#unmodifiableMap(Map)} for safety.
+     * Converts a namespace used in JAXB annotation to the namespace used in 
XML document,
+     * together with a map of properties to rename.
+     * Returns {@code null} if there is no replacement.
      */
-    final Map<String, Replacement> exports() {
-        return Collections.unmodifiableMap(exports);
+    final Replacement export(final String uri) {
+        return exports.get(uri);
     }
 
     /**
-     * Returns the URI replacements to apply when going from the filtered 
reader/writer to the model implemented
-     * by Apache SIS. Used only for mor sophisticated work than what {@link 
#exportNS(String)} does. Wrapped in
-     * a {@link Collections#unmodifiableMap(Map)} for safety.
+     * Returns the URI replacements to apply when going from the model 
implemented by Apache SIS to the
+     * filtered reader/writer. Used only for more sophisticated work than what 
{@link #exportNS(String)} does.
+     * Returned as an iterator for avoiding to expose modifiable map; do not 
invoke {@link Iterator#remove()}.
      */
-    final Map<String, String> imports() {
-        return Collections.unmodifiableMap(imports);
+    final Iterator<Map.Entry<String, Replacement>> exports() {
+        return exports.entrySet().iterator();
     }
 }

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java?rev=1824147&r1=1824146&r2=1824147&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java
 [UTF-8] Tue Feb 13 14:56:15 2018
@@ -245,24 +245,29 @@ abstract class FilteredEvent<E extends X
             return null;
         }
 
-        /** Gets a read-only namespace context. */
-        @Override public NamespaceContext getNamespaceContext() {
-            final NamespaceContext context = event.getNamespaceContext();
-            return (context != null) ? new FilteredNamespaces(context, 
version) : null;
+        /**
+         * Gets a read-only namespace context.
+         *
+         * @see FilteredWriter#getNamespaceContext()
+         */
+        @Override
+        public NamespaceContext getNamespaceContext() {
+            return FilteredNamespaces.exportNS(event.getNamespaceContext(), 
version);
         }
 
-        /** Gets the value that the prefix is bound to in the context of this 
element. */
-        @Override public String getNamespaceURI(final String prefix) {
-            final NamespaceContext context = event.getNamespaceContext();
-            if (context != null) {
-                final String uri = context.getNamespaceURI(prefix);
-                return version.exportNS(uri);
-            }
-            return null;
+        /**
+         * Gets the value that the prefix is bound to in the context of this 
element.
+         */
+        @Override
+        public String getNamespaceURI(final String prefix) {
+            return version.exportNS(event.getNamespaceURI(prefix));
         }
 
-        /** Writes the event as per the XML 1.0 without indentation or 
whitespace. */
-        @Override void write(final Appendable out) throws IOException {
+        /**
+         * Writes the event as per the XML 1.0 without indentation or 
whitespace.
+         */
+        @Override
+        void write(final Appendable out) throws IOException {
             name(out.append('<'));
             final int n = attributes.size();
             for (int i=0; i<n; i++) {

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredNamespaces.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredNamespaces.java?rev=1824147&r1=1824146&r2=1824147&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredNamespaces.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredNamespaces.java
 [UTF-8] Tue Feb 13 14:56:15 2018
@@ -64,6 +64,51 @@ import javax.xml.XMLConstants;
  */
 class FilteredNamespaces implements NamespaceContext {
     /**
+     * Given the context for namespaces used in our JAXB annotations, returns 
a context working with namespaces
+     * used in XML document. The returned context converts namespace arguments 
from XML to JAXB namespaces, and
+     * converts returned namespaces from JAXB to XML. Prefixes are left 
unchanged since they can be arbitrary
+     * (even if not the standard match for a given namespace).
+     *
+     * <div class="note"><b>Example:</b>
+     * for a {@code "http://www.isotc211.org/2005/gmd"} namespace (legacy ISO 
19139:2007) given in argument to
+     * {@link #getPrefixes(String)}, the context convert that namespace to all 
possible ISO 19115-3 namespaces
+     * (there is many) and returns the associated prefixes: {@code "mdb"}, 
{@code "cit"}, <i>etc.</i>
+     * Conversely given a {@code "mdb"}, {@code "cit"}, <i>etc.</i>, prefix, 
{@link #getNamespaceURI(String)}
+     * method returns the above-cited legacy GMD namespace.</div>
+     *
+     * This can be used when a {@link javax.xml.stream.XMLStreamWriter} has 
been created for writing with JAXB
+     * annotations and we want to expose an {@code XMLStreamReader} for 
writing a legacy XML document.
+     */
+    static NamespaceContext exportNS(NamespaceContext context, final 
FilterVersion version) {
+        if (context != null) {
+            if (context instanceof Import && ((Import) context).version == 
version) {
+                context = ((Import) context).context;
+            } else {
+                context = new FilteredNamespaces(context, version);
+            }
+        }
+        return context;
+    }
+
+    /**
+     * Given a context for namespaces used in XML document, returns a context 
working with the namespaces used
+     * in our JAXB annotations.  The returned context converts namespace 
arguments from JAXB to XML namespaces
+     * before to delegate to the wrapped context, and converts returned 
namespaces from XML to JAXB.  This can
+     * be used when a {@link javax.xml.stream.XMLStreamReader} has been 
created for reading a legacy XML document
+     * and we want to expose an {@code XMLStreamReader} for JAXB.
+     */
+    static NamespaceContext importNS(NamespaceContext context, final 
FilterVersion version) {
+        if (context != null) {
+            if (context.getClass() == FilteredNamespaces.class && 
((FilteredNamespaces) context).version == version) {
+                context = ((FilteredNamespaces) context).context;
+            } else {
+                context = new FilteredNamespaces.Import(context, version);
+            }
+        }
+        return context;
+    }
+
+    /**
      * The context to wrap, given by {@link FilteredReader} or {@link 
FilteredWriter}.
      *
      * @see javax.xml.stream.XMLStreamReader#getNamespaceContext()
@@ -79,38 +124,24 @@ class FilteredNamespaces implements Name
     /**
      * Creates a new namespaces filter for the given target version.
      */
-    FilteredNamespaces(final NamespaceContext context, final FilterVersion 
version) {
+    private FilteredNamespaces(final NamespaceContext context, final 
FilterVersion version) {
         this.context = context;
         this.version = version;
     }
 
     /**
-     * Returns the inverse of {@code FilteredNamespaces}.
-     */
-    NamespaceContext inverse(final FilterVersion target) {
-        return (version == target) ? context : new Import(context, target);
-    }
-
-    /**
      * Substitutes the XML namespaces used in XML documents by namespaces used 
in JAXB annotations.
-     * This is used at unmarshalling time for importing legacy documents.
+     * This is used at unmarshalling time for importing legacy documents, 
performing the reverse of
+     * {@link FilteredNamespaces}. The <i>namespace → prefix</i> mapping is 
simpler because various
+     * ISO 19115-3 namespaces are mapped to the same legacy {@code "gmd"} 
prefix.
      */
-    static final class Import extends FilteredNamespaces {
-        /**
-         * Creates a new namespaces filter for the given source version.
-         */
+    private static final class Import extends FilteredNamespaces {
+        /** Creates a new namespaces filter for the given source version. */
         Import(final NamespaceContext context, final FilterVersion version) {
             super(context, version);
         }
 
         /**
-         * Returns the inverse of this namespace.
-         */
-        @Override NamespaceContext inverse(final FilterVersion target) {
-            return (version == target) ? context : new 
FilteredNamespaces(context, target);
-        }
-
-        /**
          * Returns the namespace used in JAXB annotations for the given prefix 
in XML document.
          * If no unique namespace can be mapped (for example if asking the 
namespace of legacy
          * {@code "gmd"} prefix), returns {@link XMLConstants#NULL_NS_URI}.
@@ -173,7 +204,9 @@ class FilteredNamespaces implements Name
          * legacy ISO 19139:2007) is mapped to multiple namespaces in the new 
ISO 19115-3:2016 or other standard.
          * In such case, we have to iterate over 'exports' entries until we 
find an inverse mapping.
          */
-        for (final Map.Entry<String, FilterVersion.Replacement> e : 
version.exports().entrySet()) {
+        final Iterator<Map.Entry<String, FilterVersion.Replacement>> it = 
version.exports();
+        while (it.hasNext()) {
+            final Map.Entry<String, FilterVersion.Replacement> e = it.next();
             if (namespaceURI.equals(e.getValue().namespace)) {
                 p = context.getPrefix(e.getKey());
                 if (p != null) return p;
@@ -213,9 +246,11 @@ class FilteredNamespaces implements Name
         private String next;
 
         /** Creates a new iterator for the prefixes associated to the given 
namespace URI. */
-        Prefixes(final NamespaceContext context, final Map<String, 
FilterVersion.Replacement> exports, final String namespaceURI) {
+        Prefixes(final NamespaceContext context, final 
Iterator<Map.Entry<String, FilterVersion.Replacement>> exports,
+                 final String namespaceURI)
+        {
             this.context      = context;
-            this.exports      = exports.entrySet().iterator();
+            this.exports      = exports;
             this.namespaceURI = namespaceURI;
         }
 

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java?rev=1824147&r1=1824146&r2=1824147&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java
 [UTF-8] Tue Feb 13 14:56:15 2018
@@ -205,6 +205,13 @@ final class FilteredReader extends Strea
     private final List<String> outerElements;
 
     /**
+     * The {@code localPart} argument given to {@link #namespaceOf(String)}, 
potentially renamed.
+     * For example given the {@code "DCP/distributedComputingPlatform"} entry 
in {@value #FILENAME} file,
+     * a call to {@code namespaceOf("DCP")} will set this field to {@code 
"distributedComputingPlatform"}.
+     */
+    private String renamed;
+
+    /**
      * Creates a new filter for the given version of the standards.
      */
     FilteredReader(final XMLStreamReader in, final FilterVersion version) {
@@ -268,6 +275,10 @@ final class FilteredReader extends Strea
      * @return a namespace for the given type, or {@code null} if unknown.
      */
     static String namespace(final String type) {
+        /*
+         * Same implementation than namespaceOf(type) but without 
DECLARING_TYPES.get(…)
+         * since that value should alway be null for class names.
+         */
         final Map<String,String> attributes = NAMESPACES.get(type);
         return (attributes != null) ? attributes.get(TYPE_KEY) : null;
     }
@@ -281,10 +292,13 @@ final class FilteredReader extends Strea
      *          or {@code null} if the given name is unknown.
      */
     private String namespaceOf(final String localPart) {
+        renamed = localPart;
         final Set<String> declaringTypes = DECLARING_TYPES.get(localPart);
         if (declaringTypes == null) {
             /*
              * If the element is a root element, return the associated 
namespace.
+             * We do not need to check if the value associated to TYPE_KEY is 
for
+             * a renaming since it is never the case for that key.
              */
             final Map<String,String> attributes = NAMESPACES.get(localPart);
             if (attributes != null) {
@@ -302,7 +316,13 @@ final class FilteredReader extends Strea
                      * A NullPointerException below would be a bug in our 
algorithm because
                      * we constructed DECLARING_TYPES from NAMESPACES keys 
only.
                      */
-                    return NAMESPACES.get(parent).get(localPart);
+                    final Map<String,String> attributes = 
NAMESPACES.get(parent);
+                    String uri = attributes.get(localPart);
+                    if (!isNamespace(uri)) {
+                        renamed = uri;
+                        uri = attributes.get(uri);
+                    }
+                    return uri;
                 }
             }
         }
@@ -320,8 +340,8 @@ final class FilteredReader extends Strea
         if (replacement == null) {
             replacement = version.importNS(namespaceURI);
         }
-        if (!replacement.equals(namespaceURI)) {
-            name = new QName(replacement, localPart, name.getPrefix());
+        if (!replacement.equals(namespaceURI) || !localPart.equals(renamed)) {
+            name = new QName(replacement, renamed, name.getPrefix());
         }
         return name;
     }
@@ -335,7 +355,7 @@ final class FilteredReader extends Strea
     /** Returns the context of the underlying reader wrapped in a filter that 
converts the namespaces on the fly. */
     @Override
     public NamespaceContext getNamespaceContext() {
-        return new FilteredNamespaces.Import(super.getNamespaceContext(), 
version);
+        return FilteredNamespaces.importNS(super.getNamespaceContext(), 
version);
     }
 
     /** Forwards the call, then replaces the namespace URI if needed. */

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredWriter.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredWriter.java?rev=1824147&r1=1824146&r2=1824147&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredWriter.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredWriter.java
 [UTF-8] Tue Feb 13 14:56:15 2018
@@ -276,20 +276,17 @@ final class FilteredWriter implements XM
      */
     @Override
     public void setNamespaceContext(NamespaceContext context) throws 
XMLStreamException {
-        if (context instanceof FilteredNamespaces) {
-            context = ((FilteredNamespaces) context).inverse(version);
-        } else {
-            context = new FilteredNamespaces.Import(context, version);
-        }
-        out.setNamespaceContext(context);
+        out.setNamespaceContext(FilteredNamespaces.importNS(context, version));
     }
 
     /**
      * Returns the context of the underlying writer wrapped in a filter that 
convert the namespaces on the fly.
+     *
+     * @see FilteredEvent.Start#getNamespaceContext()
      */
     @Override
     public NamespaceContext getNamespaceContext() {
-        return new FilteredNamespaces(out.getNamespaceContext(), version);
+        return FilteredNamespaces.exportNS(out.getNamespaceContext(), version);
     }
 
     /**

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/NamespaceContent.txt
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/NamespaceContent.txt?rev=1824147&r1=1824146&r2=1824147&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/NamespaceContent.txt
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/NamespaceContent.txt
 [UTF-8] Tue Feb 13 14:56:15 2018
@@ -3,6 +3,7 @@
 # Lines with zero-spaces indentation are namespace URIs.
 # Lines with two-spaces  indentation are classes.
 # Lines with four-spaces indentation are attributes.
+# old/new means that a property needs to be renamed.
 #
 http://standards.iso.org/iso/19115/-3/cit/1.0
   AbstractCI_Party
@@ -965,11 +966,11 @@ http://standards.iso.org/iso/19115/-3/sr
     <type>
     connectPoint
     dependsOn
-    distributedComputingPlatform
+    DCP/distributedComputingPlatform
     invocationName
     operationDescription
     operationName
-    parameter
+    parameters/parameter
   SV_Parameter
     <type>
     description

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/test/java/org/apache/sis/xml/FilteredNamespacesTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/test/java/org/apache/sis/xml/FilteredNamespacesTest.java?rev=1824147&r1=1824146&r2=1824147&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/test/java/org/apache/sis/xml/FilteredNamespacesTest.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/test/java/org/apache/sis/xml/FilteredNamespacesTest.java
 [UTF-8] Tue Feb 13 14:56:15 2018
@@ -51,7 +51,7 @@ public final strictfp class FilteredName
      */
     @Test
     public void testGetPrefixes() {
-        final FilteredNamespaces fns = new FilteredNamespaces(this, 
FilterVersion.ISO19139);
+        final NamespaceContext fns = FilteredNamespaces.exportNS(this, 
FilterVersion.ISO19139);
         final Iterator<String> it = fns.getPrefixes(LegacyNamespaces.GMD);
         final Set<String> prefixes = new HashSet<>();
         while (it.hasNext()) {
@@ -91,7 +91,7 @@ public final strictfp class FilteredName
      */
     @Test
     public void testGetPrefix() {
-        final FilteredNamespaces fns = new FilteredNamespaces(this, 
FilterVersion.ISO19139);
+        final NamespaceContext fns = FilteredNamespaces.exportNS(this, 
FilterVersion.ISO19139);
         /*
          * Following tests are not really interesting since FilteredNamespaces,
          * after failing to find a mapping, just delegates to 
this.getPrefix(…).


Reply via email to