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 XMLMergerRunner(String descriptorClassName) {
039 if (Validator.isNotNull(descriptorClassName)) {
040 _descriptorClassName = descriptorClassName;
041 }
042 else {
043 _descriptorClassName = _AUTO_DESCRIPTOR;
044 }
045 }
046
047 public void mergeAndSave(File masterFile, File slaveFile, File mergedFile)
048 throws ClassNotFoundException, DocumentException,
049 IllegalAccessException, InstantiationException, IOException {
050
051 String xml1 = FileUtil.read(masterFile);
052 String xml2 = FileUtil.read(slaveFile);
053
054 String mergedXml = _merge(xml1, xml2);
055
056 FileUtil.write(mergedFile, mergedXml);
057 }
058
059 public void mergeAndSave(
060 String masterFile, String slaveFile, String mergedFile)
061 throws ClassNotFoundException, DocumentException,
062 IllegalAccessException, InstantiationException, IOException {
063
064 mergeAndSave(
065 new File(masterFile), new File(slaveFile), new File(mergedFile));
066 }
067
068 private String _documentToString(Document doc, String docType)
069 throws IOException {
070
071 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
072 new UnsyncByteArrayOutputStream();
073
074 OutputFormat format = OutputFormat.createPrettyPrint();
075
076 format.setIndent("\t");
077 format.setLineSeparator("\n");
078
079 XMLWriter writer = new XMLWriter(unsyncByteArrayOutputStream, format);
080
081 writer.write(doc);
082
083 String xml = unsyncByteArrayOutputStream.toString();
084
085 int pos = xml.indexOf("<?");
086
087 String header = xml.substring(pos, xml.indexOf("?>", pos) + 2);
088
089 xml = StringUtil.replace(xml, header, "");
090 xml = header + "\n" + docType + "\n" + xml;
091
092 return xml;
093 }
094
095 private String _merge(String masterXml, String slaveXml)
096 throws ClassNotFoundException, DocumentException,
097 IllegalAccessException, InstantiationException, IOException {
098
099 int pos = masterXml.indexOf("<!DOCTYPE");
100
101 String masterDoctype = "";
102
103 if (pos >= 0) {
104 masterDoctype = masterXml.substring(
105 pos, masterXml.indexOf(">", pos) + 1);
106 masterXml = StringUtil.replace(masterXml, masterDoctype, "");
107 }
108
109 pos = slaveXml.indexOf("<!DOCTYPE");
110
111 String slaveDoctype = "";
112
113 if (pos >= 0) {
114 slaveDoctype = slaveXml.substring(
115 pos, slaveXml.indexOf(">", pos) + 1);
116 slaveXml = StringUtil.replace(slaveXml, slaveDoctype, "");
117 }
118
119 String doctype = null;
120
121 if (Validator.isNotNull(masterDoctype)) {
122 doctype = masterDoctype;
123 }
124 else {
125 doctype = slaveDoctype;
126 }
127
128 SAXReader reader = new SAXReader();
129
130 Document masterDoc = reader.read(new UnsyncStringReader(masterXml));
131 Document slaveDoc = reader.read(new UnsyncStringReader(slaveXml));
132
133 XMLDescriptor descriptor = null;
134
135 if (_descriptorClassName.equals(_AUTO_DESCRIPTOR)) {
136 descriptor = XMLTypeDetector.determineType(doctype, masterDoc);
137 }
138 else {
139 Class<?> clazz = Class.forName(_descriptorClassName);
140
141 descriptor = (XMLDescriptor)clazz.newInstance();
142 }
143
144 XMLMerger merger = new XMLMerger(descriptor);
145
146 Document mergedDoc = merger.merge(masterDoc, slaveDoc);
147
148 return _documentToString(mergedDoc, doctype);
149 }
150
151 private static final String _AUTO_DESCRIPTOR = "auto";
152
153 private final String _descriptorClassName;
154
155 }