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);
    }
}