--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javatest.java Mon Apr 24 21:01:41 2023 +0200 @@ -0,0 +1,176 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Mike Becker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +package de.uapcore.sigred.doc.base; + +import de.uapcore.sigred.doc.Resources; +import de.uapcore.sigrapi.impl.Digraph; +import de.uapcore.sigrapi.impl.Graph; +import de.uapcore.sigrapi.IGraph; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import org.apache.xerces.impl.Constants; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.Namespace; +import org.dom4j.QName; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.SAXReader; +import org.dom4j.io.XMLWriter; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public abstract class AbstractGraphDocument<T extends IGraph> + extends FileBackedDocument { + + protected static final Namespace NAMESPACE = Namespace.get("sigred", + "http://develop.uap-core.de/sigred/"); + + private static final + QName TAG_GRAPHDOC = QName.get("graph-document", NAMESPACE); + private static final + QName TAG_GRAPH = QName.get("graph", NAMESPACE); + private static final + QName TAG_DIGRAPH = QName.get("digraph", NAMESPACE); + private static final + QName TAG_METADATA = QName.get("metadata", NAMESPACE); + + protected final T graph; + + private final GraphDocumentMetadata metadata; + + public AbstractGraphDocument(Class<T> graphType) { + T g; + try { + g = graphType.newInstance(); + } catch (ReflectiveOperationException e) { + assert false; + g = null; // for the compiler + } + graph = g; + metadata = new GraphDocumentMetadata(); + } + + public T getGraph() { + return graph; + } + + public GraphDocumentMetadata getMetadata() { + return metadata; + } + + protected abstract void writeGraph(Element rootNode) throws IOException; + protected abstract void readGraph(Element rootNode) throws IOException; + + @Override + public void writeTo(OutputStream out) throws IOException { + Document doc = DocumentHelper.createDocument(); + + Element rootNode = doc.addElement(TAG_GRAPHDOC); + + Element metadataNode = rootNode.addElement(TAG_METADATA); + + metadata.write(metadataNode); + + if (graph instanceof Graph) { + writeGraph(rootNode.addElement(TAG_GRAPH)); + } else if (graph instanceof Digraph) { + writeGraph(rootNode.addElement(TAG_DIGRAPH)); + } else { + throw new IOException("unsupported graph type"); + } + + XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint()); + writer.write(doc); + writer.flush(); + } + + @Override + public void readFrom(InputStream in) throws IOException { + try { + SAXReader reader = new SAXReader(true); + reader.setStripWhitespaceText(true); + + reader.setFeature(Constants.XERCES_FEATURE_PREFIX+ + Constants.SCHEMA_VALIDATION_FEATURE, true); + reader.setProperty(Constants.XERCES_PROPERTY_PREFIX + + Constants.SCHEMA_LOCATION, String.format("%s %s", + NAMESPACE.getURI(), Resources.class.getResource( + "graph-document.xsd").toExternalForm())); + + final AtomicBoolean passed = new AtomicBoolean(true); + final AtomicReference<SAXParseException> xmlerror = new AtomicReference<>(); + // TODO: we should do more detailed error handling here + reader.setErrorHandler(new ErrorHandler() { + @Override + public void warning(SAXParseException exception) throws SAXException { + } + + @Override + public void error(SAXParseException exception) throws SAXException { + xmlerror.set(exception); + passed.set(false); + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + xmlerror.set(exception); + passed.set(false); + } + + }); + Document doc = reader.read(in); + if (!passed.get()) { + // TODO: provide details (maybe via separate error object?) + throw xmlerror.get(); + } + + doc.normalize(); + + Element root = doc.getRootElement(); + metadata.read(root.element(TAG_METADATA)); + + if (graph instanceof Graph) { + readGraph(root.element(TAG_GRAPH)); + } else if (graph instanceof Digraph) { + readGraph(root.element(TAG_DIGRAPH)); + } else { + throw new IOException("unsupported graph type"); + } + } catch (DocumentException | SAXException ex) { + throw new IOException(ex); + } + } +}