1
22
23 package com.liferay.util.xml;
24
25 import com.liferay.util.xml.descriptor.XMLDescriptor;
26
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Vector;
32
33 import org.dom4j.Document;
34 import org.dom4j.Element;
35
36
44 public class XMLMerger {
45
46 public XMLMerger(XMLDescriptor descriptor) {
47 _descriptor = descriptor;
48 }
49
50 public XMLElementComparator getElementComparator() {
51 return new XMLElementComparator(_descriptor);
52 }
53
54 public Document merge(Document masterDoc, Document slaveDoc) {
55 Document mergedDoc = (Document)masterDoc.clone();
56
57 Element root1 = mergedDoc.getRootElement();
58 Element root2 = slaveDoc.getRootElement();
59
60 List children = root2.elements();
61
62 for (int i = 0; i < children.size(); i++) {
63 Element el2 = (Element)children.get(i);
64
65 Element el2Clone = (Element)el2.clone();
66
67 el2Clone.detach();
68
69 root1.add(el2Clone);
70 }
71
72 organizeXML(mergedDoc);
73
74 return mergedDoc;
75 }
76
77 public void organizeXML(Document doc) {
78 Element root = doc.getRootElement();
79
80 _orderChildren(root, _descriptor.getRootChildrenOrder());
81 _mergeDuplicateElements(root, getElementComparator());
82 }
83
84 private void _addChildren(Element first, Collection childrenToJoin) {
85 Collection clones = new Vector();
86
87 Iterator itr = childrenToJoin.iterator();
88
89 while (itr.hasNext()) {
90 clones.add(((Element)itr.next()).clone());
91 }
92
93 first.elements().addAll(clones);
94 }
95
96 private boolean _containsObjectEqualTo(
97 Element example, List list, ElementComparator comparator) {
98
99 Iterator itr = list.iterator();
100
101 while (itr.hasNext()) {
102 Element candidate = (Element)itr.next();
103
104 if (comparator.compare(example, candidate) == 0) {
105 return true;
106 }
107 }
108
109 return false;
110 }
111
112 private Element _findObjectEqualTo(
113 Element example, List list, ElementComparator comparator) {
114
115 Iterator itr = list.iterator();
116
117 while (itr.hasNext()) {
118 Element candidate = (Element)itr.next();
119
120 if (comparator.compare(example, candidate) == 0) {
121 return candidate;
122 }
123 }
124
125 return example;
126 }
127
128 private void _mergeDuplicateElements(
129 Element el, ElementComparator comparator) {
130
131 if (el.elements().size() > 0) {
132 List children = el.elements();
133
134 List originals = new ArrayList();
135 List duplicates = new ArrayList();
136
137 for (int i = 0; i < children.size(); i++) {
138 Element child = (Element)children.get(i);
139
140 if (_containsObjectEqualTo(child, originals, comparator)) {
141 if (_descriptor.canJoinChildren(child)) {
142 Element first =
143 _findObjectEqualTo(child, originals, comparator);
144
145 Collection childrenToJoin = child.elements();
146
147 _addChildren(first, childrenToJoin);
148 }
149
150 duplicates.add(child);
151 }
152 else {
153 originals.add(child);
154 }
155 }
156
157 for (int i = 0; i < duplicates.size(); i++) {
158 Element duplicate = (Element)duplicates.get(i);
159
160 duplicate.detach();
161 }
162
163 Iterator itr = originals.iterator();
164
165 while (itr.hasNext()) {
166 Element child = (Element)itr.next();
167
168 _mergeDuplicateElements(child, comparator);
169 }
170 }
171 }
172
173 private void _orderChildren(
174 Element parent, String[] orderedChildrenNames) {
175
176 if (orderedChildrenNames == null) {
177 return;
178 }
179
180 List elements = new ArrayList();
181
182 for (int i = 0; i < orderedChildrenNames.length; i++) {
183 elements.addAll(parent.elements(orderedChildrenNames[i]));
184 }
185
186 for (int i = 0; i < elements.size(); i++) {
187 Element el = (Element)elements.get(i);
188 el.detach();
189 parent.add(el);
190 }
191 }
192
193 private XMLDescriptor _descriptor;
194
195 }