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