001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.xml;
016    
017    import com.liferay.portal.kernel.util.StringUtil;
018    import com.liferay.portal.kernel.xml.Attribute;
019    import com.liferay.portal.kernel.xml.CDATA;
020    import com.liferay.portal.kernel.xml.Element;
021    import com.liferay.portal.kernel.xml.Entity;
022    import com.liferay.portal.kernel.xml.Namespace;
023    import com.liferay.portal.kernel.xml.Node;
024    import com.liferay.portal.kernel.xml.QName;
025    import com.liferay.portal.kernel.xml.Text;
026    import com.liferay.portal.kernel.xml.Visitor;
027    import com.liferay.util.xml.XMLFormatter;
028    
029    import java.io.IOException;
030    
031    import java.util.Iterator;
032    import java.util.List;
033    import java.util.Map;
034    import java.util.TreeMap;
035    
036    /**
037     * @author Brian Wing Shun Chan
038     */
039    public class ElementImpl extends BranchImpl implements Element {
040    
041            public ElementImpl(org.dom4j.Element element) {
042                    super(element);
043    
044                    _element = element;
045            }
046    
047            @Override
048            public <T, V extends Visitor<T>> T accept(V visitor) {
049                    return visitor.visitElement(this);
050            }
051    
052            @Override
053            public void add(Attribute attribute) {
054                    AttributeImpl attributeImpl = (AttributeImpl)attribute;
055    
056                    _element.add(attributeImpl.getWrappedAttribute());
057            }
058    
059            @Override
060            public void add(CDATA cdata) {
061                    CDATAImpl cdataImpl = (CDATAImpl)cdata;
062    
063                    _element.add(cdataImpl.getWrappedCDATA());
064            }
065    
066            @Override
067            public void add(Entity entity) {
068                    EntityImpl entityImpl = (EntityImpl)entity;
069    
070                    _element.add(entityImpl.getWrappedEntity());
071            }
072    
073            @Override
074            public void add(Namespace namespace) {
075                    NamespaceImpl namespaceImpl = (NamespaceImpl)namespace;
076    
077                    _element.add(namespaceImpl.getWrappedNamespace());
078            }
079    
080            @Override
081            public void add(Text text) {
082                    TextImpl textImpl = (TextImpl)text;
083    
084                    _element.add(textImpl.getWrappedText());
085            }
086    
087            @Override
088            public Element addAttribute(QName qName, String value) {
089                    QNameImpl qNameImpl = (QNameImpl)qName;
090    
091                    return new ElementImpl(
092                            _element.addAttribute(qNameImpl.getWrappedQName(), value));
093            }
094    
095            @Override
096            public Element addAttribute(String name, String value) {
097                    return new ElementImpl(_element.addAttribute(name, value));
098            }
099    
100            @Override
101            public Element addCDATA(String cdata) {
102                    cdata = StringUtil.replace(cdata, "]]>", "]]]]><![CDATA[>");
103    
104                    return new ElementImpl(_element.addCDATA(cdata));
105            }
106    
107            @Override
108            public Element addComment(String comment) {
109                    return new ElementImpl(_element.addComment(comment));
110            }
111    
112            @Override
113            public Element addEntity(String name, String text) {
114                    return new ElementImpl(_element.addEntity(name, text));
115            }
116    
117            @Override
118            public List<Namespace> additionalNamespaces() {
119                    return SAXReaderImpl.toNewNamespaces(_element.additionalNamespaces());
120            }
121    
122            @Override
123            public Element addNamespace(String prefix, String uri) {
124                    return new ElementImpl(_element.addNamespace(prefix, uri));
125            }
126    
127            @Override
128            public Element addProcessingInstruction(
129                    String target, Map<String, String> data) {
130    
131                    return new ElementImpl(_element.addProcessingInstruction(target, data));
132            }
133    
134            @Override
135            public Element addProcessingInstruction(String target, String data) {
136                    return new ElementImpl(_element.addProcessingInstruction(target, data));
137            }
138    
139            @Override
140            public Element addText(String text) {
141                    return new ElementImpl(_element.addText(text));
142            }
143    
144            @Override
145            public void appendAttributes(Element element) {
146                    ElementImpl elementImpl = (ElementImpl)element;
147    
148                    _element.appendAttributes(elementImpl.getWrappedElement());
149            }
150    
151            @Override
152            public Attribute attribute(int index) {
153                    org.dom4j.Attribute attribute = _element.attribute(index);
154    
155                    if (attribute == null) {
156                            return null;
157                    }
158                    else {
159                            return new AttributeImpl(attribute);
160                    }
161            }
162    
163            @Override
164            public Attribute attribute(QName qName) {
165                    QNameImpl qNameImpl = (QNameImpl)qName;
166    
167                    org.dom4j.Attribute attribute = _element.attribute(
168                            qNameImpl.getWrappedQName());
169    
170                    if (attribute == null) {
171                            return null;
172                    }
173                    else {
174                            return new AttributeImpl(attribute);
175                    }
176            }
177    
178            @Override
179            public Attribute attribute(String name) {
180                    org.dom4j.Attribute attribute = _element.attribute(name);
181    
182                    if (attribute == null) {
183                            return null;
184                    }
185                    else {
186                            return new AttributeImpl(attribute);
187                    }
188            }
189    
190            @Override
191            public int attributeCount() {
192                    return _element.attributeCount();
193            }
194    
195            @Override
196            public Iterator<Attribute> attributeIterator() {
197                    return attributes().iterator();
198            }
199    
200            @Override
201            public List<Attribute> attributes() {
202                    return SAXReaderImpl.toNewAttributes(_element.attributes());
203            }
204    
205            @Override
206            public String attributeValue(QName qName) {
207                    QNameImpl qNameImpl = (QNameImpl)qName;
208    
209                    return _element.attributeValue(qNameImpl.getWrappedQName());
210            }
211    
212            @Override
213            public String attributeValue(QName qName, String defaultValue) {
214                    QNameImpl qNameImpl = (QNameImpl)qName;
215    
216                    return _element.attributeValue(
217                            qNameImpl.getWrappedQName(), defaultValue);
218            }
219    
220            @Override
221            public String attributeValue(String name) {
222                    return _element.attributeValue(name);
223            }
224    
225            @Override
226            public String attributeValue(String name, String defaultValue) {
227                    return _element.attributeValue(name, defaultValue);
228            }
229    
230            @Override
231            public Element createCopy() {
232                    return new ElementImpl(_element.createCopy());
233            }
234    
235            @Override
236            public Element createCopy(QName qName) {
237                    QNameImpl qNameImpl = (QNameImpl)qName;
238    
239                    return new ElementImpl(
240                            _element.createCopy(qNameImpl.getWrappedQName()));
241            }
242    
243            @Override
244            public Element createCopy(String name) {
245                    return new ElementImpl(_element.createCopy(name));
246            }
247    
248            @Override
249            public List<Namespace> declaredNamespaces() {
250                    return SAXReaderImpl.toNewNamespaces(_element.declaredNamespaces());
251            }
252    
253            @Override
254            public Element element(QName qName) {
255                    QNameImpl qNameImpl = (QNameImpl)qName;
256    
257                    org.dom4j.Element element = _element.element(
258                            qNameImpl.getWrappedQName());
259    
260                    if (element == null) {
261                            return null;
262                    }
263                    else {
264                            return new ElementImpl(element);
265                    }
266            }
267    
268            @Override
269            public Element element(String name) {
270                    org.dom4j.Element element = _element.element(name);
271    
272                    if (element == null) {
273                            return null;
274                    }
275                    else {
276                            return new ElementImpl(element);
277                    }
278            }
279    
280            @Override
281            public Iterator<Element> elementIterator() {
282                    return elements().iterator();
283            }
284    
285            @Override
286            public Iterator<Element> elementIterator(QName qName) {
287                    return elements(qName).iterator();
288            }
289    
290            @Override
291            public Iterator<Element> elementIterator(String name) {
292                    return elements(name).iterator();
293            }
294    
295            @Override
296            public List<Element> elements() {
297                    return SAXReaderImpl.toNewElements(_element.elements());
298            }
299    
300            @Override
301            public List<Element> elements(QName qName) {
302                    QNameImpl qNameImpl = (QNameImpl)qName;
303    
304                    return SAXReaderImpl.toNewElements(
305                            _element.elements(qNameImpl.getWrappedQName()));
306            }
307    
308            @Override
309            public List<Element> elements(String name) {
310                    return SAXReaderImpl.toNewElements(_element.elements(name));
311            }
312    
313            @Override
314            public String elementText(QName qName) {
315                    QNameImpl qNameImpl = (QNameImpl)qName;
316    
317                    return _element.elementText(qNameImpl.getWrappedQName());
318            }
319    
320            @Override
321            public String elementText(String name) {
322                    return _element.elementText(name);
323            }
324    
325            @Override
326            public String elementTextTrim(QName qName) {
327                    QNameImpl qNameImpl = (QNameImpl)qName;
328    
329                    return _element.elementTextTrim(qNameImpl.getWrappedQName());
330            }
331    
332            @Override
333            public String elementTextTrim(String name) {
334                    return _element.elementTextTrim(name);
335            }
336    
337            @Override
338            public boolean equals(Object obj) {
339                    if (this == obj) {
340                            return true;
341                    }
342    
343                    if (obj instanceof NodeImpl) {
344                            NodeImpl nodeImpl = (NodeImpl)obj;
345    
346                            if (nodeImpl.getWrappedNode() instanceof org.dom4j.Element) {
347                                    obj = new ElementImpl(
348                                            (org.dom4j.Element)nodeImpl.getWrappedNode());
349                            }
350                            else {
351                                    return false;
352                            }
353                    }
354                    else if (!(obj instanceof ElementImpl)) {
355                            return false;
356                    }
357    
358                    org.dom4j.Element element = ((ElementImpl)obj).getWrappedElement();
359    
360                    return _element.equals(element);
361            }
362    
363            @Override
364            public String formattedString() throws IOException {
365                    return XMLFormatter.toString(_element);
366            }
367    
368            @Override
369            public String formattedString(String indent) throws IOException {
370                    return XMLFormatter.toString(_element, indent);
371            }
372    
373            @Override
374            public String formattedString(String indent, boolean expandEmptyElements)
375                    throws IOException {
376    
377                    return XMLFormatter.toString(_element, indent, expandEmptyElements);
378            }
379    
380            @Override
381            public Object getData() {
382                    return _element.getData();
383            }
384    
385            @Override
386            public Namespace getNamespace() {
387                    org.dom4j.Namespace namespace = _element.getNamespace();
388    
389                    if (namespace == null) {
390                            return null;
391                    }
392                    else {
393                            return new NamespaceImpl(namespace);
394                    }
395            }
396    
397            @Override
398            public Namespace getNamespaceForPrefix(String prefix) {
399                    org.dom4j.Namespace namespace = _element.getNamespaceForPrefix(prefix);
400    
401                    if (namespace == null) {
402                            return null;
403                    }
404                    else {
405                            return new NamespaceImpl(namespace);
406                    }
407            }
408    
409            @Override
410            public Namespace getNamespaceForURI(String uri) {
411                    org.dom4j.Namespace namespace = _element.getNamespaceForURI(uri);
412    
413                    if (namespace == null) {
414                            return null;
415                    }
416                    else {
417                            return new NamespaceImpl(namespace);
418                    }
419            }
420    
421            @Override
422            public String getNamespacePrefix() {
423                    return _element.getNamespacePrefix();
424            }
425    
426            @Override
427            public List<Namespace> getNamespacesForURI(String uri) {
428                    return SAXReaderImpl.toNewNamespaces(_element.getNamespacesForURI(uri));
429            }
430    
431            @Override
432            public String getNamespaceURI() {
433                    return _element.getNamespaceURI();
434            }
435    
436            @Override
437            public QName getQName() {
438                    org.dom4j.QName qName = _element.getQName();
439    
440                    if (qName == null) {
441                            return null;
442                    }
443                    else {
444                            return new QNameImpl(qName);
445                    }
446            }
447    
448            @Override
449            public QName getQName(String qualifiedName) {
450                    org.dom4j.QName qName = _element.getQName(qualifiedName);
451    
452                    if (qName == null) {
453                            return null;
454                    }
455                    else {
456                            return new QNameImpl(qName);
457                    }
458            }
459    
460            @Override
461            public String getQualifiedName() {
462                    return _element.getQualifiedName();
463            }
464    
465            @Override
466            public String getTextTrim() {
467                    return _element.getTextTrim();
468            }
469    
470            public org.dom4j.Element getWrappedElement() {
471                    return _element;
472            }
473    
474            @Override
475            public Node getXPathResult(int index) {
476                    org.dom4j.Node node = _element.getXPathResult(index);
477    
478                    if (node == null) {
479                            return null;
480                    }
481                    else {
482                            return new NodeImpl(node);
483                    }
484            }
485    
486            @Override
487            public int hashCode() {
488                    return _element.hashCode();
489            }
490    
491            @Override
492            public boolean hasMixedContent() {
493                    return _element.hasMixedContent();
494            }
495    
496            @Override
497            public boolean isRootElement() {
498                    return _element.isRootElement();
499            }
500    
501            @Override
502            public boolean isTextOnly() {
503                    return _element.isTextOnly();
504            }
505    
506            @Override
507            public boolean remove(Attribute attribute) {
508                    AttributeImpl attributeImpl = (AttributeImpl)attribute;
509    
510                    return _element.remove(attributeImpl.getWrappedAttribute());
511            }
512    
513            @Override
514            public boolean remove(CDATA cdata) {
515                    CDATAImpl cdataImpl = (CDATAImpl)cdata;
516    
517                    return _element.remove(cdataImpl.getWrappedCDATA());
518            }
519    
520            @Override
521            public boolean remove(Entity entity) {
522                    EntityImpl entityImpl = (EntityImpl)entity;
523    
524                    return _element.remove(entityImpl.getWrappedEntity());
525            }
526    
527            @Override
528            public boolean remove(Namespace namespace) {
529                    NamespaceImpl namespaceImpl = (NamespaceImpl)namespace;
530    
531                    return _element.remove(namespaceImpl.getWrappedNamespace());
532            }
533    
534            @Override
535            public boolean remove(Text text) {
536                    TextImpl textImpl = (TextImpl)text;
537    
538                    return _element.remove(textImpl.getWrappedText());
539            }
540    
541            @Override
542            public void setAttributes(List<Attribute> attributes) {
543                    _element.setAttributes(SAXReaderImpl.toOldAttributes(attributes));
544            }
545    
546            @Override
547            public void setData(Object data) {
548                    _element.setData(data);
549            }
550    
551            @Override
552            public void setQName(QName qName) {
553                    QNameImpl qNameImpl = (QNameImpl)qName;
554    
555                    _element.setQName(qNameImpl.getWrappedQName());
556            }
557    
558            @Override
559            public void sortAttributes(boolean recursive) {
560                    Map<String, Attribute> attributesMap = new TreeMap<String, Attribute>();
561    
562                    List<Attribute> attributes = attributes();
563    
564                    for (Attribute attribute : attributes) {
565                            attribute.detach();
566    
567                            attributesMap.put(attribute.getName(), attribute);
568                    }
569    
570                    for (Map.Entry<String, Attribute> entry : attributesMap.entrySet()) {
571                            Attribute attribute = entry.getValue();
572    
573                            add(attribute);
574                    }
575    
576                    if (!recursive) {
577                            return;
578                    }
579    
580                    List<Element> elements = elements();
581    
582                    for (Element element : elements) {
583                            element.sortAttributes(true);
584                    }
585            }
586    
587            @Override
588            public void sortElementsByAttribute(
589                    String elementName, String attributeName) {
590    
591                    Map<String, Element> elementsMap = new TreeMap<String, Element>();
592    
593                    List<Element> elements = elements();
594    
595                    for (Element element : elements) {
596                            element.detach();
597    
598                            if (elementName.equals(element.getName())) {
599                                    String attributeValue = element.attributeValue(attributeName);
600    
601                                    elementsMap.put(attributeValue, element);
602                            }
603                    }
604    
605                    for (Element element : elements) {
606                            if (elementName.equals(element.getName())) {
607                                    break;
608                            }
609    
610                            add(element);
611                    }
612    
613                    for (Map.Entry<String, Element> entry : elementsMap.entrySet()) {
614                            Element element = entry.getValue();
615    
616                            add(element);
617                    }
618    
619                    boolean foundLastElementWithElementName = false;
620    
621                    for (int i = 0; i < elements.size(); i++) {
622                            Element element = elements.get(i);
623    
624                            if (!foundLastElementWithElementName) {
625                                    if (elementName.equals(element.getName())) {
626                                            if ((i + 1) < elements.size()) {
627                                                    Element nextElement = elements.get(i + 1);
628    
629                                                    if (!elementName.equals(nextElement.getName())) {
630                                                            foundLastElementWithElementName = true;
631                                                    }
632                                            }
633                                    }
634                            }
635                            else {
636                                    add(element);
637                            }
638                    }
639            }
640    
641            @Override
642            public void sortElementsByChildElement(
643                    String elementName, String childElementName) {
644    
645                    Map<String, Element> elementsMap = new TreeMap<String, Element>();
646    
647                    List<Element> elements = elements();
648    
649                    for (Element element : elements) {
650                            element.detach();
651    
652                            if (elementName.equals(element.getName())) {
653                                    String childElementValue = element.elementText(
654                                            childElementName);
655    
656                                    elementsMap.put(childElementValue, element);
657                            }
658                    }
659    
660                    for (Element element : elements) {
661                            if (elementName.equals(element.getName())) {
662                                    break;
663                            }
664    
665                            add(element);
666                    }
667    
668                    for (Map.Entry<String, Element> entry : elementsMap.entrySet()) {
669                            Element element = entry.getValue();
670    
671                            add(element);
672                    }
673    
674                    boolean foundLastElementWithElementName = false;
675    
676                    for (int i = 0; i < elements.size(); i++) {
677                            Element element = elements.get(i);
678    
679                            if (!foundLastElementWithElementName) {
680                                    if (elementName.equals(element.getName())) {
681                                            if ((i + 1) < elements.size()) {
682                                                    Element nextElement = elements.get(i + 1);
683    
684                                                    if (!elementName.equals(nextElement.getName())) {
685                                                            foundLastElementWithElementName = true;
686                                                    }
687                                            }
688                                    }
689                            }
690                            else {
691                                    add(element);
692                            }
693                    }
694            }
695    
696            @Override
697            public String toString() {
698                    return _element.toString();
699            }
700    
701            private org.dom4j.Element _element;
702    
703    }