Subversion Repositories XServices

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
114 brianR 1
/*
2
 *   Copyright 2013 Brian Rosenberger (Brutex Network)
3
 *
4
 *   Licensed under the Apache License, Version 2.0 (the "License");
5
 *   you may not use this file except in compliance with the License.
6
 *   You may obtain a copy of the License at
7
 *
8
 *       http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *   Unless required by applicable law or agreed to in writing, software
11
 *   distributed under the License is distributed on an "AS IS" BASIS,
12
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *   See the License for the specific language governing permissions and
14
 *   limitations under the License.
15
 */
16
 
17
package net.brutex.xservices.ws.impl;
18
 
19
import java.io.ByteArrayInputStream;
20
import java.io.IOException;
21
import java.io.InputStream;
22
import java.io.StringReader;
23
import java.io.StringWriter;
24
import java.util.Iterator;
25
import java.util.List;
26
import java.util.StringTokenizer;
27
 
28
import javax.jws.WebService;
29
import javax.xml.stream.XMLOutputFactory;
30
import javax.xml.stream.XMLStreamException;
31
import javax.xml.stream.XMLStreamReader;
32
import javax.xml.stream.XMLStreamWriter;
33
import net.brutex.xservices.types.NamespaceListType;
34
import net.brutex.xservices.types.NamespaceType;
35
import net.brutex.xservices.types.ant.FileResource;
36
import net.brutex.xservices.ws.XServicesFault;
37
import net.brutex.xservices.ws.XmlService;
38
import org.apache.axiom.om.OMAbstractFactory;
39
import org.apache.axiom.om.OMCloneOptions;
40
import org.apache.axiom.om.OMContainer;
41
import org.apache.axiom.om.OMDocument;
42
import org.apache.axiom.om.OMElement;
43
import org.apache.axiom.om.OMNode;
44
import org.apache.axiom.om.OMText;
45
import org.apache.axiom.om.OMXMLBuilderFactory;
46
import org.apache.axiom.om.xpath.AXIOMXPath;
47
import org.apache.log4j.Logger;
48
import org.jaxen.JaxenException;
49
import org.jaxen.SimpleNamespaceContext;
50
 
51
/**
52
 * @author Brian Rosenberger, bru(at)brutex.de
53
 *
54
 */
