001    /**
002     * Copyright (c) 2000-2010 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.util.xml.descriptor;
016    
017    import com.liferay.util.xml.AttributeComparator;
018    import com.liferay.util.xml.ElementComparator;
019    
020    import java.util.Comparator;
021    import java.util.List;
022    
023    import org.dom4j.Attribute;
024    import org.dom4j.Document;
025    import org.dom4j.Element;
026    
027    /**
028     * @author Jorge Ferrer
029     */
030    public class StrictXMLDescriptor implements XMLDescriptor {
031    
032            public boolean areEqual(Element el1, Element el2) {
033                    if (_compare(el1, el2) == 0) {
034                            return true;
035                    }
036                    else {
037                            return false;
038                    }
039            }
040    
041            public boolean canHandleType(String doctype, Document root) {
042                    return false;
043            }
044    
045            public boolean canJoinChildren(Element element) {
046                    return false;
047            }
048    
049            public String[] getRootChildrenOrder() {
050                    return _ROOT_ORDERED_CHILDREN;
051            }
052    
053            public String[] getChildrenOrder(Element parentElement) {
054                    return new String[0];
055            }
056    
057            private int _compare(Object obj1, Object obj2) {
058                    Element el1 = (Element)obj1;
059                    Element el2 = (Element)obj2;
060    
061                    String el1Name = el1.getName();
062                    String el2Name = el2.getName();
063    
064                    if (!el1Name.equals(el2Name)) {
065                            return el1Name.compareTo(el2Name);
066                    }
067    
068                    String el1Text = el1.getTextTrim();
069                    String el2Text = el2.getTextTrim();
070    
071                    if (!el1Text.equals(el2Text)) {
072                            return el1Text.compareTo(el2Text);
073                    }
074    
075                    int attributeComparison = _compareAttributes(el1, el2);
076    
077                    if (attributeComparison != 0) {
078                            return attributeComparison;
079                    }
080    
081                    int childrenComparison = _compareChildren(el1, el2);
082    
083                    if (childrenComparison != 0) {
084                            return childrenComparison;
085                    }
086    
087                    return 0;
088            }
089    
090            private int _compareAttributes(Element el1, Element el2) {
091                    List<Attribute> el1Attrs = el1.attributes();
092                    List<Attribute> el2Attrs = el2.attributes();
093    
094                    if (el1Attrs.size() < el2Attrs.size()) {
095                            return -1;
096                    }
097                    else if (el1Attrs.size() > el2Attrs.size()) {
098                            return 1;
099                    }
100    
101                    for (Attribute attr : el1Attrs) {
102                            int value = _contains(el2Attrs, attr, new AttributeComparator());
103    
104                            if (value != 0) {
105                                    return value;
106                            }
107                    }
108    
109                    return -1;
110            }
111    
112            private int _compareChildren(Element el1, Element el2) {
113                    List<Element> el1Children = el1.elements();
114                    List<Element> el2Children = el2.elements();
115    
116                    if (el1Children.size() < el2Children.size()) {
117                            return -1;
118                    }
119                    else if (el1Children.size() > el2Children.size()) {
120                            return 1;
121                    }
122    
123                    for (Element el : el1Children) {
124                            int value = _contains(el2Children, el, new ElementComparator());
125    
126                            if (value != 0) {
127                                    return value;
128                            }
129                    }
130    
131                    return -1;
132            }
133    
134            private int _contains(
135                    List<Attribute> list, Attribute obj, Comparator<Attribute> comparator) {
136    
137                    int firstValue = -1;
138    
139                    for (int i = 0; i < list.size(); i++) {
140                            Attribute o = list.get(i);
141    
142                            int value = comparator.compare(obj, o);
143    
144                            if (i == 0) {
145                                    firstValue = value;
146                            }
147    
148                            if (value == 0) {
149                                    return 0;
150                            }
151                    }
152    
153                    return firstValue;
154            }
155    
156            private int _contains(
157                    List<Element> list, Element obj, Comparator<Element> comparator) {
158    
159                    int firstValue = -1;
160    
161                    for (int i = 0; i < list.size(); i++) {
162                            Element o = list.get(i);
163    
164                            int value = comparator.compare(obj, o);
165    
166                            if (i == 0) {
167                                    firstValue = value;
168                            }
169    
170                            if (value == 0) {
171                                    return 0;
172                            }
173                    }
174    
175                    return firstValue;
176            }
177    
178            private static final String[] _ROOT_ORDERED_CHILDREN = {
179            };
180    
181    }