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 665efa1 Avoid hard-coded value for French profile. The target namespaces are declared in the RenameOnImport.lst file instead. This complete the https://issues.apache.org/jira/browse/SIS-404 fix. 665efa1 is described below commit 665efa19686df59226d5abce9c30764e30f4b66c Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Wed Oct 10 12:38:18 2018 +0200 Avoid hard-coded value for French profile. The target namespaces are declared in the RenameOnImport.lst file instead. This complete the https://issues.apache.org/jira/browse/SIS-404 fix. --- .../main/java/org/apache/sis/xml/Transformer.java | 33 +++++++++--- .../org/apache/sis/xml/TransformingNamespaces.java | 2 - .../org/apache/sis/xml/TransformingReader.java | 46 ++++++++++------ .../org/apache/sis/xml/TransformingWriter.java | 5 +- .../src/main/java/org/apache/sis/xml/readme.html | 7 ++- .../org/apache/sis/xml/RenameOnImport.lst | 9 ++++ .../apache/sis/test/suite/MetadataTestSuite.java | 1 + .../java/org/apache/sis/xml/TransformerTest.java | 63 ++++++++++++++++++++++ .../apache/sis/xml/TransformingNamespacesTest.java | 1 - .../sis/internal/profile/fra/RenameOnImport.lst | 15 +++--- 10 files changed, 144 insertions(+), 38 deletions(-) diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/Transformer.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/Transformer.java index 0c49150..2710a19 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/xml/Transformer.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/Transformer.java @@ -96,6 +96,13 @@ import org.apache.sis.internal.jaxb.TypeRegistration; */ abstract class Transformer { /** + * Heading character for declaring a namespaces on which the remaining of the {@code Rename.lst} file applies. + * Lines with this prefix specify <em>legacy</em> namespaces to be renamed (the target of the renaming process), + * while lines without this prefix specify <em>new</em> namespaces. + */ + private static final char TARGET_PREFIX = '*'; + + /** * Character used for separating an old name from the new name. For example in {@code SV_OperationMetadata}, * {@code "DCP"} in ISO 19139:2007 has been renamed {@code "distributedComputingPlatform"} in ISO 19115-3. * This is encoded in {@value TransformingReader#FILENAME} file as {@code "DCP/distributedComputingPlatform"}. @@ -111,7 +118,7 @@ abstract class Transformer { private static final char EXTENDS = ':'; /** - * A flag after type name in files loaded by {@link #load(boolean, String, int)}, meaning that the type itself + * A flag after type name in files loaded by {@link #load(boolean, String, Set, int)}, meaning that the type itself * is in a different namespace than the properties listed below the type. For example in the following: * * {@preformat text @@ -198,8 +205,8 @@ abstract class Transformer { /** * Returns {@code true} if the given string is a namespace URI, or {@code false} if it is a property name. * This method implements a very fast check based on the presence of {@code ':'} in {@code "http://foo.bar"}. - * It assumes that all namespaces declared in files loaded by {@link #load(boolean, String, int)} use the - * {@code "http"} protocol and no property name use the {@code ':'} character. + * It assumes that all namespaces declared in files loaded by {@link #load(boolean, String, Set, int)} use + * the {@code "http"} protocol and no property name use the {@code ':'} character. */ static boolean isNamespace(final String candidate) { return (candidate.length() > 4) && (candidate.charAt(4) == ':'); @@ -235,10 +242,11 @@ abstract class Transformer { * </ul> * * @param export {@code true} for {@code "RenameOnImport.lst"}, {@code false} for {@code "RenameOnImport.lst"}. - * @param filename name of the file to load. - * @param capacity initial hash map capacity. This is only a hint. + * @param filename name of the file to load. Shall be consistent with the {@code export} flag. + * @param targets initially empty set where to add the namespaces on which the renaming will apply. + * @param capacity initial capacity for the hash map to be returned. This is only a hint. */ - static Map<String, Map<String,String>> load(final boolean export, final String filename, final int capacity) { + static Map<String, Map<String,String>> load(final boolean export, final String filename, final Set<String> targets, final int capacity) { final Map<String, Map<String,String>> m = new HashMap<>(capacity); final Set<Class<?>> renameLoaders = new LinkedHashSet<>(8); renameLoaders.add(Transformer.class); @@ -251,11 +259,18 @@ abstract class Transformer { while ((line = in.readLine()) != null) { final int length = line.length(); final int start = CharSequences.skipLeadingWhitespaces(line, 0, length); - if (start < length && line.charAt(start) != '#') { + final char startChar; + if (start < length && (startChar = line.charAt(start)) != '#') { + if (startChar == TARGET_PREFIX) { + targets.add(CharSequences.trimWhitespaces(line, start+1, line.length()).toString()); + continue; + } String element = line.substring(start).trim(); switch (start) { /* * Begin a new namespace. Must be before any class or property. + * All classes and properties read below this point will be associated + * to that namespace, until a new namespace declaration is encountered. */ case 0: { // New namespace URI. if (!isNamespace(element)) break; // Report illegal format. @@ -281,6 +296,7 @@ abstract class Transformer { parent = CharSequences.trimWhitespaces(element, s+1, element.length()).toString(); element = CharSequences.trimWhitespaces(element, 0, s).toString(); init = (k) -> { + // Inherit properties from another class. Map<String,String> properties = m.get(parent); if (properties != null) { properties = new HashMap<>(properties); @@ -290,6 +306,7 @@ abstract class Transformer { throw new NoSuchElementException(parent); }; } else { + // No property inheritance. init = (k) -> new HashMap<>(); } element = element.intern(); @@ -524,7 +541,7 @@ abstract class Transformer { } /** - * Returns the map loaded by {@link #load(boolean, String, int)}. + * Returns the map loaded by {@link #load(boolean, String, Set, int)}. * This is a static field in the {@link TransformingReader} or {@link TransformingWriter} subclass. * * @param namespace the namespace URI for which to get the substitution map (never null). diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingNamespaces.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingNamespaces.java index e80e0f4..ac97303 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingNamespaces.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingNamespaces.java @@ -147,7 +147,6 @@ class TransformingNamespaces implements NamespaceContext { * many prefixes can be created from the same namespace.</p> */ @Override - @SuppressWarnings("unchecked") // TODO: remove with JDK9 public Iterator<String> getPrefixes(final String namespaceURI) { return context.getPrefixes(version.exportNS(namespaceURI)); } @@ -232,7 +231,6 @@ class TransformingNamespaces implements NamespaceContext { * Invoking this method fetched at most one prefix from the wrapped context. */ @Override - @SuppressWarnings("unchecked") // TODO: remove on JDK9 public boolean hasNext() { while (next == null) { while (prefixes == null) { diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java index 0da5899..86e4786 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingReader.java @@ -17,8 +17,10 @@ package org.apache.sis.xml; import java.util.Map; +import java.util.Set; import java.util.List; import java.util.HashMap; +import java.util.HashSet; import java.util.ArrayList; import java.util.Iterator; import java.util.Collections; @@ -30,7 +32,6 @@ import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.StartElement; -import org.apache.sis.internal.xml.LegacyNamespaces; import org.apache.sis.util.collection.BackingStoreException; import static javax.xml.stream.XMLStreamConstants.*; @@ -56,12 +57,32 @@ final class TransformingReader extends Transformer implements XMLEventReader { * This is used for mapping legacy ISO 19139:2007 namespace to newer ISO 19115-3:2016 ones, * where the same legacy {@code "http://www.isotc211.org/2005/gmd"} URI can be replaced by * different URIs under {@code "http://standards.iso.org/iso/19115/-3/…"} depending on the - * class name. + * class name. Syntax is documented in the <a href="readme.html">readme.html</a> page. */ static final String FILENAME = "RenameOnImport.lst"; /** - * The mapping from (<var>type</var>, <var>attribute</var>) pairs to namespaces. + * Namespaces of classes containing elements to move in different namespaces. + * This set will contain at least the following namespaces: + * + * <ul> + * <li>{@value org.apache.sis.internal.xml.LegacyNamespaces#GMI}</li> + * <li>{@value org.apache.sis.internal.xml.LegacyNamespaces#GMI_ALIAS}</li> + * <li>{@value org.apache.sis.internal.xml.LegacyNamespaces#GMD}</li> + * <li>{@value org.apache.sis.internal.xml.LegacyNamespaces#SRV}</li> + * <li>{@value org.apache.sis.internal.xml.LegacyNamespaces#GCO}</li> + * <li>{@value org.apache.sis.internal.xml.LegacyNamespaces#GMX}</li> + * <li>{@value org.apache.sis.internal.xml.LegacyNamespaces#GML}</li> + * </ul> + * + * More namespaces may appear depending on the optional module on the classpath. + * For example {@code sis-french-profile} adds {@code "http://www.cnig.gouv.fr/2005/fra"}. + */ + private static final Set<String> LEGACY_NAMESPACES = new HashSet<>(12); + + /** + * The mapping from (<var>type</var>, <var>attribute</var>) pairs to new namespaces. + * This mapping will be applied only to namespaces enumerated in {@link #LEGACY_NAMESPACES}. * * <ul> * <li>Keys are XML names of types, ignoring {@code "_TYPE"} suffix (e.g. {@code "CI_Citation"})</li> @@ -77,7 +98,8 @@ final class TransformingReader extends Transformer implements XMLEventReader { * * This map is initialized only once and should not be modified after that point. */ - private static final Map<String, Map<String,String>> NAMESPACES = load(false, FILENAME, 260); + private static final Map<String, Map<String,String>> NAMESPACES = load(false, FILENAME, LEGACY_NAMESPACES, 260); + // TODO: use Set.copyOf(…) with JDK10. /** * Returns the namespace for the given ISO type, or {@code null} if unknown. @@ -209,7 +231,6 @@ final class TransformingReader extends Transformer implements XMLEventReader { * @param event the event read from the underlying event reader. * @return the converted event (may be the same instance). */ - @SuppressWarnings("unchecked") // TODO: remove on JDK9 private XMLEvent convert(XMLEvent event) throws XMLStreamException { switch (event.getEventType()) { case ATTRIBUTE: { @@ -280,7 +301,7 @@ final class TransformingReader extends Transformer implements XMLEventReader { } /** - * Returns the map loaded by {@link #load(boolean, String, int)} if the given namespace is a known legacy namespace. + * Returns the map loaded by {@link #load(boolean, String, Set, int)} if the given namespace is a known legacy namespace. * This method returns a non-empty map only for legacy namespaces for which the {@value #FILENAME} file has been designed. * This is necessary for avoiding confusion with classes of the same name defined in other standards. * For example the {@code Record} class name is used by other standards like Catalog Service for the Web (OGC CSW), @@ -293,17 +314,8 @@ final class TransformingReader extends Transformer implements XMLEventReader { @SuppressWarnings("ReturnOfCollectionOrArrayField") final Map<String, Map<String,String>> renamingMap(final String namespace) { if (!namespace.isEmpty()) { - switch (removeTrailingSlash(namespace)) { - case "http://www.cnig.gouv.fr/2005/fra": // TODO: move to sis-french-profile module. - case LegacyNamespaces.GMI_ALIAS: - case LegacyNamespaces.GMI: - case LegacyNamespaces.GMD: - case LegacyNamespaces.SRV: - case LegacyNamespaces.GCO: - case LegacyNamespaces.GMX: - case LegacyNamespaces.GML: { - return NAMESPACES; - } + if (LEGACY_NAMESPACES.contains(removeTrailingSlash(namespace))) { + return NAMESPACES; } } return Collections.emptyMap(); diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingWriter.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingWriter.java index 2984ed3..8288e1b 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingWriter.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/TransformingWriter.java @@ -84,7 +84,7 @@ final class TransformingWriter extends Transformer implements XMLEventWriter { * * This map is initialized only once and should not be modified after that point. */ - private static final Map<String, Map<String,String>> NAMESPACES = load(true, FILENAME, 60); + private static final Map<String, Map<String,String>> NAMESPACES = load(true, FILENAME, Collections.emptySet(), 60); /** * Elements that appear in different order in ISO 19139:2007 (or other legacy standards) compared @@ -214,7 +214,7 @@ final class TransformingWriter extends Transformer implements XMLEventWriter { } /** - * Returns the map loaded by {@link #load(boolean, String, int)}. + * Returns the map loaded by {@link #load(boolean, String, Set, int)}. * * @param namespace the namespace URI for which to get the substitution map. * @return the substitution map for the given namespace. @@ -338,7 +338,6 @@ final class TransformingWriter extends Transformer implements XMLEventWriter { * @param event the event using JAXB namespaces. */ @Override - @SuppressWarnings("unchecked") // TODO: remove on JDK9 public void add(XMLEvent event) throws XMLStreamException { switch (event.getEventType()) { case ATTRIBUTE: { diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/readme.html b/core/sis-metadata/src/main/java/org/apache/sis/xml/readme.html index f03b263..88b7e83 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/xml/readme.html +++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/readme.html @@ -29,6 +29,7 @@ Both share the same syntax: </p> <ul> + <li>Lines starting with "*" character specify the legacy namespaces containing elements to rename.</li> <li>Lines with zero-space indentation are namespace URIs.</li> <li>Lines with one-space indentation are XML type names.</li> <li>Lines with two-spaces indentation are property names.</li> @@ -51,7 +52,11 @@ For example in the following example, <code>Georectified.centerPoint</code> (from the old standard) is renamed as <code>Georectified.centrePoint</code> (new standard). </p> - <blockquote><pre>http://standards.iso.org/iso/19115/-3/<b>cit</b>/1.0 + <blockquote><pre># Legacy namespace containing elements to rename: +* http://www.isotc211.org/2005/gmd + +# New namespaces: +http://standards.iso.org/iso/19115/-3/<b>cit</b>/1.0 CI_Citation title edition diff --git a/core/sis-metadata/src/main/resources/org/apache/sis/xml/RenameOnImport.lst b/core/sis-metadata/src/main/resources/org/apache/sis/xml/RenameOnImport.lst index 5018d16..8687283 100644 --- a/core/sis-metadata/src/main/resources/org/apache/sis/xml/RenameOnImport.lst +++ b/core/sis-metadata/src/main/resources/org/apache/sis/xml/RenameOnImport.lst @@ -3,6 +3,15 @@ # # See readme.html is source code for the syntax of this file. # +# Apply to: +* http://standards.iso.org/iso/19115/-2/gmi/1.0 +* http://www.isotc211.org/2005/gmi +* http://www.isotc211.org/2005/gmd +* http://www.isotc211.org/2005/srv +* http://www.isotc211.org/2005/gco +* http://www.isotc211.org/2005/gmx +* http://www.opengis.net/gml + http://standards.iso.org/iso/19115/-3/cit/1.0 AbstractCI_Party contactInfo diff --git a/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java b/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java index 256796a..12c12ec 100644 --- a/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java +++ b/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java @@ -67,6 +67,7 @@ import org.junit.BeforeClass; org.apache.sis.xml.OGCNamespacePrefixMapperTest.class, org.apache.sis.xml.MarshallerPoolTest.class, org.apache.sis.xml.TransformingNamespacesTest.class, + org.apache.sis.xml.TransformerTest.class, org.apache.sis.internal.xml.XmlUtilitiesTest.class, org.apache.sis.internal.jaxb.IdentifierMapAdapterTest.class, org.apache.sis.internal.jaxb.ModifiableIdentifierMapTest.class, diff --git a/core/sis-metadata/src/test/java/org/apache/sis/xml/TransformerTest.java b/core/sis-metadata/src/test/java/org/apache/sis/xml/TransformerTest.java new file mode 100644 index 0000000..e019043 --- /dev/null +++ b/core/sis-metadata/src/test/java/org/apache/sis/xml/TransformerTest.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.xml; + +import java.util.Set; +import java.util.HashSet; +import java.util.Map; +import org.apache.sis.internal.xml.LegacyNamespaces; +import org.apache.sis.test.TestCase; +import org.junit.Test; + +import static org.junit.Assert.*; + + +/** + * Tests {@link Transformer}. + * + * @author Martin Desruisseaux (Geomatys) + * @version 1.0 + * @since 1.0 + * @module + */ +public final strictfp class TransformerTest extends TestCase { + /** + * Tests {@link Transformer#load(boolean, String, Set, int)}. + */ + @Test + public void testLoad() { + final Set<String> targets = new HashSet<>(12); + final Map<String, Map<String,String>> namespaces = Transformer.load(false, TransformingReader.FILENAME, targets, 260); + assertTrue(LegacyNamespaces.GMI_ALIAS, targets.contains(LegacyNamespaces.GMI_ALIAS)); + assertTrue(LegacyNamespaces.GMI, targets.contains(LegacyNamespaces.GMI)); + assertTrue(LegacyNamespaces.GMD, targets.contains(LegacyNamespaces.GMD)); + assertTrue(LegacyNamespaces.SRV, targets.contains(LegacyNamespaces.SRV)); + assertTrue(LegacyNamespaces.GCO, targets.contains(LegacyNamespaces.GCO)); + assertTrue(LegacyNamespaces.GMX, targets.contains(LegacyNamespaces.GMX)); + assertTrue(LegacyNamespaces.GML, targets.contains(LegacyNamespaces.GML)); + + Map<String, String> m = namespaces.get("CI_Citation"); + assertNotNull("CI_Citation", m); + assertEquals("title", Namespaces.CIT, m.get("title")); + assertEquals("edition", Namespaces.CIT, m.get("edition")); + + m = namespaces.get("MD_Metadata"); + assertNotNull("MD_Metadata", m); + assertEquals("identificationInfo", Namespaces.MDB, m.get("identificationInfo")); + assertEquals("spatialRepresentationInfo", Namespaces.MDB, m.get("spatialRepresentationInfo")); + } +} diff --git a/core/sis-metadata/src/test/java/org/apache/sis/xml/TransformingNamespacesTest.java b/core/sis-metadata/src/test/java/org/apache/sis/xml/TransformingNamespacesTest.java index 57708a2..d433dab 100644 --- a/core/sis-metadata/src/test/java/org/apache/sis/xml/TransformingNamespacesTest.java +++ b/core/sis-metadata/src/test/java/org/apache/sis/xml/TransformingNamespacesTest.java @@ -50,7 +50,6 @@ public final strictfp class TransformingNamespacesTest extends TestCase implemen * Tests {@link TransformingNamespaces#getPrefixes(String)}. */ @Test - @SuppressWarnings("unchecked") // TODO: remove with JDK9 public void testGetPrefixes() { final NamespaceContext fns = TransformingNamespaces.asXML(this, TransformVersion.ISO19139); final Iterator<String> it = fns.getPrefixes(LegacyNamespaces.GMD); diff --git a/profiles/sis-french-profile/src/main/resources/org/apache/sis/internal/profile/fra/RenameOnImport.lst b/profiles/sis-french-profile/src/main/resources/org/apache/sis/internal/profile/fra/RenameOnImport.lst index fc0fa04..4231f68 100644 --- a/profiles/sis-french-profile/src/main/resources/org/apache/sis/internal/profile/fra/RenameOnImport.lst +++ b/profiles/sis-french-profile/src/main/resources/org/apache/sis/internal/profile/fra/RenameOnImport.lst @@ -1,10 +1,13 @@ # Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements; # and to You under the Apache License, Version 2.0. # +# Apply to: +* http://www.cnig.gouv.fr/2005/fra + http://www.cnig.gouv.fr/2005/fra - FRA_DataIdentification : MD_DataIdentification - FRA_DirectReferenceSystem : MD_ReferenceSystem - FRA_IndirectReferenceSystem : MD_ReferenceSystem - FRA_Constraints : MD_Constraints - FRA_LegalConstraints : MD_LegalConstraints - FRA_SecurityConstraints : MD_SecurityConstraints + FRA_DataIdentification : MD_DataIdentification !no rename + FRA_DirectReferenceSystem : MD_ReferenceSystem !no rename + FRA_IndirectReferenceSystem : MD_ReferenceSystem !no rename + FRA_Constraints : MD_Constraints !no rename + FRA_LegalConstraints : MD_LegalConstraints !no rename + FRA_SecurityConstraints : MD_SecurityConstraints !no rename