Author: desruisseaux
Date: Mon Feb 19 10:42:38 2018
New Revision: 1824730

URL: http://svn.apache.org/viewvc?rev=1824730&view=rev
Log:
Fix PositionalAccuracyTest. This require a partial implementation of xsi:type 
attribute renaming.
This fix is incomplete - see https://issues.apache.org/jira/browse/SIS-399

Modified:
    
sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java
    
sis/branches/ISO-19115-3/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy
 (legacy).xml
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformedEvent.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/Transformer.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingReader.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingWriter.java
    
sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/ImportNames.lst

Modified: 
sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java?rev=1824730&r1=1824729&r2=1824730&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/quality/AbstractPositionalAccuracyTest.java
 [UTF-8] Mon Feb 19 10:42:38 2018
@@ -18,11 +18,13 @@ package org.apache.sis.metadata.iso.qual
 
 import java.util.Locale;
 import javax.xml.bind.JAXBException;
+import org.opengis.metadata.quality.Result;
 import org.opengis.util.InternationalString;
 import org.apache.sis.xml.FreeTextMarshallingTest;
 import org.apache.sis.util.Version;
 import org.apache.sis.test.XMLTestCase;
 import org.apache.sis.test.DependsOn;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import static org.opengis.test.Assert.*;
@@ -51,10 +53,11 @@ public final strictfp class AbstractPosi
      *
      * @throws JAXBException if an error occurred during the during 
marshalling / unmarshalling processes.
      *
-     * @see <a href="http://jira.geotoolkit.org/browse/GEOTK-107";>GEOTK-107</a>
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-394";>Issue 
SIS-394</a>
      * @see FreeTextMarshallingTest
      */
     @Test
+    @Ignore("Depends on SIS-394")
     public void testXML() throws JAXBException {
         roundtrip("PositionalAccuracy.xml", VERSION_2014);
     }
@@ -63,6 +66,9 @@ public final strictfp class AbstractPosi
      * Tests the (un)marshalling of a text group from/to legacy ISO 19139:2007 
schema.
      *
      * @throws JAXBException if an error occurred during the during 
