# GraphMLXsd.java

    package org.thewonderlemming.c4plantuml.graphml.validation;

    import java.util.Optional;
    import java.util.stream.Stream;

    /**
     * This enumeration maps XML namespaces to their system ID and a local resource that contains the XSD - the purpose
     * being to avoid having external calls to retrieve these XSDs.
     *
     * @author thewonderlemming
     *
     */
    public enum GraphMLXsd {

        /**
         * An XSD that extends the GraphML format to redefine its attributes.
         */
        ATTRIBUTES(
            "http://graphml.graphdrawing.org/xmlns/1.1/graphml-attributes.xsd",
            "/graphml-attributes.xsd",
            GraphMLXsd.GRAPHML_NAMESPACE_URI),

        /**
         * An XSD that defines the basics of the GraphML format.
         */
        GRAPHML(
            "http://graphml.graphdrawing.org/xmlns/1.1/graphml.xsd",
            "/graphml.xsd",
            GraphMLXsd.GRAPHML_NAMESPACE_URI),

        /**
         * An XSD that extends the GraphML format to redefine its parse information.
         */
        PARSE_INFO(
            "http://graphml.graphdrawing.org/xmlns/1.1/graphml-parseinfo.xsd",
            "/graphml-parseinfo.xsd",
            GraphMLXsd.GRAPHML_NAMESPACE_URI),

        /**
         * An XSD that extends the GraphML format to redefine its structure.
         */
        STRUCTURE(
            "http://graphml.graphdrawing.org/xmlns/1.1/graphml-structure.xsd",
            "/graphml-structure.xsd",
            GraphMLXsd.GRAPHML_NAMESPACE_URI),

        /**
         * An XSD that defines attributes that can be used to create hyperlinks.
         */
        XLINK(
            "http://graphml.graphdrawing.org/xmlns/1.1/xlink.xsd",
            "/xlink.xsd",
            "http://www.w3.org/1999/xlink");

        private static final String GRAPHML_NAMESPACE_URI = "http://graphml.graphdrawing.org/xmlns";

        private final String namespaceURI;

        private final String resourceFilename;

        private final String systemId;

        /**
         * Looks for an XSD value that matches the given {@code systemId} and {@code namespaceURI} and returns it as an
         * {@link Optional}.
         *
         * @param systemId the expected XSD system ID.
         * @param namespaceURI the expected XSD namespace URI.
         * @return an {@link Optional} of {@link GraphMLXsd} or empty if no match were to be found.
         */
        public static Optional<GraphMLXsd> resolveXsd(final String systemId, final String namespaceURI) {

            return Stream
                .of(GraphMLXsd.values())
                    .filter(value -> value.matchesCurrentXsd(systemId, namespaceURI))
                    .findAny();
        }

        private GraphMLXsd(final String systemId, final String resourceFilename, final String namespaceUri) {

            this.resourceFilename = resourceFilename;
            this.systemId = systemId;
            this.namespaceURI = namespaceUri;
        }

        /**
         * Returns the current XSD namespace URI.
         *
         * @return the XSD namespace URI.
         */
        public String getNamespaceURI() {
            return namespaceURI;
        }

        /**
         * Returns the current XSD filename.
         *
         * @return the XSD filename.
         */
        public String getResourceFilename() {
            return this.resourceFilename;
        }

        /**
         * Returns the current XML system ID.
         *
         * @return the XSD system ID.
         */
        public String getSystemId() {
            return systemId;
        }

        private boolean matchesCurrentXsd(final String systemId, final String namespaceUri) {
            return this.systemId.equals(systemId) && this.namespaceURI.equals(namespaceUri);
        }
    }