1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.jeuclid;
20
21 import javax.annotation.concurrent.GuardedBy;
22 import javax.annotation.concurrent.ThreadSafe;
23 import javax.xml.transform.Transformer;
24 import javax.xml.transform.TransformerException;
25 import javax.xml.transform.TransformerFactory;
26 import javax.xml.transform.dom.DOMResult;
27 import javax.xml.transform.dom.DOMSource;
28 import javax.xml.transform.stream.StreamSource;
29
30 import net.sourceforge.jeuclid.elements.generic.DocumentElement;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.w3c.dom.DOMException;
35 import org.w3c.dom.Document;
36 import org.w3c.dom.DocumentFragment;
37 import org.w3c.dom.Element;
38 import org.w3c.dom.Node;
39
40
41
42
43
44
45 @ThreadSafe
46 public final class DOMBuilder {
47
48
49
50 private static final Log LOGGER = LogFactory.getLog(DOMBuilder.class);
51
52 private static final class SingletonHolder {
53 private static final DOMBuilder INSTANCE = new DOMBuilder();
54
55 private SingletonHolder() {
56 }
57 }
58
59 @GuardedBy("itself")
60 private final Transformer contentTransformer;
61
62 @GuardedBy("itself")
63 private final Transformer identityTransformer;
64
65 @GuardedBy("itself")
66 private final Transformer namespaceTransformer;
67
68
69
70
71 protected DOMBuilder() {
72 this.identityTransformer = this.createIdentityTransformer();
73 this.contentTransformer = this.createTransformer(
74 "/net/sourceforge/jeuclid/content/mathmlc2p.xsl",
75 this.identityTransformer);
76 this.namespaceTransformer = this.createTransformer(
77 "/net/sourceforge/jeuclid/addMathMLNamespace.xsl",
78 this.identityTransformer);
79 }
80
81 private Transformer createIdentityTransformer() {
82 Transformer t;
83 try {
84 t = TransformerFactory.newInstance().newTransformer();
85 } catch (final TransformerException e) {
86 DOMBuilder.LOGGER.warn(e.getMessage());
87 t = null;
88 assert false;
89 }
90 return t;
91 }
92
93 private Transformer createTransformer(final String sourceFile,
94 final Transformer fallback) {
95 Transformer t;
96 try {
97 t = TransformerFactory.newInstance().newTemplates(
98 new StreamSource(DOMBuilder.class
99 .getResourceAsStream(sourceFile))).newTransformer();
100 } catch (final TransformerException e) {
101 DOMBuilder.LOGGER.warn(e.getMessage());
102 t = fallback;
103 }
104 return t;
105 }
106
107
108
109
110 public static DOMBuilder getInstance() {
111 return DOMBuilder.SingletonHolder.INSTANCE;
112 }
113
114
115
116
117
118
119
120 @Deprecated
121 public static DOMBuilder getDOMBuilder() {
122 return DOMBuilder.getInstance();
123 }
124
125
126
127
128
129
130
131
132
133
134 public DocumentElement createJeuclidDom(final Node node) {
135 return this.createJeuclidDom(node, true);
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 public DocumentElement createJeuclidDom(final Node node,
154 final boolean supportContent) {
155 return this.createJeuclidDom(node, supportContent, false);
156 }
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 public DocumentElement createJeuclidDom(final Node node,
177 final boolean supportContent, final boolean addNamespace) {
178 Node documentElement;
179 if (node instanceof Document) {
180 documentElement = ((Document) node).getDocumentElement();
181 } else if (node instanceof Element) {
182 documentElement = node;
183 } else if (node instanceof DocumentFragment) {
184 final Node child = node.getFirstChild();
185 if (!(child instanceof Element)) {
186 throw new IllegalArgumentException(
187 "Expected DocumentFragment with Element child");
188 }
189 documentElement = child;
190 } else {
191 throw new IllegalArgumentException("Unsupported node: " + node
192 + ". Expected either Document, Element or DocumentFragment");
193 }
194
195 if (addNamespace) {
196 documentElement = this.applyTransform(documentElement,
197 this.namespaceTransformer);
198 }
199
200 final DocumentElement d;
201 if (supportContent) {
202 d = this.applyTransform(documentElement, this.contentTransformer);
203 } else {
204 d = this.applyTransform(documentElement, this.identityTransformer);
205 }
206 return d;
207 }
208
209 private DocumentElement applyTransform(final Node src,
210 final Transformer transformer) {
211 DocumentElement d;
212 try {
213 final DOMSource source = new DOMSource(src);
214 d = new DocumentElement();
215 final DOMResult result = new DOMResult(d);
216 synchronized (transformer) {
217 transformer.transform(source, result);
218 }
219 } catch (final TransformerException e) {
220 d = null;
221 DOMBuilder.LOGGER.warn(e.getMessage());
222 } catch (final NullPointerException e) {
223 d = null;
224
225 DOMBuilder.LOGGER.warn(e.getMessage());
226 } catch (final DOMException e) {
227 d = null;
228 DOMBuilder.LOGGER.warn(e.getMessage());
229 }
230 return d;
231 }
232
233 }