sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 18/33: Leverage geoapi-conformance for reading OGC XSD files.
Date Mon, 18 Jun 2018 21:02:40 GMT
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

commit f60835a9a24781aadfca72d23ddbd94dfe1ea0bb
Author: Martin Desruisseaux <desruisseaux@apache.org>
AuthorDate: Sat Jun 2 12:04:07 2018 +0000

    Leverage geoapi-conformance for reading OGC XSD files.
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sis/branches/JDK8@1832732 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sis/test/xml/PackageVerifier.java   |  45 +--
 .../org/apache/sis/test/xml/SchemaCompliance.java  | 382 +--------------------
 .../org/apache/sis/test/xml/SchemaException.java   |  39 ---
 .../org/apache/sis/xml/RenameListGenerator.java    |   2 +-
 4 files changed, 32 insertions(+), 436 deletions(-)

diff --git a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/PackageVerifier.java
b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/PackageVerifier.java
index bf52a98..760e895 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/PackageVerifier.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/PackageVerifier.java
@@ -37,6 +37,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
 import javax.xml.parsers.ParserConfigurationException;
 import org.xml.sax.SAXException;
 import org.opengis.annotation.UML;
+import org.opengis.geoapi.SchemaException;
 import org.apache.sis.util.Classes;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.jaxb.LegacyNamespaces;
@@ -134,9 +135,9 @@ final strictfp class PackageVerifier {
     /**
      * The schema definition for the class under examination.
      *
-     * @see SchemaCompliance#typeDefinition(String)
+     * @see SchemaCompliance#getTypeDefinition(String)
      */
-    private Map<String, SchemaCompliance.Info> properties;
+    private Map<String, SchemaCompliance.Element> properties;
 
     /**
      * Whether a namespace is actually used of not.
@@ -259,7 +260,7 @@ final strictfp class PackageVerifier {
             if (xmlType != null) {
                 if (!classNS.equals(xmlType.namespace())) {
                     throw new SchemaException(errorInClassMember(null)
-                            .append("Mismatched namespace in @XmlType and @XmlRootElement."));
+                            .append("Mismatched namespace in @XmlType and @XmlRootElement.").toString());
                 }
                 SchemaCompliance.verifyNamingConvention(type.getName(), isoName, xmlType.name(),
SchemaCompliance.TYPE_SUFFIX);
             }
@@ -293,14 +294,14 @@ final strictfp class PackageVerifier {
             classNS = packageNS;
         } else if (classNS.equals(packageNS)) {
             throw new SchemaException(errorInClassMember(null)
-                    .append("Redundant namespace declaration: ").append(classNS));
+                    .append("Redundant namespace declaration: ").append(classNS).toString());
         }
         /*
          * Verify that the namespace has a prefix associated to it in the package-info file.
          */
         if (namespaceIsUsed.put(classNS, Boolean.TRUE) == null) {
             throw new SchemaException(errorInClassMember(null)
-                    .append("No prefix in package-info for ").append(classNS));
+                    .append("No prefix in package-info for ").append(classNS).toString());
         }
         /*
          * Properties in the legacy GMD or GMI namespaces may be deprecated, depending if
a replacement
@@ -311,20 +312,20 @@ final strictfp class PackageVerifier {
         if (!isDeprecatedClass) {
             if (type.isAnnotationPresent(Deprecated.class)) {
                 throw new SchemaException(errorInClassMember(null)
-                        .append("Unexpected @Deprecated annotation."));
+                        .append("Unexpected @Deprecated annotation.").toString());
             }
             /*
              * Verify that class name exists, then verify its namespace (associated to the
null key by convention).
              */
-            properties = schemas.typeDefinition(isoName);
+            properties = schemas.getTypeDefinition(isoName);
             if (properties == null) {
                 throw new SchemaException(errorInClassMember(null)
-                        .append("Unknown name declared in @XmlRootElement: ").append(isoName));
+                        .append("Unknown name declared in @XmlRootElement: ").append(isoName).toString());
             }
             final String expectedNS = properties.get(null).namespace;
             if (!classNS.equals(expectedNS)) {
                 throw new SchemaException(errorInClassMember(null)
-                        .append(isoName).append(" shall be associated to namespace ").append(expectedNS));
+                        .append(isoName).append(" shall be associated to namespace ").append(expectedNS).toString());
             }
             if (codeList != null) return;                   // If the class was a code list,
