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