1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package de.uapcore.sigred.doc.base;
31
32 import de.uapcore.sigred.doc.
Resources;
33 import de.uapcore.sigrapi.impl.
Digraph;
34 import de.uapcore.sigrapi.impl.
Graph;
35 import de.uapcore.sigrapi.
IGraph;
36 import java.io.
IOException;
37 import java.io.
InputStream;
38 import java.io.
OutputStream;
39 import java.util.concurrent.atomic.
AtomicBoolean;
40 import java.util.concurrent.atomic.
AtomicReference;
41 import org.apache.xerces.impl.
Constants;
42 import org.dom4j.
Document;
43 import org.dom4j.
DocumentException;
44 import org.dom4j.
DocumentHelper;
45 import org.dom4j.
Element;
46 import org.dom4j.
Namespace;
47 import org.dom4j.
QName;
48 import org.dom4j.io.
OutputFormat;
49 import org.dom4j.io.
SAXReader;
50 import org.dom4j.io.
XMLWriter;
51 import org.xml.sax.
ErrorHandler;
52 import org.xml.sax.
SAXException;
53 import org.xml.sax.
SAXParseException;
54
55 public abstract class AbstractGraphDocument<
T extends IGraph>
56 extends FileBackedDocument {
57
58 protected static final Namespace NAMESPACE =
Namespace.get(
"sigred",
59 "http://develop.uap-core.de/sigred/");
60
61 private static final
62 QName TAG_GRAPHDOC =
QName.get(
"graph-document",
NAMESPACE);
63 private static final
64 QName TAG_GRAPH =
QName.get(
"graph",
NAMESPACE);
65 private static final
66 QName TAG_DIGRAPH =
QName.get(
"digraph",
NAMESPACE);
67 private static final
68 QName TAG_METADATA =
QName.get(
"metadata",
NAMESPACE);
69
70 protected final T graph;
71
72 private final GraphDocumentMetadata metadata;
73
74 public AbstractGraphDocument(
Class<
T> graphType) {
75 T g;
76 try {
77 g = graphType.newInstance();
78 }
catch (
ReflectiveOperationException e) {
79 assert false;
80 g = null;
81 }
82 graph = g;
83 metadata =
new GraphDocumentMetadata();
84 }
85
86 public T getGraph() {
87 return graph;
88 }
89
90 public GraphDocumentMetadata getMetadata() {
91 return metadata;
92 }
93
94 protected abstract void writeGraph(
Element rootNode)
throws IOException;
95 protected abstract void readGraph(
Element rootNode)
throws IOException;
96
97 @Override
98 public void writeTo(
OutputStream out)
throws IOException {
99 Document doc =
DocumentHelper.createDocument();
100
101 Element rootNode = doc.addElement(
TAG_GRAPHDOC);
102
103 Element metadataNode = rootNode.addElement(
TAG_METADATA);
104
105 metadata.write(metadataNode);
106
107 if (graph
instanceof Graph) {
108 writeGraph(rootNode.addElement(
TAG_GRAPH));
109 }
else if (graph
instanceof Digraph) {
110 writeGraph(rootNode.addElement(
TAG_DIGRAPH));
111 }
else {
112 throw new IOException(
"unsupported graph type");
113 }
114
115 XMLWriter writer =
new XMLWriter(out,
OutputFormat.createPrettyPrint());
116 writer.write(doc);
117 writer.flush();
118 }
119
120 @Override
121 public void readFrom(
InputStream in)
throws IOException {
122 try {
123 SAXReader reader =
new SAXReader(true);
124 reader.setStripWhitespaceText(true);
125
126 reader.setFeature(
Constants.
XERCES_FEATURE_PREFIX+
127 Constants.
SCHEMA_VALIDATION_FEATURE, true);
128 reader.setProperty(
Constants.
XERCES_PROPERTY_PREFIX +
129 Constants.
SCHEMA_LOCATION,
String.format(
"%s %s",
130 NAMESPACE.getURI(),
Resources.
class.getResource(
131 "graph-document.xsd").toExternalForm()));
132
133 final AtomicBoolean passed =
new AtomicBoolean(true);
134 final AtomicReference<
SAXParseException> xmlerror =
new AtomicReference<>();
135
136 reader.setErrorHandler(
new ErrorHandler() {
137 @Override
138 public void warning(
SAXParseException exception)
throws SAXException {
139 }
140
141 @Override
142 public void error(
SAXParseException exception)
throws SAXException {
143 xmlerror.set(exception);
144 passed.set(false);
145 }
146
147 @Override
148 public void fatalError(
SAXParseException exception)
throws SAXException {
149 xmlerror.set(exception);
150 passed.set(false);
151 }
152
153 });
154 Document doc = reader.read(in);
155 if (!passed.get()) {
156
157 throw xmlerror.get();
158 }
159
160 doc.normalize();
161
162 Element root = doc.getRootElement();
163 metadata.read(root.element(
TAG_METADATA));
164
165 if (graph
instanceof Graph) {
166 readGraph(root.element(
TAG_GRAPH));
167 }
else if (graph
instanceof Digraph) {
168 readGraph(root.element(
TAG_DIGRAPH));
169 }
else {
170 throw new IOException(
"unsupported graph type");
171 }
172 }
catch (
DocumentException |
SAXException ex) {
173 throw new IOException(ex);
174 }
175 }
176 }