1
22
23 package com.liferay.util.xml;
24
25 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
26 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
27 import com.liferay.portal.kernel.util.FileUtil;
28 import com.liferay.portal.kernel.util.StringUtil;
29 import com.liferay.portal.kernel.util.Validator;
30 import com.liferay.util.xml.descriptor.XMLDescriptor;
31
32 import java.io.File;
33 import java.io.IOException;
34
35 import org.dom4j.Document;
36 import org.dom4j.DocumentException;
37 import org.dom4j.io.OutputFormat;
38 import org.dom4j.io.SAXReader;
39 import org.dom4j.io.XMLWriter;
40
41
46 public class XMLMergerRunner {
47
48 public static void main(String[] args)
49 throws ClassNotFoundException, DocumentException,
50 IllegalAccessException, InstantiationException, IOException {
51
52 if ((args != null) && (args.length == 4)) {
53 XMLMergerRunner runner = new XMLMergerRunner(args[3]);
54
55 runner.mergeAndSave(args[0], args[1], args[2]);
56 }
57 else {
58 throw new IllegalArgumentException();
59 }
60 }
61
62 public XMLMergerRunner(String descriptorClassName) {
63 if (Validator.isNotNull(descriptorClassName)) {
64 _descriptorClassName = descriptorClassName;
65 }
66 }
67
68 public void mergeAndSave(
69 String masterFile, String slaveFile, String mergedFile)
70 throws ClassNotFoundException, DocumentException,
71 IllegalAccessException, InstantiationException, IOException {
72
73 mergeAndSave(
74 new File(masterFile), new File(slaveFile), new File(mergedFile));
75 }
76
77 public void mergeAndSave(File masterFile, File slaveFile, File mergedFile)
78 throws ClassNotFoundException, DocumentException,
79 IllegalAccessException, InstantiationException, IOException {
80
81 String xml1 = FileUtil.read(masterFile);
82 String xml2 = FileUtil.read(slaveFile);
83
84 String mergedXml = _merge(xml1, xml2);
85
86 FileUtil.write(mergedFile, mergedXml);
87 }
88
89 private String _documentToString(Document doc, String docType)
90 throws IOException {
91
92 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
93 new UnsyncByteArrayOutputStream();
94
95 OutputFormat format = OutputFormat.createPrettyPrint();
96
97 format.setIndent("\t");
98 format.setLineSeparator("\n");
99
100 XMLWriter writer = new XMLWriter(unsyncByteArrayOutputStream, format);
101
102 writer.write(doc);
103
104 String xml = unsyncByteArrayOutputStream.toString();
105
106 int pos = xml.indexOf("<?");
107
108 String header = xml.substring(pos, xml.indexOf("?>", pos) + 2);
109
110 xml = StringUtil.replace(xml, header, "");
111 xml = header + "\n" + docType + "\n" + xml;
112
113 return xml;
114 }
115
116 private String _merge(String masterXml, String slaveXml)
117 throws ClassNotFoundException, DocumentException,
118 IllegalAccessException, InstantiationException, IOException {
119
120 int pos = masterXml.indexOf("<!DOCTYPE");
121
122 String masterDoctype = "";
123
124 if (pos >= 0) {
125 masterDoctype = masterXml.substring(
126 pos, masterXml.indexOf(">", pos) + 1);
127 masterXml = StringUtil.replace(masterXml, masterDoctype, "");
128 }
129
130 pos = slaveXml.indexOf("<!DOCTYPE");
131
132 String slaveDoctype = "";
133
134 if (pos >= 0) {
135 slaveDoctype = slaveXml.substring(
136 pos, slaveXml.indexOf(">", pos) + 1);
137 slaveXml = StringUtil.replace(slaveXml, slaveDoctype, "");
138 }
139
140 String doctype = null;
141
142 if (Validator.isNotNull(masterDoctype)) {
143 doctype = masterDoctype;
144 }
145 else {
146 doctype = slaveDoctype;
147 }
148
149 SAXReader reader = new SAXReader();
150
151 Document masterDoc = reader.read(new UnsyncStringReader(masterXml));
152 Document slaveDoc = reader.read(new UnsyncStringReader(slaveXml));
153
154 XMLDescriptor descriptor = null;
155
156 if (_descriptorClassName.equals(_AUTO_DESCRIPTOR)) {
157 descriptor = XMLTypeDetector.determineType(doctype, masterDoc);
158 }
159 else {
160 descriptor = (XMLDescriptor)Class.forName(
161 _descriptorClassName).newInstance();
162 }
163
164 XMLMerger merger = new XMLMerger(descriptor);
165
166 Document mergedDoc = merger.merge(masterDoc, slaveDoc);
167
168 return _documentToString(mergedDoc, doctype);
169 }
170
171 private static final String _AUTO_DESCRIPTOR = "auto";
172
173 private String _descriptorClassName = _AUTO_DESCRIPTOR;
174
175 }