1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ch.elca.el4j.services.xmlmerge.merge;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23
24 import org.jdom.DocType;
25 import org.jdom.Document;
26 import org.jdom.Element;
27 import org.jdom.JDOMException;
28 import org.jdom.input.DOMBuilder;
29 import org.jdom.input.SAXBuilder;
30 import org.jdom.output.DOMOutputter;
31 import org.jdom.output.Format;
32 import org.jdom.output.XMLOutputter;
33 import org.xml.sax.EntityResolver;
34
35 import ch.elca.el4j.services.xmlmerge.AbstractXmlMergeException;
36 import ch.elca.el4j.services.xmlmerge.DocumentException;
37 import ch.elca.el4j.services.xmlmerge.Mapper;
38 import ch.elca.el4j.services.xmlmerge.Matcher;
39 import ch.elca.el4j.services.xmlmerge.MergeAction;
40 import ch.elca.el4j.services.xmlmerge.ParseException;
41 import ch.elca.el4j.services.xmlmerge.XmlMerge;
42 import ch.elca.el4j.services.xmlmerge.XmlMergeContext;
43 import ch.elca.el4j.services.xmlmerge.action.OrderedMergeAction;
44 import ch.elca.el4j.services.xmlmerge.factory.StaticOperationFactory;
45 import ch.elca.el4j.services.xmlmerge.mapper.IdentityMapper;
46 import ch.elca.el4j.services.xmlmerge.matcher.TagMatcher;
47
48
49
50
51
52
53
54
55
56
57
58
59 public class DefaultXmlMerge implements XmlMerge {
60
61
62
63
64 private MergeAction m_rootMergeAction = new OrderedMergeAction();
65
66
67
68
69 private Matcher m_rootMatcher = new TagMatcher();
70
71
72
73
74
75 public DefaultXmlMerge() {
76 m_rootMergeAction.setActionFactory(new StaticOperationFactory(
77 new OrderedMergeAction()));
78 m_rootMergeAction.setMapperFactory(new StaticOperationFactory(
79 new IdentityMapper()));
80 m_rootMergeAction.setMatcherFactory(new StaticOperationFactory(
81 new TagMatcher()));
82 }
83
84
85
86
87 public void setRootMapper(Mapper rootMapper) { }
88
89
90
91
92 public void setRootMergeAction(MergeAction rootMergeAction) {
93 this.m_rootMergeAction = rootMergeAction;
94 }
95
96
97
98
99 public String merge(String[] sources) throws AbstractXmlMergeException {
100
101 InputStream[] inputStreams = new InputStream[sources.length];
102
103 for (int i = 0; i < sources.length; i++) {
104 inputStreams[i] = new ByteArrayInputStream(sources[i].getBytes());
105 }
106
107 InputStream merged = merge(inputStreams);
108
109 ByteArrayOutputStream result = new ByteArrayOutputStream();
110
111 try {
112 byte[] buffer = new byte[1024];
113 int len;
114 while ((len = merged.read(buffer)) != -1) {
115 result.write(buffer, 0, len);
116 }
117 } catch (IOException ioe) {
118
119 throw new RuntimeException(ioe);
120 }
121
122 return result.toString();
123 }
124
125
126
127
128 public org.w3c.dom.Document merge(org.w3c.dom.Document[] sources)
129 throws AbstractXmlMergeException {
130 DOMBuilder domb = new DOMBuilder();
131
132
133 Document[] docs = new Document[sources.length];
134
135 for (int i = 0; i < sources.length; i++) {
136
137 docs[i] = domb.build(sources[i]);
138 }
139
140 Document result = doMerge(docs);
141
142 DOMOutputter outputter = new DOMOutputter();
143
144 try {
145 return outputter.output(result);
146 } catch (JDOMException e) {
147 throw new DocumentException(result, e);
148 }
149 }
150
151
152
153
154 public InputStream merge(InputStream[] sources)
155 throws AbstractXmlMergeException {
156 SAXBuilder sxb = new SAXBuilder();
157
158 EntityResolver entityResolver = XmlMergeContext.getEntityResolver();
159 if (entityResolver != null) {
160 sxb.setEntityResolver(entityResolver);
161 }
162
163
164 Document[] docs = new Document[sources.length];
165
166 for (int i = 0; i < sources.length; i++) {
167 try {
168
169 docs[i] = sxb.build(sources[i]);
170 } catch (JDOMException e) {
171 throw new ParseException(e);
172 } catch (IOException ioe) {
173 ioe.printStackTrace();
174 throw new ParseException(ioe);
175 }
176 }
177
178 Document result = doMerge(docs);
179
180 Format prettyFormatter = Format.getPrettyFormat();
181
182
183 prettyFormatter.setLineSeparator(System.getProperty("line.separator"));
184 XMLOutputter sortie = new XMLOutputter(prettyFormatter);
185
186 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
187
188 try {
189 sortie.output(result, buffer);
190 } catch (IOException ex) {
191 throw new DocumentException(result, ex);
192 }
193
194 return new ByteArrayInputStream(buffer.toByteArray());
195 }
196
197
198
199
200
201
202
203
204
205
206 private Document doMerge(Document[] docs) throws AbstractXmlMergeException {
207 Document temporary = docs[0];
208
209 for (int i = 1; i < docs.length; i++) {
210
211 if (!m_rootMatcher.matches(temporary.getRootElement(), docs[i]
212 .getRootElement())) {
213 throw new IllegalArgumentException(
214 "Root elements do not match.");
215 }
216
217 Document output = new Document();
218 if (docs[0].getDocType() != null) {
219 output.setDocType((DocType) docs[0].getDocType().clone());
220 }
221 output.setRootElement(new Element("root"));
222
223 m_rootMergeAction.perform(temporary.getRootElement(), docs[i]
224 .getRootElement(), output.getRootElement());
225
226 Element root = (Element) output.getRootElement().getChildren().get(
227 0);
228 root.detach();
229
230 temporary.setRootElement(root);
231 }
232
233 return temporary;
234 }
235
236 }
237
238