# 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() {
        }
    }