we are done.
         }
@@ -375,7 +376,7 @@ final strictfp class PackageVerifier {
         }
         if (namespaceIsUsed.put(ns, Boolean.TRUE) == null) {
             throw new SchemaException(errorInClassMember(javaName)
-                    .append("Missing @XmlNs for namespace ").append(ns));
+                    .append("Missing @XmlNs for namespace ").append(ns).toString());
         }
         /*
          * Remember that we need an adapter for this property, unless the method or field
defines its own adapter.
@@ -395,7 +396,7 @@ final strictfp class PackageVerifier {
                     final Class<?>[] p = c.getInterfaces();
                     if (p.length == 0) {
                         throw new SchemaException(errorInClassMember(javaName)
-                                .append("Missing @XmlJavaTypeAdapter for ").append(valueType));
+                                .append("Missing @XmlJavaTypeAdapter for ").append(valueType).toString());
                     }
                     c = p[0];   // Take only the first interface, which should be the "main"
parent.
                 }
@@ -408,7 +409,7 @@ final strictfp class PackageVerifier {
         if (LEGACY_NAMESPACES.getOrDefault(ns, Collections.emptySet()).contains(name)) {
             if (!isDeprecatedClass && element.required()) {
                 throw new SchemaException(errorInClassMember(javaName)
-                        .append("Legacy property should not be required."));
+                        .append("Legacy property should not be required.").toString());
             }
         } else {
             /*
@@ -417,21 +418,21 @@ final strictfp class PackageVerifier {
              */
             if (property.isAnnotationPresent(Deprecated.class)) {
                 throw new SchemaException(errorInClassMember(javaName)
-                        .append("Unexpected deprecation status."));
+                        .append("Unexpected deprecation status.").toString());
             }
-            final SchemaCompliance.Info info = properties.get(name);
+            final SchemaCompliance.Element info = properties.get(name);
             if (info == null) {
                 throw new SchemaException(errorInClassMember(javaName)
-                        .append("Unexpected XML element: ").append(name));
+                        .append("Unexpected XML element: ").append(name).toString());
             }
             if (info.namespace != null && !ns.equals(info.namespace)) {
                 throw new SchemaException(errorInClassMember(javaName)
                         .append("Declared namespace: ").append(ns).append(System.lineSeparator())
-                        .append("Expected namespace: ").append(info.namespace));
+                        .append("Expected namespace: ").append(info.namespace).toString());
             }
             if (element.required() != info.isRequired) {
                 throw new SchemaException(errorInClassMember(javaName)
-                        .append("Expected @XmlElement(required = ").append(info.isRequired).append(')'));
+                        .append("Expected @XmlElement(required = ").append(info.isRequired).append(')').toString());
             }
             /*
              * Following is a continuation of our check for cardinality, but also the beginning
of the check
@@ -441,11 +442,11 @@ final strictfp class PackageVerifier {
             if (isCollection) {
                 if (!info.isCollection) {
                     if (false)  // Temporarily disabled because require GeoAPI modifications.
-                    throw new SchemaException(errorInClassMember(javaName).append("Value
should be a singleton."));
+                    throw new SchemaException(errorInClassMember(javaName).append("Value
should be a singleton.").toString());
                 }
             } else if (info.isCollection) {
                 if (false)  // Temporarily disabled because require GeoAPI modifications.
-                throw new SchemaException(errorInClassMember(javaName).append("Value should
be a collection."));
+                throw new SchemaException(errorInClassMember(javaName).append("Value should
be a collection.").toString());
             }
             if (valueType != null) {
                 final UML valueUML = valueType.getAnnotation(UML.class);
@@ -458,7 +459,7 @@ final strictfp class PackageVerifier {
                         if (false)  // Temporarily disabled because require GeoAPI modifications.
                         throw new SchemaException(errorInClassMember(javaName)
                                 .append("Declared value type: ").append(actual).append(System.lineSeparator())
-                                .append("Expected value type: ").append(expected));
+                                .append("Expected value type: ").append(expected).toString());
                     }
                 }
             }
@@ -466,12 +467,12 @@ final strictfp class PackageVerifier {
              * Verify if we have a @XmlNs for the type of the value. This is probably not
required, but we
              * do that as a safety. A common namespace added by this check is Metadata Common
Classes (MCC).
              */
