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