/* * 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("" + xmlFragment + "")) .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("" + replace + "")) .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("" + xmlFragment + "")) .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("" + xmlFragment + "")) .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"; 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; } }