-            final Map<String, SchemaCompliance.Info> valueInfo = schemas.typeDefinition(info.typeName);
+            final Map<String, SchemaCompliance.Element> valueInfo = schemas.getTypeDefinition(info.typeName);
             if (valueInfo != null) {
                 final String valueNS = valueInfo.get(null).namespace;
                 if (namespaceIsUsed.put(valueNS, Boolean.TRUE) == null) {
                     throw new SchemaException(errorInClassMember(javaName)
-                            .append("Missing @XmlNs for property value namespace: ").append(valueNS));
+                            .append("Missing @XmlNs for property value namespace: ").append(valueNS).toString());
                 }
             }
         }
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/SchemaCompliance.java
b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/SchemaCompliance.java
index 1280c3a..ad6edcb 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/SchemaCompliance.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/SchemaCompliance.java
@@ -17,27 +17,20 @@
 package org.apache.sis.test.xml;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
 import java.nio.file.Path;
 import java.nio.file.Files;
 import java.nio.file.DirectoryStream;
 import java.nio.file.DirectoryIteratorException;
 import java.util.Map;
-import java.util.Deque;
 import java.util.HashMap;
-import java.util.ArrayDeque;
-import java.util.Objects;
-import java.util.Collections;
-import javax.xml.XMLConstants;
 import javax.xml.bind.annotation.XmlNs;
 import javax.xml.bind.annotation.XmlElement;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
-import org.w3c.dom.Node;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
 import org.xml.sax.SAXException;
+import org.opengis.geoapi.Departures;
+import org.opengis.geoapi.DocumentationStyle;
+import org.opengis.geoapi.SchemaInformation;
+import org.opengis.geoapi.SchemaException;
 import org.apache.sis.util.StringBuilders;
 
 
@@ -63,35 +56,7 @@ import org.apache.sis.util.StringBuilders;
  * @since   1.0
  * @module
  */