55
@WebService(targetNamespace = "http://ws.xservices.brutex.net", endpointInterface = "net.brutex.xservices.ws.XmlService", serviceName = "XmlService")
56
public class XmlServiceImpl implements XmlService {
57
	final Logger logger = Logger.getLogger(XmlServiceImpl.class);
58
 
59
	public String insertNodesFromFile(FileResource res, NamespaceListType nsList, String xpath, String xmlFragment) throws XServicesFault {
60
		try {
61
			AXIOMXPath axp = new AXIOMXPath(xpath);
62
			InputStream is = res.getAntResource(null).getInputStream();
63
			OMDocument sourcedoc = OMXMLBuilderFactory.createOMBuilder(is)
64
					.getDocument();
65
			OMDocument fragdoc = null;
66
			if ((xmlFragment != null) && (new String(xmlFragment).length() > 0)) {
67
				fragdoc = OMXMLBuilderFactory.createOMBuilder(
68
						new StringReader("<XS>" + xmlFragment + "</XS>"))
69
						.getDocument();
70
			} else {
71
				throw new XServicesFault("No xmldata to insert.");
72
			}
73
 
74
			// Initialize XPath context
75
			SimpleNamespaceContext context = new SimpleNamespaceContext();
76
			for (NamespaceType ns : nsList.getNamespaces()) {
77
				context.addNamespace(ns.getPrefix(), ns.getUri().toString());
78
				this.logger.debug(Messages.getString("XmlService.0")
79
						+ ns.getPrefix() + "=\"" + ns.getUri().toString()
80
						+ "\"'");
81
			}
82
			axp.setNamespaceContext(context);
83
			axp.addNamespaces(fragdoc.getOMDocumentElement());
84
 
85
			OMDocument document = insertNodes(sourcedoc, axp, fragdoc);
86
 
87
			StringWriter sw = new StringWriter();
88
			XMLOutputFactory xof = XMLOutputFactory.newInstance();
89
			XMLStreamWriter writer = xof.createXMLStreamWriter(sw);
90
			document.serialize(writer);
91
 
92
			this.logger.trace(sw.getBuffer().toString());
93
			return sw.getBuffer().toString();
94
		} catch (JaxenException e) {
95
			e.printStackTrace();
96
			throw new XServicesFault(e);
97
		} catch (IOException e) {
98
			e.printStackTrace();
99
			throw new XServicesFault(e);
100
		} catch (XMLStreamException e) {
101
			e.printStackTrace();
102
			throw new XServicesFault(e);
103
		}
104
	}
105
 
106
	public String replaceNodesFromFile(FileResource res, NamespaceListType nsList, String xpath, String replace) throws XServicesFault {
107
		try {
108
			AXIOMXPath axp = new AXIOMXPath(xpath);
109
 
110
			InputStream is = res.getAntResource(null).getInputStream();
111
 
112
			XMLStreamReader reader = OMXMLBuilderFactory.createOMBuilder(is)
113
					.getDocument().getXMLStreamReader(false);
114
			StringWriter sw = new StringWriter();
115
			OMAbstractFactory.getOMFactory();
116
 
117
			while (reader.hasNext()) {
118
				if (reader.getEventType() == 1) {
119
					OMElement element = OMXMLBuilderFactory
120
							.createStAXOMBuilder(reader).getDocumentElement();
121
					element.build();
122
 
123
					SimpleNamespaceContext context = new SimpleNamespaceContext();
124
					for (NamespaceType ns : nsList.getNamespaces()) {
125
						context.addNamespace(ns.getPrefix(), ns.getUri()
126
								.toString());
127
						this.logger.debug(Messages.getString(
128
								"XmlService.adding_namespace",
129
								new Object[] { ns.getPrefix(),
130
										ns.getUri().toString() }));
131
					}
132
					axp.setNamespaceContext(context);
133
					axp.addNamespaces(element);
134
 
135
					OMDocument xfrag = OMXMLBuilderFactory.createOMBuilder(
136
							new StringReader("<XS>" + replace + "</XS>"))
137
							.getDocument();
138
					xfrag.build();
139
 
140
					List list = axp.selectNodes(element);
141
					for (Iterator localIterator2 = list.iterator(); localIterator2
142
							.hasNext();) {
143
						Object o = localIterator2.next();
144
						if (!(o instanceof OMNode))
145
							throw new XServicesFault(
146
									"You must match a node to be replaced, but you matched something differen (attribute, etc.");
147
						OMNode node = (OMNode) o;
148
 
149
						Iterator<?> children = xfrag.getOMDocumentElement()
150
								.getChildren();
151
						while (children.hasNext()) {
152
							OMNode container = (OMNode) children.next();
153
							node.insertSiblingAfter((OMNode) container
154
									.clone(new OMCloneOptions()));
155
						}
156
						node.detach();
157
 
158
						// node.insertSiblingAfter(AXIOMUtil.stringToOM(replace));
159
 
160
					}
161
					XMLOutputFactory xof = XMLOutputFactory.newInstance();
162
					XMLStreamWriter writer = xof.createXMLStreamWriter(sw);
163
					element.serialize(writer);
164
					sw.flush();
165
				} else {
166
					reader.next();
167
				}
168
			}
169
			this.logger.trace(sw.getBuffer().toString());
170
			return sw.getBuffer().toString();
171
		} catch (JaxenException e) {
172
			e.printStackTrace();
173
			throw new XServicesFault(e);
174
		} catch (IOException e) {
175
			e.printStackTrace();
176
			throw new XServicesFault(e);
177
		} catch (XMLStreamException e) {
178
			e.printStackTrace();
179
			throw new XServicesFault(e);
180
		}
181
	}
182
 
183
	public String replaceNodes(String source, NamespaceListType nsList, String xpath, String xmlFragment) throws XServicesFault {
184
		try {
185
			AXIOMXPath axp = new AXIOMXPath(xpath);
186
			InputStream is = new ByteArrayInputStream(source.getBytes());
187
			OMDocument sourcedoc = OMXMLBuilderFactory.createOMBuilder(is)
188
					.getDocument();
189
			OMDocument fragdoc = null;
190
			if ((xmlFragment != null) && (new String(xmlFragment).length() > 0)) {
191
				fragdoc = OMXMLBuilderFactory.createOMBuilder(
192
						new StringReader("<XS>" + xmlFragment + "</XS>"))
193
						.getDocument();
194
			} else {
195
				throw new XServicesFault("No xmldata to insert.");
196
			}
197
 
198
			// Initialize XPath context
199
			SimpleNamespaceContext context = new SimpleNamespaceContext();
200
			for (NamespaceType ns : nsList.getNamespaces()) {
201
				context.addNamespace(ns.getPrefix(), ns.getUri().toString());
202
				this.logger.debug(Messages.getString("XmlService.0")
203
						+ ns.getPrefix() + "=\"" + ns.getUri().toString()
204
						+ "\"'");
205
			}
206
			axp.setNamespaceContext(context);
207
			axp.addNamespaces(fragdoc.getOMDocumentElement());
208
 
209
			OMDocument document = replaceNodes(sourcedoc, axp, fragdoc);
210
 
211
			StringWriter sw = new StringWriter();
212
			XMLOutputFactory xof = XMLOutputFactory.newInstance();
213
			XMLStreamWriter writer = xof.createXMLStreamWriter(sw);
214
			document.serialize(writer);
215
 
216
			this.logger.trace(sw.getBuffer().toString());
217
			return sw.getBuffer().toString();
218
		} catch (JaxenException e) {
219
			e.printStackTrace();
220
			throw new XServicesFault(e);
221
		} catch (XMLStreamException e) {
222
			e.printStackTrace();
223
			throw new XServicesFault(e);
224
		}
225
	}
226
 
227
	public String insertNodes(String source, NamespaceListType nsList, String xpath, String xmlFragment) throws XServicesFault {
228
		try {
229
			AXIOMXPath axp = new AXIOMXPath(xpath);
230
			InputStream is = new ByteArrayInputStream(source.getBytes());
231
			OMDocument sourcedoc = OMXMLBuilderFactory.createOMBuilder(is)
232
					.getDocument();
233
			OMDocument fragdoc = null;
234
			if ((xmlFragment != null) && (new String(xmlFragment).length() > 0)) {
235
				fragdoc = OMXMLBuilderFactory.createOMBuilder(
236
						new StringReader("<XS>" + xmlFragment + "</XS>"))
237
						.getDocument();
238
			} else {
239
				throw new XServicesFault("No xmldata to insert.");
240
			}
241
 
242
			// Initialize XPath context
243
			SimpleNamespaceContext context = new SimpleNamespaceContext();
244
			for (NamespaceType ns : nsList.getNamespaces()) {
245
				context.addNamespace(ns.getPrefix(), ns.getUri().toString());
246
				this.logger.debug(Messages.getString("XmlService.0")
247
						+ ns.getPrefix() + "=\"" + ns.getUri().toString()
248
						+ "\"'");
249
			}
250
			axp.setNamespaceContext(context);
251
			axp.addNamespaces(fragdoc.getOMDocumentElement());
252
 
253
			OMDocument document = insertNodes(sourcedoc, axp, fragdoc);
254
 
255
			StringWriter sw = new StringWriter();
256
			XMLOutputFactory xof = XMLOutputFactory.newInstance();
257
			XMLStreamWriter writer = xof.createXMLStreamWriter(sw);
258
			document.serialize(writer);
259
 
260
			this.logger.trace(sw.getBuffer().toString());
261
			return sw.getBuffer().toString();
262
		} catch (JaxenException e) {
263
			e.printStackTrace();
264
			throw new XServicesFault(e);
265
		} catch (XMLStreamException e) {
266
			e.printStackTrace();
267
			throw new XServicesFault(e);
268
		}
269
	}
270
 
271
	public String wrapInCDATA(String data) throws XServicesFault {
272
		String result ="";
273
		String[] tokens = data.split("\\]\\]>", -1);
274
 
275
		for(int i=0; i<tokens.length; i++) {
276
			result +=  tokens[i];
277
			if (i+1 < tokens.length ) result += "]]]]><![CDATA[>";
278
		}
279
 
280
		result = "<![CDATA[" + result + "]]>";
281
		return result;
282
	}
283
	private OMDocument insertNodes(OMDocument xmldocument, AXIOMXPath axp,OMDocument xmlfragment) throws XServicesFault {
284
		List<?> olist = null;
285
		try {
286
			olist = axp.selectNodes(xmldocument.getOMDocumentElement());
287
			this.logger.debug("XPath '" + axp.toString() + "' has "
288
					+ olist.size() + " matches.");
289
			this.logger.trace("XPath root expression is: '" + axp.debug()
290
					+ "'.");
291
		} catch (JaxenException e) {
292
			throw new XServicesFault(e.getMessage(), e);
293
		}
294
		if (olist.size() == 0)
295
			throw new XServicesFault(Messages.getString("XmlService.no_match",
296
					new Object[] { axp.toString() }));
297
 
298
		// Prepare children to insert
299
		xmlfragment.build();
300
 
301
		// Determine what has been matched
302
		OMContainer match = null;
303
		for (Object o : olist) {
304
			Iterator<?> children = xmlfragment.getOMDocumentElement()
305
					.getChildren();
306
			if ((o instanceof OMNode)) {
307
				OMNode node = (OMNode) o;
308
				switch (node.getType()) {
309
				case OMNode.ELEMENT_NODE:
310
					if ((o instanceof OMElement))
311
						match = (OMElement) o;
312
					if ((o instanceof OMDocument))
313
						match = ((OMDocument) o).getOMDocumentElement();
314
					this.logger.debug(Messages.getString("XmlService.8"));
315
					break;
316
				case OMNode.TEXT_NODE:
317
					match = ((OMText) o).getParent();
318
					this.logger.debug(Messages.getString("XmlService.9"));
319
					break;
320
				case OMNode.COMMENT_NODE:
321
					// match = node.getParent();
322
					match = (OMContainer) node;
323
					this.logger.debug(Messages.getString("XmlService.10"));
324
					break;
325
				default:
326
					this.logger.error("XPath matched "
327
							+ o.getClass().getCanonicalName() + " Node Type:"
328
							+ node.getType());
329
					this.logger.error(Messages.getString("XmlService.11"));
330
					throw new XServicesFault(
331
							Messages.getString("XmlService.12"));
332
				}
333
			} else {
334
				this.logger.error("XPath matched "
335
						+ o.getClass().getCanonicalName());
336
				this.logger.error(Messages.getString("XmlService.11"));
337
				throw new XServicesFault(Messages.getString("XmlService.12"));
338
			}
339
 
340
			while (children.hasNext()) {
341
				OMNode container = (OMNode) children.next();
342
				match.addChild((OMNode) container.clone(new OMCloneOptions()));
343
			}
344
		}
345
 
346
		xmldocument.build();
347
		return xmldocument;
348
	}
349
 
350
 
351
	private OMDocument replaceNodes(OMDocument xmldocument, AXIOMXPath axp, OMDocument xmlfragment) throws XServicesFault {
352
		List<?> olist = null;
353
		try {
354
			olist = axp.selectNodes(xmldocument.getOMDocumentElement());
355
			this.logger.debug("XPath '" + axp.toString() + "' has "
356
					+ olist.size() + " matches.");
357
			this.logger.trace("XPath root expression is: '" + axp.debug()
358
					+ "'.");
359
		} catch (JaxenException e) {
360
			throw new XServicesFault(e.getMessage(), e);
361
		}
362
		if (olist.size() == 0)
363
			throw new XServicesFault(Messages.getString("XmlService.no_match",
364
					new Object[] { axp.toString() }));
365
 
366
		// Prepare children to insert
367
		xmlfragment.build();
368
 
369
		// Determine what has been matched
370
		OMNode match = null;
371
		for (Object o : olist) {
372
			Iterator<?> children = xmlfragment.getOMDocumentElement()
373
					.getChildren();
374
			if ((o instanceof OMNode)) {
375
				OMNode node = (OMNode) o;
376
				switch (node.getType()) {
377
				case OMNode.ELEMENT_NODE:
378
					if ((o instanceof OMElement))
379
						match = (OMElement) o;
380
					if ((o instanceof OMDocument))
381
						match = ((OMDocument) o).getOMDocumentElement();
382
					this.logger.debug(Messages.getString("XmlService.8"));
383
					break;
384
				default:
385
					this.logger.error("XPath matched "
386
							+ o.getClass().getCanonicalName() + " Node Type:"
387
							+ node.getType());
388
					this.logger.error(Messages.getString("XmlService.11"));
389
					throw new XServicesFault(
390
							Messages.getString("XmlService.12"));
391
				}
392
			} else {
393
				this.logger.error("XPath matched "
394
						+ o.getClass().getCanonicalName());
395
				this.logger.error(Messages.getString("XmlService.11"));
396
				throw new XServicesFault(Messages.getString("XmlService.12"));
397
			}
398
 
399
			while (children.hasNext()) {
400
				OMNode container = (OMNode) children.next();
401
				match.insertSiblingAfter((OMNode) container.clone(new OMCloneOptions()));
402
			}
403
			match.detach();
404
		}
405
		xmldocument.build();
406
		return xmldocument;
407
	}
408
}