GraphMLValidator.java

package org.thewonderlemming.c4plantuml.graphml.validation;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

/**
 * Validates a given XML stream against the GraphML XSDs set.
 *
 * @author thewonderlemming
 *
 */
public class GraphMLValidator {

    private static final String GRAPHML_XSD_FILENAME = "/graphml.xsd";

    private static final Logger LOGGER = LoggerFactory.getLogger(GraphMLValidator.class);


    /**
     * Validates the given XML stream and throws an exception if it is not a valid GraphML.
     *
     * @param graphML the XML stream to validate.
     * @param strictValidation throws exceptions on validation error if set to {@code true}.
     * @throws ValidationException if a validation error occurs while {@code strictValidation} is set to {@code true}.
     */
    public static void validate(final InputStream graphML, final boolean strictValidation) throws ValidationException {
        validate(new StreamSource(graphML), strictValidation);
    }

    /**
     * Validates the given XML stream and throws an exception if it is not a valid GraphML.
     *
     * @param graphML the XML stream to validate.
     * @param strictValidation throws exceptions on validation error if set to {@code true}.
     * @throws ValidationException if a validation error occurs while {@code strictValidation} is set to {@code true}.
     */
    public static void validate(final StreamSource graphML, final boolean strictValidation) throws ValidationException {

        try {

            final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
            factory.setResourceResolver(new CustomResourceResolver());

            final Schema schema = factory.newSchema(getXsdAsStream(GraphMLValidator.GRAPHML_XSD_FILENAME));
            final Validator validator = schema.newValidator();
            validator.setErrorHandler(new GraphMLValidatorErrorHandler(strictValidation));
            validator.validate(graphML);

        } catch (final SAXException | IOException e) {

            final String errMsg = String
                .format("Cannot validate the GraphML stream because of the following: %s",
                    e.getMessage());

            LOGGER.error(errMsg);
            throw new ValidationException(errMsg, e);
        }
    }

    private static StreamSource getXsdAsStream(final String filename) {

        return new StreamSource(
            GraphMLValidator.class
                .getResourceAsStream(filename));
    }

    private GraphMLValidator() {
    }
}