001
014
015 package com.liferay.util.xml;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
019 import com.liferay.portal.kernel.util.FileUtil;
020 import com.liferay.portal.kernel.util.StringUtil;
021 import com.liferay.portal.kernel.util.Validator;
022 import com.liferay.util.xml.descriptor.XMLDescriptor;
023
024 import java.io.File;
025 import java.io.IOException;
026
027 import org.dom4j.Document;
028 import org.dom4j.DocumentException;
029 import org.dom4j.io.OutputFormat;
030 import org.dom4j.io.SAXReader;
031 import org.dom4j.io.XMLWriter;
032
033
036 public class XMLMergerRunner {
037
038 public static void main(String[] args)
039 throws ClassNotFoundException, DocumentException,
040 IllegalAccessException, InstantiationException, IOException {
041
042 if ((args != null) && (args.length == 4)) {
043 XMLMergerRunner runner = new XMLMergerRunner(args[3]);
044
045 runner.mergeAndSave(args[0], args[1], args[2]);
046 }
047 else {
048 throw new IllegalArgumentException();
049 }
050 }
051
052 public XMLMergerRunner(String descriptorClassName) {
053 if (Validator.isNotNull(descriptorClassName)) {
054 _descriptorClassName = descriptorClassName;
055 }
056 }
057
058 public void mergeAndSave(
059 String masterFile, String slaveFile, String mergedFile)
060 throws ClassNotFoundException, DocumentException,
061 IllegalAccessException, InstantiationException, IOException {
062
063 mergeAndSave(
064 new File(masterFile), new File(slaveFile), new File(mergedFile));
065 }
066
067 public void mergeAndSave(File masterFile, File slaveFile, File mergedFile)
068 throws ClassNotFoundException, DocumentException,
069 IllegalAccessException, InstantiationException, IOException {
070
071 String xml1 = FileUtil.read(masterFile);
072 String xml2 = FileUtil.read(slaveFile);
073
074 String mergedXml = _merge(xml1, xml2);
075
076 FileUtil.write(mergedFile, mergedXml);
077 }
078
079 private String _documentToString(Document doc, String docType)
080 throws IOException {
081
082 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
083 new UnsyncByteArrayOutputStream();
084
085 OutputFormat format = OutputFormat.createPrettyPrint();
086
087 format.setIndent("\t");
088 format.setLineSeparator("\n");
089
090 XMLWriter writer = new XMLWriter(unsyncByteArrayOutputStream, format);
091
092 writer.write(doc);
093
094 String xml = unsyncByteArrayOutputStream.toString();
095
096 int pos = xml.indexOf("<?");
097
098 String header = xml.substring(pos, xml.indexOf("?>", pos) + 2);
099
100 xml = StringUtil.replace(xml, header, "");
101 xml = header + "\n" + docType + "\n" + xml;
102
103 return xml;
104 }
105
106 private String _merge(String masterXml, String slaveXml)
107 throws ClassNotFoundException, DocumentException,
108 IllegalAccessException, InstantiationException, IOException {
109
110 int pos = masterXml.indexOf("<!DOCTYPE");
111
112 String masterDoctype = "";
113
114 if (pos >= 0) {
115 masterDoctype = masterXml.substring(
116 pos, masterXml.indexOf(">", pos) + 1);
117 masterXml = StringUtil.replace(masterXml, masterDoctype, "");
118 }
119
120 pos = slaveXml.indexOf("<!DOCTYPE");
121
122 String slaveDoctype = "";
123
124 if (pos >= 0) {
125 slaveDoctype = slaveXml.substring(
126 pos, slaveXml.indexOf(">", pos) + 1);
127 slaveXml = StringUtil.replace(slaveXml, slaveDoctype, "");
128 }
129
130 String doctype = null;
131
132 if (Validator.isNotNull(masterDoctype)) {
133 doctype = masterDoctype;
134 }
135 else {
136 doctype = slaveDoctype;
137 }
138
139 SAXReader reader = new SAXReader();
140
141 Document masterDoc = reader.read(new UnsyncStringReader(masterXml));
142 Document slaveDoc = reader.read(new UnsyncStringReader(slaveXml));
143
144 XMLDescriptor descriptor = null;
145
146 if (_descriptorClassName.equals(_AUTO_DESCRIPTOR)) {
147 descriptor = XMLTypeDetector.determineType(doctype, masterDoc);
148 }
149 else {
150 descriptor = (XMLDescriptor)Class.forName(
151 _descriptorClassName).newInstance();
152 }
153
154 XMLMerger merger = new XMLMerger(descriptor);
155
156 Document mergedDoc = merger.merge(masterDoc, slaveDoc);
157
158 return _documentToString(mergedDoc, doctype);
159 }
160
161 private static final String _AUTO_DESCRIPTOR = "auto";
162
163 private String _descriptorClassName = _AUTO_DESCRIPTOR;
164
165 }