marshalling / unmarshalling processes.
+     *
+     * @see <a href="http://jira.geotoolkit.org/browse/GEOTK-107";>GEOTK-107</a>
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-399";>SIS-399</a>
      */
     @Test
     public void testLegacyXML() throws JAXBException {
@@ -87,8 +93,9 @@ public final strictfp class AbstractPosi
          * Opportunist test. While it was not the purpose of this test, the 
above metadata
          * needs to contain a "result" element in order to pass XML validation 
test.
          */
-        assertInstanceOf("Wrong value for <gmd:result>", 
DefaultConformanceResult.class,
-                getSingleton(metadata.getResults()));
+        final Result result = getSingleton(metadata.getResults());
+        assertInstanceOf("Wrong value for <gmd:result>", 
DefaultConformanceResult.class, result);
+        assertEquals("result.pass", Boolean.TRUE, ((DefaultConformanceResult) 
result).pass());
         /*
          * Marshalling: ensure that we didn't lost any information.
          */

Modified: 
sis/branches/ISO-19115-3/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy
 (legacy).xml
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy%20%28legacy%29.xml?rev=1824730&r1=1824729&r2=1824730&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy
 (legacy).xml (original)
+++ 
sis/branches/ISO-19115-3/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/quality/PositionalAccuracy
 (legacy).xml Mon Feb 19 10:42:38 2018
@@ -21,6 +21,7 @@
 <gmd:DQ_RelativeInternalPositionalAccuracy
     xmlns:gmd = "http://www.isotc211.org/2005/gmd";
     xmlns:gco = "http://www.isotc211.org/2005/gco";
+    xmlns:lan = "http://standards.iso.org/iso/19115/-3/lan/1.0";
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance";
     xsi:schemaLocation = "http://www.isotc211.org/2005/gmd 
http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd";>
 

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformedEvent.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformedEvent.java?rev=1824730&r1=1824729&r2=1824730&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformedEvent.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformedEvent.java
 [UTF-8] Mon Feb 19 10:42:38 2018
@@ -157,7 +157,7 @@ abstract class TransformedEvent<E extend
      * Wrapper over an attribute emitted during the reading or writing of an 
XML document.
      * This wrapper is used for changing the namespace of the attribute.
      */
-    static final class Attr extends TransformedEvent<Attribute> implements 
Attribute {
+    static class Attr extends TransformedEvent<Attribute> implements Attribute 
{
         /** Wraps the given event with a different name. */
         Attr(final Attribute event, final QName name) {
             super(event, name);
@@ -180,6 +180,22 @@ abstract class TransformedEvent<E extend
     }
 
     /**
+     * The attribute for {@code "xsi:type"}.
+     */
+    static final class TypeAttr extends Attr {
+        /** The attribute value. */
+        private final String value;
+
+        /** Wraps the given event with a different name. */
+        TypeAttr(final Attribute event, final QName name, final String value) {
+            super(event, name);
+            this.value = value;
+        }
+
+        @Override public String getValue() {return value;}
+    }
+
+    /**
      * Wrapper over an element emitted during the reading or writing of an XML 
document.
      * This wrapper is used for changing the namespace and sometime the name 
of the element.
      */

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/Transformer.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/Transformer.java?rev=1824730&r1=1824729&r2=1824730&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/Transformer.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/Transformer.java
 [UTF-8] Mon Feb 19 10:42:38 2018
@@ -29,6 +29,7 @@ import java.io.LineNumberReader;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Namespace;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.CollectionsExt;
@@ -138,7 +139,7 @@ abstract class Transformer {
 
     /**
      * Properties of the last outer elements, or {@code null} if not yet 
determined.
-     * If non-empty, this is one of the values got from the map given in 
argument to {@link #open(QName, Map)}.
+     * If non-empty, this is one of the values got from the map given in 
argument to {@link #open(QName)}.
      */
     private Map<String,String> outerElementProperties;
 
@@ -149,10 +150,19 @@ abstract class Transformer {
     final List<Attribute> renamedAttributes;
 
     /**
+     * The namespaces associated to prefixes in the source. When 
unmarshalling, this is for the namespaces in
+     * the source XML document (e.g. using legacy ISO 19139:2007 standard). 
When marshalling, this is for the
+     * namespaces in the JAXB annotations (e.g. using newer ISO 19115-3 
standard).  This is used for handling
+     * {@code xsi:type} attribute values.
+     */
+    private final Map<String,String> namespaces;
+
+    /**
      * Creates a new XML reader or writer.
      */
     Transformer(final TransformVersion version) {
         this.version           = version;
+        namespaces             = new HashMap<>();
         outerElements          = new ArrayList<>();
         renamedAttributes      = new ArrayList<>();
         outerElementProperties = Collections.emptyMap();
@@ -276,6 +286,15 @@ abstract class Transformer {
     }
 
     /**
+     * Notifies that a new namespace is declared in the source. When 
unmarshalling, this is for a namespace
+     * in the source XML document (e.g. using legacy ISO 19139:2007 standard). 
When marshalling, this is for
+     * a namespaces in the JAXB annotations (e.g. using newer ISO 19115-3 
standard).
+     */
+    final void notify(final Namespace namespace) {
+        namespaces.put(namespace.getPrefix(), namespace.getNamespaceURI());
+    }
+
+    /**
      * Returns a snapshot of {@link #renamedAttributes} list and clears the 
later.
      */
     final List<Attribute> attributes() {
@@ -291,6 +310,53 @@ abstract class Transformer {
     }
 
     /**
+     * Imports or exports an attribute read or write from/to the XML document.
+     * If there is no name change, then this method returns the given instance 
as-is.
+     * This method performs a special check for the {@code "xsi:type"} 
attribute:
+     * its value is parsed as a name and converted.
+     */
+    final Attribute convert(Attribute attribute) throws XMLStreamException {
+        final QName originalName = attribute.getName();
+        if ("type".equals(originalName.getLocalPart()) && 
Namespaces.XSI.equals(originalName.getNamespaceURI())) {
+            /*
+             * In the special case of "xsi:type", do not convert the attribute 
name.
+             * Instead, parse and convert the attribute value.
+             */
+            final String value = attribute.getValue();
+            if (value != null) {
+                final int s = value.indexOf(':');
+                if (s >= 0) {
+                    String prefix = value.substring(0, s);
+                    String ns = namespaces.get(prefix);
+                    if (ns != null) {
+                        String localPart = value.substring(s+1);
+                        final Map<String,String> renaming = 
renamingMap().get(localPart);
+                        if (renaming != null) {
+                            QName name = new QName(ns, localPart, prefix);
+                            final Map<String,String> currentMap = 
outerElementProperties;
+                            outerElementProperties = renaming;
+                            name = convert(name);
+                            outerElementProperties = currentMap;
+                            prefix    = name.getPrefix();
+                            localPart = name.getLocalPart();
+                            final String exported = prefix + ':' + localPart;
+                            if (!exported.equals(value)) {
+                                return new 
TransformedEvent.TypeAttr(attribute, originalName, exported);
+                            }
+                        }
+                    }
+                }
+            }
+        } else {    // For all attributes other than "xsi:type", convert the 
attribute name.
+            final QName name = convert(originalName);
+            if (name != originalName) {
+                attribute = new TransformedEvent.Attr(attribute, name);
+            }
+        }
+        return attribute;
+    }
+
+    /**
      * Returns {@code true} if an element with the given name is an OGC/ISO 
type (as opposed to property).
      * For example given the following XML, this method returns {@code true} 
for {@code cit:CI_Date} but
      * {@code false} for {@code cit:date}:
@@ -317,14 +383,13 @@ abstract class Transformer {
     /**
      * Notifies that we are opening an element of the given name.
      *
-     * @param  name        element name as declared in JAXB annotations.
-     * @param  namespaces  namespaces map loaded by {@link #load(String, int)}.
+     * @param  name  element name as declared in JAXB annotations.
      */
-    final void open(final QName name, final Map<String, Map<String,String>> 
namespaces) {
+    final void open(final QName name) {
         final String localPart = name.getLocalPart();
         if (isTypeElement(localPart)) {
             outerElements.add(name);
-            outerElementProperties = namespaces.getOrDefault(localPart, 
Collections.emptyMap());
+            outerElementProperties = renamingMap().getOrDefault(localPart, 
Collections.emptyMap());
         }
     }
 
@@ -333,17 +398,16 @@ abstract class Transformer {
      * with a matching name. It should be the last element on the list in a 
well-formed XML, but we loop in
      * the list anyway as a safety.
      *
-     * @param  name        element name as declared in JAXB annotations.
-     * @param  namespaces  namespaces map loaded by {@link #load(String, int)}.
+     * @param  name  element name as declared in JAXB annotations.
      */
-    final void close(final QName name, final Map<String, Map<String,String>> 
namespaces) {
+    final void close(final QName name) {
         if (isTypeElement(name.getLocalPart())) {
             outerElementProperties = null;
             for (int i=outerElements.size(); --i >= 0;) {
                 if (name.equals(outerElements.get(i))) {
                     outerElements.remove(i);
                     final String parent = (--i >= 0) ? 
outerElements.get(i).getLocalPart() : null;
-                    outerElementProperties = namespaces.getOrDefault(parent, 
Collections.emptyMap());
+                    outerElementProperties = 
renamingMap().getOrDefault(parent, Collections.emptyMap());
                     break;
                 }
             }
@@ -391,6 +455,12 @@ abstract class Transformer {
     }
 
     /**
+     * Returns the map loaded by {@link #load(String, int)}.
+     * This is a static field in the {@link TransformingReader} or {@link 
TransformingWriter} subclass.
+     */
+    abstract Map<String, Map<String,String>> renamingMap();
+
+    /**
      * Returns the new namespace for elements (types and properties) in the 
given namespace.
      * This method is used only for default relocations, i.e. the fallback to 
apply when no
      * explicit rule has been found.

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingReader.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingReader.java?rev=1824730&r1=1824729&r2=1824730&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingReader.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingReader.java
 [UTF-8] Mon Feb 19 10:42:38 2018
@@ -65,7 +65,7 @@ final class TransformingReader extends T
      * <ul>
      *   <li>Keys are XML names of types, ignoring {@code "_TYPE"} suffix 
(e.g. {@code "CI_Citation"})</li>
      *   <li>Values are maps where:<ul>
-     *     <li>Keys are XML names of properties (e.g. {@code "title"}) or 
{@value #TYPE_KEY}</li>
+     *     <li>Keys are XML names of properties (e.g. {@code "title"}).</li>
      *     <li>Values are either:<ul>
      *       <li>Namespace URI if {@link #isNamespace(String)} returns {@code 
true} for that value.</li>
      *       <li>New name of the element otherwise. In such case, the map must 
be queried again with
@@ -222,7 +222,7 @@ final class TransformingReader extends T
             case START_ELEMENT: {
                 final StartElement e = event.asStartElement();
                 final QName originalName = e.getName();
-                open(originalName, NAMESPACES);                 // Must be 
invoked before 'convert(QName)'.
+                open(originalName);                         // Must be invoked 
before 'convert(QName)'.
                 final QName name = convert(originalName);
                 boolean changed = name != originalName;
                 for (final Iterator<Attribute> it = e.getAttributes(); 
it.hasNext();) {
@@ -249,7 +249,7 @@ final class TransformingReader extends T
                 if (namespaces != null) {
                     event = new TransformedEvent.End(e, name, namespaces);
                 }
-                close(originalName, NAMESPACES);            // Must be invoked 
only after 'convert(QName)'
+                close(originalName);                    // Must be invoked 
only after 'convert(QName)'
                 break;
             }
         }
@@ -257,16 +257,12 @@ final class TransformingReader extends T
     }
 
     /**
-     * Imports an attribute read from the XML document.
-     * If there is no name change, then this method returns the given instance 
as-is.
+     * Returns the map loaded by {@link #load(String, int)}.
      */
-    private Attribute convert(Attribute attribute) throws XMLStreamException {
-        final QName originalName = attribute.getName();
-        final QName name = convert(originalName);
-        if (name != originalName) {
-            attribute = new TransformedEvent.Attr(attribute, name);
-        }
-        return attribute;
+    @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final Map<String, Map<String,String>> renamingMap() {
+        return NAMESPACES;
     }
 
     /**
@@ -308,6 +304,7 @@ final class TransformingReader extends T
      * @param  newURI     the new URI for {@code oldURI}, or {@code null} if 
{@code newURI} is null.
      */
     private Namespace importNS(final Namespace namespace, final String oldURI, 
final String newURI) {
+        notify(namespace);
         String uri = namespace.getNamespaceURI();
         if (uri != null && !uri.isEmpty()) {
             uri = removeTrailingSlash(uri);

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingWriter.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingWriter.java?rev=1824730&r1=1824729&r2=1824730&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingWriter.java
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/TransformingWriter.java
 [UTF-8] Mon Feb 19 10:42:38 2018
@@ -178,6 +178,15 @@ final class TransformingWriter extends T
     }
 
     /**
+     * Returns the map loaded by {@link #load(String, int)}.
+     */
+    @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final Map<String, Map<String,String>> renamingMap() {
+        return NAMESPACES;
+    }
+
+    /**
      * Returns the old namespace for elements (types and properties) in the 
given namespace.
      * This method is used only for default relocations, i.e. the fallback to 
apply when no
      * explicit rule has been found.
@@ -220,19 +229,6 @@ final class TransformingWriter extends T
     }
 
     /**
-     * Returns the attribute to write in the XML document.
-     * If there is no name change, then this method returns the given instance 
as-is.
-     */
-    private Attribute export(Attribute attribute) throws XMLStreamException {
-        final QName originalName = attribute.getName();
-        final QName name = convert(originalName);
-        if (name != originalName) {
-            attribute = new TransformedEvent.Attr(attribute, name);
-        }
-        return attribute;
-    }
-
-    /**
      * Returns the namespace to write in the XML document. This may imply a 
prefix change.
      * If there is no namespace change, then this method returns the given 
instance as-is.
      * To test if the returned namespace is a new one, callers should check if 
the size of
@@ -241,6 +237,7 @@ final class TransformingWriter extends T
      * @param  namespace  the namespace to export.
      */
     private Namespace exportIfNew(final Namespace namespace) {
+        notify(namespace);
         String uri = namespace.getNamespaceURI();
         if (uri != null && !uri.isEmpty()) {
             final String exported = relocate(removeTrailingSlash(uri));
@@ -300,7 +297,7 @@ final class TransformingWriter extends T
     public void add(XMLEvent event) throws XMLStreamException {
         switch (event.getEventType()) {
             case ATTRIBUTE: {
-                event = export((Attribute) event);
+                event = convert((Attribute) event);
                 break;
             }
             case NAMESPACE: {
@@ -326,19 +323,19 @@ final class TransformingWriter extends T
                         writeDeferred();                        // About to 
exit the parent element containing deferred element.
                     }
                 }
-                close(originalName, NAMESPACES);                // Must be 
invoked only after 'convert(QName)'
+                close(originalName);                            // Must be 
invoked only after 'convert(QName)'
                 break;
             }
             case START_ELEMENT: {
                 uniqueNamespaces.clear();                       // Discard 
entries created by NAMESPACE events.
                 final StartElement e = event.asStartElement();
                 final QName originalName = e.getName();
-                open(originalName, NAMESPACES);                 // Must be 
invoked before 'convert(QName)'.
+                open(originalName);                             // Must be 
invoked before 'convert(QName)'.
                 final QName name = convert(originalName);
                 boolean changed = name != originalName;
                 for (final Iterator<Attribute> it = e.getAttributes(); 
it.hasNext();) {
                     final Attribute a = it.next();
-                    final Attribute ae = export(a);
+                    final Attribute ae = convert(a);
                     changed |= (a != ae);
                     renamedAttributes.add(ae);
                 }

Modified: 
sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/ImportNames.lst
URL: 
http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/ImportNames.lst?rev=1824730&r1=1824729&r2=1824730&view=diff
==============================================================================
--- 
sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/ImportNames.lst
 [UTF-8] (original)
+++ 
sis/branches/ISO-19115-3/core/sis-utility/src/main/resources/org/apache/sis/xml/ImportNames.lst
 [UTF-8] Mon Feb 19 10:42:38 2018
@@ -128,15 +128,18 @@ http://standards.iso.org/iso/19115/-3/ge
   verticalCRS
 http://standards.iso.org/iso/19115/-3/lan/1.0
  CountryCode
+ Country_PropertyType
  LanguageCode
+ LanguageCode_PropertyType
  LocalisedCharacterString
  MD_CharacterSetCode
+ PT_FreeText_PropertyType
+ PT_FreeText
+  textGroup
  PT_Locale
   characterEncoding
   country
   language
- textGroup
-  <type>
 http://standards.iso.org/iso/19115/-3/mac/1.0
  MI_AcquisitionInformation
   acquisitionPlan
@@ -915,6 +918,7 @@ http://standards.iso.org/iso/19157/-2/md
   result
  DQ_ConformanceResult
   explanation
+  pass
   specification
  DQ_DataQuality
   report


Reply via email to