-public final strictfp class SchemaCompliance {
-    /**
-     * The root of ISO schemas. May be replaced by {@link #schemaRootDirectory} if a local
copy
-     * is available for faster tests.
-     */
-    private static final String SCHEMA_ROOT_DIRECTORY = "http://standards.iso.org/iso/";
-
-    /**
-     * ISO 19115-2 classes to merge with ISO 19115-1 classes. For example ISO 19115-2 defines
{@code MI_Band}
-     * as an extension of ISO 19115-1 {@code MD_Band}, but GeoAPI and Apache SIS merges those
two types in a
-     * single class for simplicity. Consequently when reading the schema, we rename some
{@code MI_*} types
-     * as {@code MD_*} in order to store properties together.
-     */
-    private static final Map<String,String> TYPES_TO_MERGE;
-    static {
-        final Map<String,String> m = new HashMap<>();
-        // ………Merge what…………………………………………………………Into……………………………………………
-        m.put("MI_Band_Type",                 "MD_Band_Type");
-        m.put("MI_CoverageDescription_Type",  "MD_CoverageDescription_Type");
-        m.put("MI_Georectified_Type",         "MD_Georectified_Type");
-        m.put("MI_Georeferenceable_Type",     "MD_Georeferenceable_Type");
-        m.put("LE_Source_Type",               "LI_Source_Type");
-        m.put("LE_ProcessStep_Type",          "LI_ProcessStep_Type");
-        m.put("AbstractMX_File_Type",         "MX_DataFile_Type");
-        m.put("Abstract_DataQuality_Type",    "DQ_DataQuality_Type");
-        m.put("Abstract_QualityElement_Type", "AbstractDQ_Element_Type");
-        TYPES_TO_MERGE = Collections.unmodifiableMap(m);
-    }
-
+public final strictfp class SchemaCompliance extends SchemaInformation {
     /**
      * The prefix of XML type names for properties. In ISO/OGC schemas, this prefix does
not appear
      * in the definition of class types but may appear in the definition of property types.
@@ -105,124 +70,16 @@ public final strictfp class SchemaCompliance {
     static final String TYPE_SUFFIX = "_Type";
 
     /**
-     * The suffix of XML property type names in a given class.
-     * This is used by convention in OGC/ISO standards (but not necessarily in other XSD).
-     */
-    private static final String PROPERTY_TYPE_SUFFIX = "_PropertyType";
-
-    /**
-     * XML type to ignore because of key collisions in {@link #typeDefinitions}.
-     * Those collisions occur because code lists are defined as links to the same file,
-     * with only different anchor positions.
-     */
-    private static final String CODELIST_TYPE = "gco:CodeListValue_Type";
-
-    /**
      * Separator between XML prefix and the actual name.
      */
     private static final char PREFIX_SEPARATOR = ':';
 
     /**
-     * If the computer contains a local copy of ISO schemas, path to that directory. Otherwise
{@code null}.
-     * If non-null, the {@code "http://standards.iso.org/iso/"} prefix in URL will be replaced
by that path.
-     * This field is usually {@code null}, but can be set to a non-null value for making
tests faster.
-     */
-    private final Path schemaRootDirectory;
-
-    /**
      * Root directory from which to search for classes.
      */
     private final Path classRootDirectory;
 
     /**
-     * A temporary buffer for miscellaneous string operations.
-     * Valid only in a local scope since the content may change at any time.
-     */
-    private final StringBuilder buffer;
-
-    /**
-     * The DOM factory used for reading XSD schemas.
-     */
-    private final DocumentBuilderFactory factory;
-
-    /**
-     * URL of schemas loaded, for avoiding loading the same schema many time.
-     * The last element on the queue is the schema in process of being loaded,
-     * used for resolving relative paths in {@code <xs:include>} elements.
-     */
-    private final Deque<String> schemaLocations;
-
-    /**
-     * The type and namespace of a property or class. Used in {@link #typeDefinitions} map.
-     */
-    static final class Info {
-        final String  typeName;
-        final String  namespace;
-        final boolean isRequired;
-        final boolean isCollection;
-
-        Info(final String typeName, final String namespace, final boolean isRequired, final
boolean isCollection) {
-            this.typeName     = typeName;
-            this.namespace    = namespace;
-            this.isRequired   = isRequired;
-            this.isCollection = isCollection;
-        }
-
-        boolean equal(final Info other) {
-            return Objects.equals(typeName,  other.typeName)
-                && Objects.equals(namespace, other.namespace)
-                && isRequired   == other.isRequired
-                && isCollection == other.isCollection;
-        }
-
-        @Override public String toString() {
-            return typeName;
-        }
-    }
-
-    /**
-     * Definitions of XML type for each class. In OGC/ISO schemas, those definitions have
the {@value #TYPE_SUFFIX}
-     * suffix in their name (which is omitted). The value is another map, where keys are
property names and values
-     * are their types, having the {@link #PROPERTY_TYPE_SUFFIX} suffix in their name (which
is omitted).
-     */
-    private final Map<String, Map<String,Info>> typeDefinitions;
-
-    /**
-     * Notifies that we are about to define the XML type for each property. In OGC/ISO schemas,
those definitions
-     * have the {@value #PROPERTY_TYPE_SUFFIX} suffix in their name (which is omitted). After
this method call,
-     * properties can be defined by calls to {@link #addProperty(String, String, boolean,
boolean)}.
-     */
-    private void preparePropertyDefinitions(final String type) throws SchemaException {
-        currentProperties = typeDefinitions.computeIfAbsent(trim(type, TYPE_SUFFIX).intern(),
(k) -> new HashMap<>());
-    }
-
-    /**
-     * The properties of the XML type under examination, or {@code null} if none.
-     * If non-null, this is one of the values in the {@link #typeDefinitions} map.
-     * By convention, the {@code null} key is associated to information about the class.
-     */
-    private Map<String,Info> currentProperties;
-
-    /**
-     * A single property type under examination, or {@code null} if none.
-     * If non-null, this is a value ending with the {@value #PROPERTY_TYPE_SUFFIX} suffix.
-     */
-    private String currentPropertyType;
-
-    /**
-     * Default value for the {@code required} attribute of {@link XmlElement}. This default
value should
-     * be {@code true} for properties declared inside a {@code <sequence>} element,
and {@code false} for
-     * properties declared inside a {@code <choice>} element.
-     */
-    private boolean requiredByDefault;
-
-    /**
-     * Namespace of the type or properties being defined.
-     * This is specified by {@code <xs:schema targetNamespace="(…)">}.
-     */
-    private String targetNamespace;
-
-    /**
      * The namespaces associated to prefixes, as declared by JAXB {@link XmlNs} annotations.
      * Used for verifying that no prefix is defined twice for different namespaces.
      *
@@ -242,13 +99,8 @@ public final strictfp class SchemaCompliance {
      *                              Otherwise {@code null}. This is only for making tests
faster.
      */
     public SchemaCompliance(final Path classRootDirectory, final Path schemaRootDirectory)
{
-        this.classRootDirectory  = classRootDirectory;
-        this.schemaRootDirectory = schemaRootDirectory;
-        factory = DocumentBuilderFactory.newInstance();
-        factory.setNamespaceAware(true);
-        buffer = new StringBuilder(100);
-        typeDefinitions = new HashMap<>();
-        schemaLocations = new ArrayDeque<>();
+        super(schemaRootDirectory, new Departures(), DocumentationStyle.NONE);
+        this.classRootDirectory = classRootDirectory;
         allXmlNS = new HashMap<>();
     }
 
@@ -269,6 +121,7 @@ public final strictfp class SchemaCompliance {
             throws IOException, ClassNotFoundException, ParserConfigurationException, SAXException,
SchemaException
     {
         PackageVerifier verifier = null;
+        final StringBuilder buffer = new StringBuilder();
         try (DirectoryStream<Path> stream = Files.newDirectoryStream(classRootDirectory.resolve(directory)))
{
             for (Path path : stream) {
                 final String filename = path.getFileName().toString();
@@ -297,184 +150,6 @@ public final strictfp class SchemaCompliance {
     }
 
     /**
-     * Loads the XSD file at the given URL. Definitions are stored in the {@link #typeDefinitions}
map.
-     * Only information of interest are stored, and we assume that the XSD follows OGC/ISO
conventions.
-     * This method may be invoked recursively if the XSD contains {@code <xs:include>}
elements.
-     *
-     * @param  location  URL to the XSD file to load.
-     */
-    final void loadSchema(String location)
-            throws IOException, ParserConfigurationException, SAXException, SchemaException
-    {
-        if (schemaRootDirectory != null && location.startsWith(SCHEMA_ROOT_DIRECTORY))
{
-            location = schemaRootDirectory.resolve(location.substring(SCHEMA_ROOT_DIRECTORY.length())).toUri().toString();
-        }
-        if (!schemaLocations.contains(location)) {
-            final Document doc;
-            try (final InputStream in = new URL(location).openStream()) {
-                doc = factory.newDocumentBuilder().parse(in);
-            }
-            schemaLocations.addLast(location);
-            storeClassDefinition(doc);
-        }
-    }
-
-    /**
-     * Stores information about classes in the given node and children. This method invokes
itself
-     * for scanning children, until we reach sub-nodes about properties (in which case we
continue
-     * with {@link #storePropertyDefinition(Node)}).
-     */
-    private void storeClassDefinition(final Node node)
-            throws IOException, ParserConfigurationException, SAXException, SchemaException
-    {
-        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(node.getNamespaceURI())) {
-            switch (node.getNodeName()) {
-                case "schema": {
-                    targetNamespace = getMandatoryAttribute(node, "targetNamespace").intern();
-                    break;
-                }
-                /*
-                 * <xs:include schemaLocation="(…).xsd">
-                 * Load the schema at the given URL, which is assumed relative.
-                 */
-                case "include": {
-                    final String oldTarget = targetNamespace;
-                    final String location = schemaLocations.getLast();
-                    buffer.setLength(0);
-                    buffer.append(location, 0, location.lastIndexOf('/') + 1).append(getMandatoryAttribute(node,
"schemaLocation"));
-                    loadSchema(buffer.toString());
-                    targetNamespace = oldTarget;
-                    return;                             // Skip children (normally, there
is none).
-                }
-                /*
-                 * <xs:element name="(…)" type="(…)_Type">
-                 * Verify that the names comply with our assumptions.
-                 */
-                case "element": {
-                    final String name = getMandatoryAttribute(node, "name");
-                    final String type = getMandatoryAttribute(node, "type");
-                    if (CODELIST_TYPE.equals(type)) {
-                        final Map<String,Info> properties = new HashMap<>(4);
-                        final Info info = new Info(null, targetNamespace, false, false);
-                        properties.put(null, info);     // Remember namespace of the code
list.
-                        properties.put(name, info);     // Pseudo-property used in our CodeList
adapters.
-                        if (typeDefinitions.put(name, properties) != null) {
-                            throw new SchemaException(String.format("Code list \"%s\" is
defined twice.", name));
-                        }
-                    } else {
-                        verifyNamingConvention(schemaLocations.getLast(), name, type, TYPE_SUFFIX);
-                        preparePropertyDefinitions(type);
-                        addProperty(null, type, false, false);
-                        currentProperties = null;
-                    }
-                    return;                             // Ignore children (they are about
documentation).
-                }
-                /*
-                 * <xs:complexType name="(…)_Type">
-                 * <xs:complexType name="(…)_PropertyType">
-                 */
-                case "complexType": {
-                    String name = getMandatoryAttribute(node, "name");
-                    if (name.endsWith(PROPERTY_TYPE_SUFFIX)) {
-                        currentPropertyType = name;
-                        verifyPropertyType(node);
-                        currentPropertyType = null;
-                    } else {
-                        /*
-                         * In the case of "(…)_PropertyType", replace some ISO 19115-2
types by ISO 19115-1 types.
-                         * For example "MI_Band_Type" is renamed as "MD_Band_Type". We do
that because we use only
-                         * one class for representing those two distincts ISO types. Note
that not all ISO 19115-2
-                         * types extend an ISO 19115-1 type, so we need to apply a case-by-case
approach.
-                         */
-                        requiredByDefault = true;
-                        name = TYPES_TO_MERGE.getOrDefault(name, name);
-                        preparePropertyDefinitions(name);
-                        storePropertyDefinition(node);
-                        currentProperties = null;
-                    }
-                    return;                             // Skip children since they have
already been examined.
-                }
-            }
-        }
-        for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling())
{
-            storeClassDefinition(child);
-        }
-    }
-
-    /**
-     * Stores information about properties in the current class. The {@link #currentProperties}
field must be
-     * set to the map of properties for the class defined by the enclosing {@code <xs:complexType>}
element.
-     * This method parses elements of the following form:
-     *
-     * {@preformat xml
-     *   <xs:element name="(…)" type="(…)_PropertyType" minOccurs="(…)" maxOccurs="(…)">
-     * }
-     */
-    private void storePropertyDefinition(final Node node) throws SchemaException {
-        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(node.getNamespaceURI())) {
-            switch (node.getNodeName()) {
-                case "sequence": {
-                    requiredByDefault = true;
-                    break;
-                }
-                case "choice": {
-                    requiredByDefault = false;
-                    break;
-                }
-                case "element": {
-                    boolean isRequired = requiredByDefault;
-                    boolean isCollection = false;
-                    final NamedNodeMap attributes = node.getAttributes();
-                    if (attributes != null) {
-                        Node attr = attributes.getNamedItem("minOccurs");
-                        if (attr != null) {
-                            final String value = attr.getNodeValue();
-                            if (value != null) {
-                                isRequired = Integer.parseInt(value) > 0;
-                            }
-                        }
-                        attr = attributes.getNamedItem("maxOccurs");
-                        if (attr != null) {
-                            final String value = attr.getNodeValue();
-                            if (value != null) {
-                                isCollection = value.equals("unbounded") || Integer.parseInt(value)
>  1;
-                            }
-                        }
-                    }
-                    addProperty(getMandatoryAttribute(node, "name").intern(),
-                           trim(getMandatoryAttribute(node, "type"), PROPERTY_TYPE_SUFFIX).intern(),
isRequired, isCollection);
-                    return;
-                }
-            }
-        }
-        for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling())
{
-            storePropertyDefinition(child);
-        }
-    }
-
-    /**
-     * Verifies the naming convention of property defined by the given node. The {@link #currentPropertyType}
-     * field must be set to the type of the property defined by the enclosing {@code <xs:complexType>}
element.
-     * This method parses elements of the following form:
-     *
-     * {@preformat xml
-     *   <xs:element ref="(…)">
-     * }
-     */
-    private void verifyPropertyType(final Node node) throws SchemaException {
-        if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(node.getNamespaceURI())) {
-            if ("element".equals(node.getNodeName())) {
-                verifyNamingConvention(schemaLocations.getLast(),
-                        getMandatoryAttribute(node, "ref"), currentPropertyType, PROPERTY_TYPE_SUFFIX);
-                return;
-            }
-        }
-        for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling())
{
-            verifyPropertyType(child);
-        }
-    }
-
-    /**
      * Verifies that the relationship between the name of the given entity and its type are
consistent with
      * OGC/ISO conventions. This method ignores the prefix (e.g. {@code "mdb:"} in {@code
"mdb:MD_Metadata"}).
      *
@@ -506,20 +181,6 @@ public final strictfp class SchemaCompliance {
     }
 
     /**
-     * Adds a property of the current name and type. This method is invoked during schema
parsing.
-     * The property namespace is assumed to be {@link #targetNamespace}.
-     */
-    private void addProperty(final String name, final String type, final boolean isRequired,
final boolean isCollection) throws SchemaException {
-        final Info info = new Info(type, targetNamespace, isRequired, isCollection);
-        final Info old = currentProperties.put(name, info);
-        if (old != null && !old.equal(info)) {
-            throw new SchemaException(String.format("Error while parsing %s:%n" +
-                    "Property \"%s\" is associated to type \"%s\", but that property was
already associated to \"%s\".",
-                    schemaLocations.getLast(), name, type, old));
-        }
-    }
-
-    /**
      * Removes leading and trailing spaces if any, then the prefix and the suffix in the
given name.
      * The prefix is anything before the first {@value #PREFIX_SEPARATOR} character.
      * The suffix must be the given string, otherwise an exception is thrown.
@@ -536,31 +197,4 @@ public final strictfp class SchemaCompliance {
         }
         throw new SchemaException(String.format("Expected a name ending with \"%s\" but got
\"%s\".", suffix, name));
     }
-
-    /**
-     * Returns the attribute of the given name in the given node,
-     * or throws an exception if the attribute is not present.
-     */
-    private static String getMandatoryAttribute(final Node node, final String name) throws
SchemaException {
-        final NamedNodeMap attributes = node.getAttributes();
-        if (attributes != null) {
-            final Node attr = attributes.getNamedItem(name);
-            if (attr != null) {
-                final String value = attr.getNodeValue();
-                if (value != null) {
-                    return value;
-                }
-            }
-        }
-        throw new SchemaException(String.format("Node \"%s\" should have a '%s' attribute.",
node.getNodeName(), name));
-    }
-
-    /**
-     * Returns the type definitions for a class of the given name.
-     *
-     * @param  className  ISO identifier of a class (e.g. {@code "MD_Metadata"}).
-     */
-    final Map<String, SchemaCompliance.Info> typeDefinition(final String className)
{
-        return typeDefinitions.get(className);
-    }
 }
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/SchemaException.java
b/core/sis-metadata/src/test/java/org/apache/sis/test/xml/SchemaException.java
deleted file mode 100644
index 9e59cfa..0000000
--- a/core/sis-metadata/src/test/java/org/apache/sis/test/xml/SchemaException.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.test.xml;
-
-
-/**
- * Thrown when a {@link SchemaCompliance} failed to load a XSD file because it does not comply
- * with expected OGC/ISO conventions, or when a JAXB annotation failed a compliance check.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
- * @since   1.0
- * @module
- */
-@SuppressWarnings("serial")
-public final class SchemaException extends Exception {
-    /**
-     * Creates an exception with the specified details message.
-     *
-     * @param message  the detail message.
-     */
-    public SchemaException(final CharSequence message) {
-        super(message != null ? message.toString() : null);
-    }
-}
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/xml/RenameListGenerator.java b/core/sis-metadata/src/test/java/org/apache/sis/xml/RenameListGenerator.java
index 1c5fb4b..de0594b 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/xml/RenameListGenerator.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/xml/RenameListGenerator.java
@@ -32,7 +32,7 @@ import java.lang.reflect.Method;
 import javax.xml.bind.annotation.XmlSchema;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
-import org.apache.sis.test.xml.SchemaException;
+import org.opengis.geoapi.SchemaException;
 import org.apache.sis.internal.jaxb.LegacyNamespaces;
 
 


Mime
View raw message