Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed
/*
* Copyright 2013 Brian Rosenberger (Brutex Network)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.brutex.xservices.ws.impl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import javax.jws.WebService;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import net.brutex.xservices.types.NamespaceListType;
import net.brutex.xservices.types.NamespaceType;
import net.brutex.xservices.types.ant.FileResource;
import net.brutex.xservices.ws.XServicesFault;
import net.brutex.xservices.ws.XmlService;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMCloneOptions;
import org.apache.axiom.om.OMContainer;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMText;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.log4j.Logger;
import org.jaxen.JaxenException;
import org.jaxen.SimpleNamespaceContext;
/**
* @author Brian Rosenberger, bru(at)brutex.de
*
*/
@WebService(targetNamespace = "http://ws.xservices.brutex.net", endpointInterface = "net.brutex.xservices.ws.XmlService", serviceName = "XmlService")
public class XmlServiceImpl implements XmlService {
final Logger logger = Logger.getLogger(XmlServiceImpl.class);
public String insertNodesFromFile(FileResource res, NamespaceListType nsList, String xpath, String xmlFragment) throws XServicesFault {
try {
AXIOMXPath axp = new AXIOMXPath(xpath);
InputStream is = res.getAntResource(null).getInputStream();
OMDocument sourcedoc = OMXMLBuilderFactory.createOMBuilder(is)
.getDocument();
OMDocument fragdoc = null;
if ((xmlFragment != null) && (new String(xmlFragment).length() > 0)) {
fragdoc = OMXMLBuilderFactory.createOMBuilder(
new StringReader("<XS>" + xmlFragment + "</XS>"))
.getDocument();
} else {
throw new XServicesFault("No xmldata to insert.");
}
// Initialize XPath context
SimpleNamespaceContext context = new SimpleNamespaceContext();
for (NamespaceType ns : nsList.getNamespaces()) {
context.addNamespace(ns.getPrefix(), ns.getUri().toString());
this.logger.debug(Messages.getString("XmlService.0")
+ ns.getPrefix() + "=\"" + ns.getUri().toString()
+ "\"'");
}
axp.setNamespaceContext(context);
axp.addNamespaces(fragdoc.getOMDocumentElement());
OMDocument document = insertNodes(sourcedoc, axp, fragdoc);
StringWriter sw = new StringWriter();
XMLOutputFactory xof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = xof.createXMLStreamWriter(sw);
document.serialize(writer);
this.logger.trace(sw.getBuffer().toString());
return sw.getBuffer().toString();
} catch (JaxenException e) {
e.printStackTrace();
throw new XServicesFault(e);
} catch (IOException e) {
e.printStackTrace();
throw new XServicesFault(e);
} catch (XMLStreamException e) {
e.printStackTrace();
throw new XServicesFault(e);
}
}
public String replaceNodesFromFile(FileResource res, NamespaceListType nsList, String xpath, String replace) throws XServicesFault {
try {
AXIOMXPath axp = new AXIOMXPath(xpath);
InputStream is = res.getAntResource(null).getInputStream();
XMLStreamReader reader = OMXMLBuilderFactory.createOMBuilder(is)
.getDocument().getXMLStreamReader(false);
StringWriter sw = new StringWriter();
OMAbstractFactory.getOMFactory();
while (reader.hasNext()) {
if (reader.getEventType() == 1) {
OMElement element = OMXMLBuilderFactory
.createStAXOMBuilder(reader).getDocumentElement();
element.build();
SimpleNamespaceContext context = new SimpleNamespaceContext();
for (NamespaceType ns : nsList.getNamespaces()) {
context.addNamespace(ns.getPrefix(), ns.getUri()
.toString());
this.logger.debug(Messages.getString(
"XmlService.adding_namespace",
new Object[] { ns.getPrefix(),
ns.getUri().toString() }));
}
axp.setNamespaceContext(context);
axp.addNamespaces(element);
OMDocument xfrag = OMXMLBuilderFactory.createOMBuilder(
new StringReader("<XS>" + replace + "</XS>"))
.getDocument();
xfrag.build();
List list = axp.selectNodes(element);
for (Iterator localIterator2 = list.iterator(); localIterator2
.hasNext();) {
Object o = localIterator2.next();
if (!(o instanceof OMNode))
throw new XServicesFault(
"You must match a node to be replaced, but you matched something differen (attribute, etc.");
OMNode node = (OMNode) o;
Iterator<?> children = xfrag.getOMDocumentElement()
.getChildren();
while (children.hasNext()) {
OMNode container = (OMNode) children.next();
node.insertSiblingAfter((OMNode) container
.clone(new OMCloneOptions()));
}
node.detach();
// node.insertSiblingAfter(AXIOMUtil.stringToOM(replace));
}
XMLOutputFactory xof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = xof.createXMLStreamWriter(sw);
element.serialize(writer);
sw.flush();
} else {
reader.next();
}
}
this.logger.trace(sw.getBuffer().toString());
return sw.getBuffer().toString();
} catch (JaxenException e) {
e.printStackTrace();
throw new XServicesFault(e);
} catch (IOException e) {
e.printStackTrace();
throw new XServicesFault(e);
} catch (XMLStreamException e) {
e.printStackTrace();
throw new XServicesFault(e);
}
}
public String replaceNodes(String source, NamespaceListType nsList, String xpath, String xmlFragment) throws XServicesFault {
try {
AXIOMXPath axp = new AXIOMXPath(xpath);
InputStream is = new ByteArrayInputStream(source.getBytes());
OMDocument sourcedoc = OMXMLBuilderFactory.createOMBuilder(is)
.getDocument();
OMDocument fragdoc = null;
if ((xmlFragment != null) && (new String(xmlFragment).length() > 0)) {
fragdoc = OMXMLBuilderFactory.createOMBuilder(
new StringReader("<XS>" + xmlFragment + "</XS>"))
.getDocument();
} else {
throw new XServicesFault("No xmldata to insert.");
}
// Initialize XPath context
SimpleNamespaceContext context = new SimpleNamespaceContext();
for (NamespaceType ns : nsList.getNamespaces()) {
context.addNamespace(ns.getPrefix(), ns.getUri().toString());
this.logger.debug(Messages.getString("XmlService.0")
+ ns.getPrefix() + "=\"" + ns.getUri().toString()
+ "\"'");
}
axp.setNamespaceContext(context);
axp.addNamespaces(fragdoc.getOMDocumentElement());
OMDocument document = replaceNodes(sourcedoc, axp, fragdoc);
StringWriter sw = new StringWriter();
XMLOutputFactory xof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = xof.createXMLStreamWriter(sw);
document.serialize(writer);
this.logger.trace(sw.getBuffer().toString());
return sw.getBuffer().toString();
} catch (JaxenException e) {
e.printStackTrace();
throw new XServicesFault(e);
} catch (XMLStreamException e) {
e.printStackTrace();
throw new XServicesFault(e);
}
}
public String insertNodes(String source, NamespaceListType nsList, String xpath, String xmlFragment) throws XServicesFault {
try {
AXIOMXPath axp = new AXIOMXPath(xpath);
InputStream is = new ByteArrayInputStream(source.getBytes());
OMDocument sourcedoc = OMXMLBuilderFactory.createOMBuilder(is)
.getDocument();
OMDocument fragdoc = null;
if ((xmlFragment != null) && (new String(xmlFragment).length() > 0)) {
fragdoc = OMXMLBuilderFactory.createOMBuilder(
new StringReader("<XS>" + xmlFragment + "</XS>"))
.getDocument();
} else {
throw new XServicesFault("No xmldata to insert.");
}
// Initialize XPath context
SimpleNamespaceContext context = new SimpleNamespaceContext();
for (NamespaceType ns : nsList.getNamespaces()) {
context.addNamespace(ns.getPrefix(), ns.getUri().toString());
this.logger.debug(Messages.getString("XmlService.0")
+ ns.getPrefix() + "=\"" + ns.getUri().toString()
+ "\"'");
}
axp.setNamespaceContext(context);
axp.addNamespaces(fragdoc.getOMDocumentElement());
OMDocument document = insertNodes(sourcedoc, axp, fragdoc);
StringWriter sw = new StringWriter();
XMLOutputFactory xof = XMLOutputFactory.newInstance();
XMLStreamWriter writer = xof.createXMLStreamWriter(sw);
document.serialize(writer);
this.logger.trace(sw.getBuffer().toString());
return sw.getBuffer().toString();
} catch (JaxenException e) {
e.printStackTrace();
throw new XServicesFault(e);
} catch (XMLStreamException e) {
e.printStackTrace();
throw new XServicesFault(e);
}
}
public String wrapInCDATA(String data) throws XServicesFault {
String result ="";
String[] tokens = data.split("\\]\\]>", -1);
for(int i=0; i<tokens.length; i++) {
result += tokens[i];
if (i+1 < tokens.length ) result += "]]]]><![CDATA[>";
}
result = "<![CDATA[" + result + "]]>";
return result;
}
private OMDocument insertNodes(OMDocument xmldocument, AXIOMXPath axp,OMDocument xmlfragment) throws XServicesFault {
List<?> olist = null;
try {
olist = axp.selectNodes(xmldocument.getOMDocumentElement());
this.logger.debug("XPath '" + axp.toString() + "' has "
+ olist.size() + " matches.");
this.logger.trace("XPath root expression is: '" + axp.debug()
+ "'.");
} catch (JaxenException e) {
throw new XServicesFault(e.getMessage(), e);
}
if (olist.size() == 0)
throw new XServicesFault(Messages.getString("XmlService.no_match",
new Object[] { axp.toString() }));
// Prepare children to insert
xmlfragment.build();
// Determine what has been matched
OMContainer match = null;
for (Object o : olist) {
Iterator<?> children = xmlfragment.getOMDocumentElement()
.getChildren();
if ((o instanceof OMNode)) {
OMNode node = (OMNode) o;
switch (node.getType()) {
case OMNode.ELEMENT_NODE:
if ((o instanceof OMElement))
match = (OMElement) o;
if ((o instanceof OMDocument))
match = ((OMDocument) o).getOMDocumentElement();
this.logger.debug(Messages.getString("XmlService.8"));
break;
case OMNode.TEXT_NODE:
match = ((OMText) o).getParent();
this.logger.debug(Messages.getString("XmlService.9"));
break;
case OMNode.COMMENT_NODE:
// match = node.getParent();
match = (OMContainer) node;
this.logger.debug(Messages.getString("XmlService.10"));
break;
default:
this.logger.error("XPath matched "
+ o.getClass().getCanonicalName() + " Node Type:"
+ node.getType());
this.logger.error(Messages.getString("XmlService.11"));
throw new XServicesFault(
Messages.getString("XmlService.12"));
}
} else {
this.logger.error("XPath matched "
+ o.getClass().getCanonicalName());
this.logger.error(Messages.getString("XmlService.11"));
throw new XServicesFault(Messages.getString("XmlService.12"));
}
while (children.hasNext()) {
OMNode container = (OMNode) children.next();
match.addChild((OMNode) container.clone(new OMCloneOptions()));
}
}
xmldocument.build();
return xmldocument;
}
private OMDocument replaceNodes(OMDocument xmldocument, AXIOMXPath axp, OMDocument xmlfragment) throws XServicesFault {
List<?> olist = null;
try {
olist = axp.selectNodes(xmldocument.getOMDocumentElement());
this.logger.debug("XPath '" + axp.toString() + "' has "
+ olist.size() + " matches.");
this.logger.trace("XPath root expression is: '" + axp.debug()
+ "'.");
} catch (JaxenException e) {
throw new XServicesFault(e.getMessage(), e);
}
if (olist.size() == 0)
throw new XServicesFault(Messages.getString("XmlService.no_match",
new Object[] { axp.toString() }));
// Prepare children to insert
xmlfragment.build();
// Determine what has been matched
OMNode match = null;
for (Object o : olist) {
Iterator<?> children = xmlfragment.getOMDocumentElement()
.getChildren();
if ((o instanceof OMNode)) {
OMNode node = (OMNode) o;
switch (node.getType()) {
case OMNode.ELEMENT_NODE:
if ((o instanceof OMElement))
match = (OMElement) o;
if ((o instanceof OMDocument))
match = ((OMDocument) o).getOMDocumentElement();
this.logger.debug(Messages.getString("XmlService.8"));
break;
default:
this.logger.error("XPath matched "
+ o.getClass().getCanonicalName() + " Node Type:"
+ node.getType());
this.logger.error(Messages.getString("XmlService.11"));
throw new XServicesFault(
Messages.getString("XmlService.12"));
}
} else {
this.logger.error("XPath matched "
+ o.getClass().getCanonicalName());
this.logger.error(Messages.getString("XmlService.11"));
throw new XServicesFault(Messages.getString("XmlService.12"));
}
while (children.hasNext()) {
OMNode container = (OMNode) children.next();
match.insertSiblingAfter((OMNode) container.clone(new OMCloneOptions()));
}
match.detach();
}
xmldocument.build();
return xmldocument;
}
}