1
2
3
4
5
6
7
8 package net.sf.saxon.option.jdom2;
9
10 import net.sf.saxon.Configuration;
11 import net.sf.saxon.event.Builder;
12 import net.sf.saxon.event.PipelineConfiguration;
13 import net.sf.saxon.event.Receiver;
14 import net.sf.saxon.expr.JPConverter;
15 import net.sf.saxon.expr.PJConverter;
16 import net.sf.saxon.expr.XPathContext;
17 import net.sf.saxon.lib.ExternalObjectModel;
18 import net.sf.saxon.lib.NamespaceConstant;
19 import net.sf.saxon.om.*;
20 import net.sf.saxon.pattern.AnyNodeTest;
21 import net.sf.saxon.tree.wrapper.VirtualNode;
22 import net.sf.saxon.type.ItemType;
23 import org.jdom2.*;
24
25 import javax.xml.transform.Result;
26 import javax.xml.transform.Source;
27
28
29
30
31
32
33
34
35 public class JDOM2ObjectModel extends TreeModel implements ExternalObjectModel {
36
37 private final static JDOM2ObjectModell.html#JDOM2ObjectModel">JDOM2ObjectModel THE_INSTANCE = new JDOM2ObjectModel();
38
39 public static JDOM2ObjectModel getInstance() {
40 return THE_INSTANCE;
41 }
42
43 public JDOM2ObjectModel() {
44 }
45
46
47
48
49
50
51
52
53 @Override
54 public String getDocumentClassName() {
55 return "org.jdom2.Document";
56 }
57
58
59
60
61
62
63 @Override
64 public String getIdentifyingURI() {
65 return NamespaceConstant.OBJECT_MODEL_JDOM;
66 }
67
68 @Override
69 public Builder makeBuilder(PipelineConfiguration pipe) {
70 return new JDOM2Writer(pipe);
71 }
72
73 @Override
74 public int getSymbolicValue() {
75 return Builder.JDOM2_TREE;
76 }
77
78 @Override
79 public String getName() {
80 return "JDOM2";
81 }
82
83
84
85
86
87
88
89
90
91 private static boolean isRecognizedNode(Object object) {
92 return object instanceof Document ||
93 object instanceof Element ||
94 object instanceof Attribute ||
95 object instanceof Text ||
96 object instanceof Comment ||
97 object instanceof ProcessingInstruction ||
98 object instanceof Namespace;
99 }
100
101
102 @Override
103 public PJConverter getPJConverter(Class<?> targetClass) {
104 if (isRecognizedNodeClass(targetClass)) {
105 return new PJConverter() {
106 @Override
107 public Object convert(Sequence value, Class<?> targetClass, XPathContext context) {
108 return convertXPathValueToObject(value, targetClass);
109 }
110 };
111 } else {
112 return null;
113 }
114 }
115
116 @Override
117 public JPConverter getJPConverter(Class sourceClass, Configuration config) {
118 if (isRecognizedNodeClass(sourceClass)) {
119 return new JPConverter() {
120 @Override
121 public Sequence convert(Object object, XPathContext context) {
122 return convertObjectToXPathValue(object, context.getConfiguration());
123 }
124
125 @Override
126 public ItemType getItemType() {
127 return AnyNodeTest.getInstance();
128 }
129 };
130 } else {
131 return null;
132 }
133 }
134
135
136
137
138
139
140
141
142
143
144
145 @Override
146 public PJConverter getNodeListCreator(Object node) {
147 return null;
148 }
149
150
151
152
153
154
155
156
157
158 private boolean isRecognizedNodeClass(Class nodeClass) {
159 return Document.class.isAssignableFrom(nodeClass) ||
160 Element.class.isAssignableFrom(nodeClass) ||
161 Attribute.class.isAssignableFrom(nodeClass) ||
162 Text.class.isAssignableFrom(nodeClass) ||
163 CDATA.class.isAssignableFrom(nodeClass) ||
164 Comment.class.isAssignableFrom(nodeClass) ||
165 ProcessingInstruction.class.isAssignableFrom(nodeClass) ||
166 Namespace.class.isAssignableFrom(nodeClass);
167 }
168
169
170
171
172
173
174
175
176 @Override
177 public Receiver getDocumentBuilder(Result result) {
178 return null;
179 }
180
181
182
183
184
185
186
187 @Override
188 public boolean sendSource(Source source, Receiver receiver) {
189 return false;
190 }
191
192
193
194
195
196
197 @Override
198 public NodeInfo unravel(Source source, Configuration config) {
199 return null;
200 }
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215 private Sequence convertObjectToXPathValue(Object object, Configuration config) {
216 if (isRecognizedNode(object)) {
217 if (object instanceof Document) {
218 return wrapDocument(object, config).getRootNode();
219 } else {
220 Document root = getDocumentRoot(object);
221 TreeInfo docInfo = wrapDocument(root, config);
222 return wrapNode(docInfo, object);
223 }
224 } else {
225 return null;
226 }
227 }
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242 private Object convertXPathValueToObject(Sequence value, Class<?> target) {
243 if (value instanceof VirtualNode) {
244 Object u = ((VirtualNode) value).getRealNode();
245 if (target.isAssignableFrom(u.getClass())) {
246 return u;
247 }
248 }
249 return null;
250 }
251
252
253
254
255
256
257
258
259
260
261
262 public TreeInfo wrapDocument(Object node, Configuration config) {
263 Document documentNode = getDocumentRoot(node);
264 return new JDOM2DocumentWrapper(documentNode, config);
265 }
266
267
268
269
270
271
272
273
274
275
276
277 public NodeInfo wrapNode(TreeInfo document, Object node) {
278 return ((JDOM2DocumentWrapper) document).wrap(node);
279 }
280
281
282
283
284
285
286
287
288 private static Document getDocumentRoot(Object node) {
289 while (!(node instanceof Document)) {
290 if (node instanceof Element) {
291 if (((Element) node).isRootElement()) {
292 return ((Element) node).getDocument();
293 } else {
294 node = ((Element) node).getParent();
295 }
296 } else if (node instanceof Text) {
297 node = ((Text) node).getParent();
298 } else if (node instanceof Comment) {
299 node = ((Comment) node).getParent();
300 } else if (node instanceof ProcessingInstruction) {
301 node = ((ProcessingInstruction) node).getParent();
302 } else if (node instanceof Attribute) {
303 node = ((Attribute) node).getParent();
304 } else if (node instanceof Namespace) {
305 throw new UnsupportedOperationException("Cannot find parent of JDOM namespace node");
306 } else {
307 throw new IllegalStateException("Unknown JDOM node type " + node.getClass());
308 }
309 }
310 return (Document) node;
311 }
312
313 }
314
315
316