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