001
014
015 package com.liferay.portal.xml;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.xml.Attribute;
020 import com.liferay.portal.kernel.xml.Document;
021 import com.liferay.portal.kernel.xml.DocumentException;
022 import com.liferay.portal.kernel.xml.Element;
023 import com.liferay.portal.kernel.xml.Entity;
024 import com.liferay.portal.kernel.xml.Namespace;
025 import com.liferay.portal.kernel.xml.Node;
026 import com.liferay.portal.kernel.xml.ProcessingInstruction;
027 import com.liferay.portal.kernel.xml.QName;
028 import com.liferay.portal.kernel.xml.SAXReader;
029 import com.liferay.portal.kernel.xml.Text;
030 import com.liferay.portal.kernel.xml.XPath;
031 import com.liferay.portal.util.EntityResolver;
032 import com.liferay.portal.util.PropsValues;
033 import com.liferay.util.xml.XMLSafeReader;
034
035 import java.io.File;
036 import java.io.InputStream;
037 import java.io.Reader;
038
039 import java.net.MalformedURLException;
040 import java.net.URL;
041
042 import java.util.ArrayList;
043 import java.util.HashMap;
044 import java.util.List;
045 import java.util.Map;
046
047 import org.apache.xerces.parsers.SAXParser;
048
049 import org.dom4j.DocumentFactory;
050 import org.dom4j.DocumentHelper;
051
052
055 public class SAXReaderImpl implements SAXReader {
056
057 public static SAXReaderImpl getInstance() {
058 return _instance;
059 }
060
061 public static List<Attribute> toNewAttributes(
062 List<org.dom4j.Attribute> oldAttributes) {
063
064 List<Attribute> newAttributes = new ArrayList<Attribute>(
065 oldAttributes.size());
066
067 for (org.dom4j.Attribute oldAttribute : oldAttributes) {
068 newAttributes.add(new AttributeImpl(oldAttribute));
069 }
070
071 return new NodeList<Attribute, org.dom4j.Attribute>(
072 newAttributes, oldAttributes);
073 }
074
075 public static List<Element> toNewElements(
076 List<org.dom4j.Element> oldElements) {
077
078 List<Element> newElements = new ArrayList<Element>(oldElements.size());
079
080 for (org.dom4j.Element oldElement : oldElements) {
081 newElements.add(new ElementImpl(oldElement));
082 }
083
084 return new NodeList<Element, org.dom4j.Element>(
085 newElements, oldElements);
086 }
087
088 public static List<Namespace> toNewNamespaces(
089 List<org.dom4j.Namespace> oldNamespaces) {
090
091 List<Namespace> newNamespaces = new ArrayList<Namespace>(
092 oldNamespaces.size());
093
094 for (org.dom4j.Namespace oldNamespace : oldNamespaces) {
095 newNamespaces.add(new NamespaceImpl(oldNamespace));
096 }
097
098 return new NodeList<Namespace, org.dom4j.Namespace>(
099 newNamespaces, oldNamespaces);
100 }
101
102 public static List<Node> toNewNodes(List<org.dom4j.Node> oldNodes) {
103 List<Node> newNodes = new ArrayList<Node>(oldNodes.size());
104
105 for (org.dom4j.Node oldNode : oldNodes) {
106 if (oldNode instanceof org.dom4j.Element) {
107 newNodes.add(new ElementImpl((org.dom4j.Element)oldNode));
108 }
109 else {
110 newNodes.add(new NodeImpl(oldNode));
111 }
112 }
113
114 return new NodeList<Node, org.dom4j.Node>(newNodes, oldNodes);
115 }
116
117 public static List<ProcessingInstruction> toNewProcessingInstructions(
118 List<org.dom4j.ProcessingInstruction> oldProcessingInstructions) {
119
120 List<ProcessingInstruction> newProcessingInstructions =
121 new ArrayList<ProcessingInstruction>(
122 oldProcessingInstructions.size());
123
124 for (org.dom4j.ProcessingInstruction oldProcessingInstruction :
125 oldProcessingInstructions) {
126
127 newProcessingInstructions.add(
128 new ProcessingInstructionImpl(oldProcessingInstruction));
129 }
130
131 return new NodeList
132 <ProcessingInstruction, org.dom4j.ProcessingInstruction>(
133 newProcessingInstructions, oldProcessingInstructions);
134 }
135
136 public static List<org.dom4j.Attribute> toOldAttributes(
137 List<Attribute> newAttributes) {
138
139 List<org.dom4j.Attribute> oldAttributes =
140 new ArrayList<org.dom4j.Attribute>(newAttributes.size());
141
142 for (Attribute newAttribute : newAttributes) {
143 AttributeImpl newAttributeImpl = (AttributeImpl)newAttribute;
144
145 oldAttributes.add(newAttributeImpl.getWrappedAttribute());
146 }
147
148 return oldAttributes;
149 }
150
151 public static List<org.dom4j.Node> toOldNodes(List<Node> newNodes) {
152 List<org.dom4j.Node> oldNodes = new ArrayList<org.dom4j.Node>(
153 newNodes.size());
154
155 for (Node newNode : newNodes) {
156 NodeImpl newNodeImpl = (NodeImpl)newNode;
157
158 oldNodes.add(newNodeImpl.getWrappedNode());
159 }
160
161 return oldNodes;
162 }
163
164 public static List<org.dom4j.ProcessingInstruction>
165 toOldProcessingInstructions(
166 List<ProcessingInstruction> newProcessingInstructions) {
167
168 List<org.dom4j.ProcessingInstruction> oldProcessingInstructions =
169 new ArrayList<org.dom4j.ProcessingInstruction>(
170 newProcessingInstructions.size());
171
172 for (ProcessingInstruction newProcessingInstruction :
173 newProcessingInstructions) {
174
175 ProcessingInstructionImpl newProcessingInstructionImpl =
176 (ProcessingInstructionImpl)newProcessingInstruction;
177
178 oldProcessingInstructions.add(
179 newProcessingInstructionImpl.getWrappedProcessingInstruction());
180 }
181
182 return oldProcessingInstructions;
183 }
184
185 public Attribute createAttribute(
186 Element element, QName qName, String value) {
187
188 ElementImpl elementImpl = (ElementImpl)element;
189 QNameImpl qNameImpl = (QNameImpl)qName;
190
191 DocumentFactory documentFactory = DocumentFactory.getInstance();
192
193 return new AttributeImpl(
194 documentFactory.createAttribute(
195 elementImpl.getWrappedElement(), qNameImpl.getWrappedQName(),
196 value));
197 }
198
199 public Attribute createAttribute(
200 Element element, String name, String value) {
201
202 ElementImpl elementImpl = (ElementImpl)element;
203
204 DocumentFactory documentFactory = DocumentFactory.getInstance();
205
206 return new AttributeImpl(
207 documentFactory.createAttribute(
208 elementImpl.getWrappedElement(), name, value));
209 }
210
211 public Document createDocument() {
212 return new DocumentImpl(DocumentHelper.createDocument());
213 }
214
215 public Document createDocument(Element rootElement) {
216 ElementImpl rootElementImpl = (ElementImpl)rootElement;
217
218 return new DocumentImpl(
219 DocumentHelper.createDocument(rootElementImpl.getWrappedElement()));
220 }
221
222 public Document createDocument(String encoding) {
223 DocumentFactory documentFactory = DocumentFactory.getInstance();
224
225 return new DocumentImpl(documentFactory.createDocument(encoding));
226 }
227
228 public Element createElement(QName qName) {
229 QNameImpl qNameImpl = (QNameImpl)qName;
230
231 return new ElementImpl(
232 DocumentHelper.createElement(qNameImpl.getWrappedQName()));
233 }
234
235 public Element createElement(String name) {
236 return new ElementImpl(DocumentHelper.createElement(name));
237 }
238
239 public Entity createEntity(String name, String text) {
240 return new EntityImpl(DocumentHelper.createEntity(name, text));
241 }
242
243 public Namespace createNamespace(String uri) {
244 return new NamespaceImpl(org.dom4j.Namespace.get(uri));
245 }
246
247 public Namespace createNamespace(String prefix, String uri) {
248 return new NamespaceImpl(DocumentHelper.createNamespace(prefix, uri));
249 }
250
251 public ProcessingInstruction createProcessingInstruction(
252 String target, Map<String, String> data) {
253
254 org.dom4j.ProcessingInstruction processingInstruction =
255 DocumentHelper.createProcessingInstruction(target, data);
256
257 if (processingInstruction == null) {
258 return null;
259 }
260 else {
261 return new ProcessingInstructionImpl(processingInstruction);
262 }
263 }
264
265 public ProcessingInstruction createProcessingInstruction(
266 String target, String data) {
267
268 org.dom4j.ProcessingInstruction processingInstruction =
269 DocumentHelper.createProcessingInstruction(target, data);
270
271 if (processingInstruction == null) {
272 return null;
273 }
274 else {
275 return new ProcessingInstructionImpl(processingInstruction);
276 }
277 }
278
279 public QName createQName(String localName) {
280 return new QNameImpl(DocumentHelper.createQName(localName));
281 }
282
283 public QName createQName(String localName, Namespace namespace) {
284 NamespaceImpl namespaceImpl = (NamespaceImpl)namespace;
285
286 return new QNameImpl(
287 DocumentHelper.createQName(
288 localName, namespaceImpl.getWrappedNamespace()));
289 }
290
291 public Text createText(String text) {
292 return new TextImpl(DocumentHelper.createText(text));
293 }
294
295 public XPath createXPath(String xPathExpression) {
296 return createXPath(xPathExpression, null);
297 }
298
299 public XPath createXPath(
300 String xPathExpression, Map<String, String> namespaceContextMap) {
301
302 return new XPathImpl(
303 DocumentHelper.createXPath(xPathExpression), namespaceContextMap);
304 }
305
306 public XPath createXPath(
307 String xPathExpression, String prefix, String namespace) {
308
309 Map<String, String> namespaceContextMap = new HashMap<String, String>();
310
311 namespaceContextMap.put(prefix, namespace);
312
313 return createXPath(xPathExpression, namespaceContextMap);
314 }
315
316 public Document read(File file) throws DocumentException {
317 return read(file, false);
318 }
319
320 public Document read(File file, boolean validate)
321 throws DocumentException {
322
323 ClassLoader classLoader = getClass().getClassLoader();
324
325 Thread currentThread = Thread.currentThread();
326
327 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
328
329 try {
330 if (contextClassLoader != classLoader) {
331 currentThread.setContextClassLoader(classLoader);
332 }
333
334 org.dom4j.io.SAXReader saxReader = getSAXReader(validate);
335
336 return new DocumentImpl(saxReader.read(file));
337 }
338 catch (org.dom4j.DocumentException de) {
339 throw new DocumentException(de.getMessage(), de);
340 }
341 finally {
342 if (contextClassLoader != classLoader) {
343 currentThread.setContextClassLoader(contextClassLoader);
344 }
345 }
346 }
347
348 public Document read(InputStream is) throws DocumentException {
349 return read(is, false);
350 }
351
352 public Document read(InputStream is, boolean validate)
353 throws DocumentException {
354
355 ClassLoader classLoader = getClass().getClassLoader();
356
357 Thread currentThread = Thread.currentThread();
358
359 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
360
361 try {
362 if (contextClassLoader != classLoader) {
363 currentThread.setContextClassLoader(classLoader);
364 }
365
366 org.dom4j.io.SAXReader saxReader = getSAXReader(validate);
367
368 return new DocumentImpl(saxReader.read(is));
369 }
370 catch (org.dom4j.DocumentException de) {
371 throw new DocumentException(de.getMessage(), de);
372 }
373 finally {
374 if (contextClassLoader != classLoader) {
375 currentThread.setContextClassLoader(contextClassLoader);
376 }
377 }
378 }
379
380 public Document read(Reader reader) throws DocumentException {
381 return read(reader, false);
382 }
383
384 public Document read(Reader reader, boolean validate)
385 throws DocumentException {
386
387 ClassLoader classLoader = getClass().getClassLoader();
388
389 Thread currentThread = Thread.currentThread();
390
391 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
392
393 try {
394 if (contextClassLoader != classLoader) {
395 currentThread.setContextClassLoader(classLoader);
396 }
397
398 org.dom4j.io.SAXReader saxReader = getSAXReader(validate);
399
400 return new DocumentImpl(saxReader.read(reader));
401 }
402 catch (org.dom4j.DocumentException de) {
403 throw new DocumentException(de.getMessage(), de);
404 }
405 finally {
406 if (contextClassLoader != classLoader) {
407 currentThread.setContextClassLoader(contextClassLoader);
408 }
409 }
410 }
411
412 public Document read(String xml) throws DocumentException {
413 return read(new XMLSafeReader(xml));
414 }
415
416 public Document read(String xml, boolean validate)
417 throws DocumentException {
418
419 return read(new XMLSafeReader(xml), validate);
420 }
421
422 public Document read(URL url) throws DocumentException {
423 return read(url, false);
424 }
425
426 public Document read(URL url, boolean validate) throws DocumentException {
427 ClassLoader classLoader = getClass().getClassLoader();
428
429 Thread currentThread = Thread.currentThread();
430
431 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
432
433 try {
434 if (contextClassLoader != classLoader) {
435 currentThread.setContextClassLoader(classLoader);
436 }
437
438 org.dom4j.io.SAXReader saxReader = getSAXReader(validate);
439
440 return new DocumentImpl(saxReader.read(url));
441 }
442 catch (org.dom4j.DocumentException de) {
443 throw new DocumentException(de.getMessage(), de);
444 }
445 finally {
446 if (contextClassLoader != classLoader) {
447 currentThread.setContextClassLoader(contextClassLoader);
448 }
449 }
450 }
451
452 public Document readURL(String url)
453 throws DocumentException, MalformedURLException {
454
455 return read(new URL(url), false);
456 }
457
458 public Document readURL(String url, boolean validate)
459 throws DocumentException, MalformedURLException {
460
461 return read(new URL(url), validate);
462 }
463
464 public List<Node> selectNodes(
465 String xPathFilterExpression, List<Node> nodes) {
466
467 return toNewNodes(
468 DocumentHelper.selectNodes(
469 xPathFilterExpression, toOldNodes(nodes)));
470 }
471
472 public List<Node> selectNodes(String xPathFilterExpression, Node node) {
473 NodeImpl nodeImpl = (NodeImpl)node;
474
475 return toNewNodes(
476 DocumentHelper.selectNodes(
477 xPathFilterExpression, nodeImpl.getWrappedNode()));
478 }
479
480 public void sort(List<Node> nodes, String xPathExpression) {
481 DocumentHelper.sort(toOldNodes(nodes), xPathExpression);
482 }
483
484 public void sort(
485 List<Node> nodes, String xPathExpression, boolean distinct) {
486
487 DocumentHelper.sort(toOldNodes(nodes), xPathExpression, distinct);
488 }
489
490 protected org.dom4j.io.SAXReader getSAXReader(boolean validate) {
491 org.dom4j.io.SAXReader reader = null;
492
493 if (!PropsValues.XML_VALIDATION_ENABLED) {
494 validate = false;
495 }
496
497 try {
498 reader = new org.dom4j.io.SAXReader(new SAXParser(), validate);
499
500 reader.setEntityResolver(new EntityResolver());
501
502 reader.setFeature(_FEATURES_DYNAMIC, validate);
503 reader.setFeature(_FEATURES_EXTERNAL_GENERAL_ENTITIES, validate);
504 reader.setFeature(_FEATURES_LOAD_DTD_GRAMMAR, validate);
505 reader.setFeature(_FEATURES_LOAD_EXTERNAL_DTD, validate);
506 reader.setFeature(_FEATURES_VALIDATION, validate);
507 reader.setFeature(_FEATURES_VALIDATION_SCHEMA, validate);
508 reader.setFeature(
509 _FEATURES_VALIDATION_SCHEMA_FULL_CHECKING, validate);
510 }
511 catch (Exception e) {
512 if (_log.isWarnEnabled()) {
513 _log.warn(
514 "XSD validation is disabled because " + e.getMessage());
515 }
516
517 reader = new org.dom4j.io.SAXReader(false);
518
519 reader.setEntityResolver(new EntityResolver());
520 }
521
522 return reader;
523 }
524
525 private static final String _FEATURES_DYNAMIC =
526 "http:
527
528 private static final String _FEATURES_EXTERNAL_GENERAL_ENTITIES =
529 "http:
530
531 private static final String _FEATURES_LOAD_DTD_GRAMMAR =
532 "http:
533
534 private static final String _FEATURES_LOAD_EXTERNAL_DTD =
535 "http:
536
537 private static final String _FEATURES_VALIDATION =
538 "http:
539
540 private static final String _FEATURES_VALIDATION_SCHEMA =
541 "http:
542
543 private static final String _FEATURES_VALIDATION_SCHEMA_FULL_CHECKING =
544 "http:
545
546 private static Log _log = LogFactoryUtil.getLog(SAXReaderImpl.class);
547
548 private static SAXReaderImpl _instance = new SAXReaderImpl();
549
550 }