| <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../.resources/report.css" type="text/css"/><link rel="shortcut icon" href="../.resources/report.gif" type="image/gif"/><title>Axis2Util.java</title><link rel="stylesheet" href="../.resources/prettify.css" type="text/css"/><script type="text/javascript" src="../.resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> > <a href="index.source.html" class="el_package">org.apache.rampart.util</a> > <span class="el_source">Axis2Util.java</span></div><h1>Axis2Util.java</h1><pre class="source lang-java linenums">/* |
| * Copyright 2004,2005 The Apache Software Foundation. |
| * |
| * 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 org.apache.rampart.util; |
| |
| import org.apache.axiom.om.OMAbstractFactory; |
| import org.apache.axiom.om.OMAttribute; |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axiom.om.OMFactory; |
| import org.apache.axiom.om.OMMetaFactory; |
| import org.apache.axiom.om.OMNamespace; |
| import org.apache.axiom.om.OMNode; |
| import org.apache.axiom.om.OMXMLBuilderFactory; |
| import org.apache.axiom.om.impl.builder.StAXOMBuilder; |
| import org.apache.axiom.soap.SOAP11Constants; |
| import org.apache.axiom.soap.SOAP12Constants; |
| import org.apache.axiom.soap.SOAPEnvelope; |
| import org.apache.axiom.soap.SOAPFactory; |
| import org.apache.axiom.soap.SOAPHeader; |
| import org.apache.axiom.soap.SOAPHeaderBlock; |
| import org.apache.axiom.soap.SOAPModelBuilder; |
| import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder; |
| import org.apache.rampart.handler.WSSHandlerConstants; |
| import org.apache.ws.security.WSSecurityException; |
| import org.apache.xml.security.utils.XMLUtils; |
| import org.w3c.dom.DOMConfiguration; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| import javax.xml.namespace.QName; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.stream.FactoryConfigurationError; |
| import javax.xml.stream.XMLStreamReader; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| |
| /** |
| * Utility class for the Axis2-WSS4J Module |
| */ |
| <span class="nc" id="L56">public class Axis2Util {</span> |
| |
| <span class="fc" id="L58"> private static ThreadLocal doomTacker = new ThreadLocal();</span> |
| |
| public static boolean isUseDOOM() { |
| <span class="nc" id="L61"> Object value = doomTacker.get();</span> |
| <span class="nc bnc" id="L62" title="All 2 branches missed."> return (value != null);</span> |
| } |
| |
| public static void useDOOM(boolean isDOOMRequired) { |
| //TODO Enable this when we have DOOM fixed to be able to flow in and out of Axis2 |
| // if(isDOOMRequired) { |
| // if(!isUseDOOM()) { |
| // System.setProperty(OMAbstractFactory.SOAP11_FACTORY_NAME_PROPERTY, SOAP11Factory.class.getName()); |
| // System.setProperty(OMAbstractFactory.SOAP12_FACTORY_NAME_PROPERTY, SOAP12Factory.class.getName()); |
| // System.setProperty(OMAbstractFactory.OM_FACTORY_NAME_PROPERTY, OMDOMFactory.class.getName()); |
| // doomTacker.set(new Object()); |
| // } |
| // } else { |
| // System.getProperties().remove(OMAbstractFactory.SOAP11_FACTORY_NAME_PROPERTY); |
| // System.getProperties().remove(OMAbstractFactory.SOAP12_FACTORY_NAME_PROPERTY); |
| // System.getProperties().remove(OMAbstractFactory.OM_FACTORY_NAME_PROPERTY); |
| // doomTacker.set(null); |
| // } |
| <span class="fc" id="L80"> }</span> |
| |
| |
| /** |
| * Creates a DOM Document using the SOAP Envelope. |
| * @param env An org.apache.axiom.soap.SOAPEnvelope instance |
| * @return Returns the DOM Document of the given SOAP Envelope. |
| */ |
| public static Document getDocumentFromSOAPEnvelope(SOAPEnvelope env, boolean useDoom) |
| throws WSSecurityException { |
| try { |
| <span class="fc bfc" id="L91" title="All 2 branches covered."> if(env instanceof Element) {</span> |
| <span class="fc" id="L92"> Element element = (Element)env;</span> |
| <span class="fc" id="L93"> Document document = element.getOwnerDocument();</span> |
| // For outgoing messages, Axis2 only creates the SOAPEnvelope, but no document. If |
| // the Axiom implementation also supports DOM, then the envelope (seen as a DOM |
| // element) will have an owner document, but the document and the envelope have no |
| // parent-child relationship. On the other hand, the input expected by WSS4J is |
| // a document with the envelope as document element. Therefore we need to set the |
| // envelope as document element on the owner document. |
| <span class="pc bpc" id="L100" title="1 of 2 branches missed."> if (element.getParentNode() != document) {</span> |
| <span class="fc" id="L101"> document.appendChild(element);</span> |
| } |
| // If the Axiom implementation supports DOM, then it is possible/likely that the |
| // DOM API was used to create the object model (or parts of it). In this case, the |
| // object model is not necessarily well formed with respect to namespaces because |
| // DOM doesn't generate namespace declarations automatically. This is an issue |
| // because WSS4J/Santuario expects that all namespace declarations are present. |
| // If this is not the case, then signature values or encryptions will be incorrect. |
| // To avoid this, we normalize the document. Note that if we disable the other |
| // normalizations supported by DOM, this is generally not a heavy operation. |
| // In particular, the Axiom implementation is not required to expand the object |
| // model (including OMSourcedElements) because the Axiom builder is required to |
| // perform namespace repairing, so that no modifications to unexpanded parts of |
| // the message are required. |
| <span class="fc" id="L115"> DOMConfiguration domConfig = document.getDomConfig();</span> |
| <span class="fc" id="L116"> domConfig.setParameter("split-cdata-sections", Boolean.FALSE);</span> |
| <span class="fc" id="L117"> domConfig.setParameter("well-formed", Boolean.FALSE);</span> |
| <span class="fc" id="L118"> domConfig.setParameter("namespaces", Boolean.TRUE);</span> |
| <span class="fc" id="L119"> document.normalizeDocument();</span> |
| <span class="fc" id="L120"> return document;</span> |
| } |
| |
| <span class="pc bpc" id="L123" title="1 of 2 branches missed."> if (useDoom) {</span> |
| <span class="fc" id="L124"> env.build();</span> |
| |
| // Workaround to prevent a bug in AXIOM where |
| // there can be an incomplete OMElement as the first child body |
| <span class="fc" id="L128"> OMElement firstElement = env.getBody().getFirstElement();</span> |
| <span class="pc bpc" id="L129" title="1 of 2 branches missed."> if (firstElement != null) {</span> |
| <span class="fc" id="L130"> firstElement.build();</span> |
| } |
| |
| //Get processed headers |
| <span class="fc" id="L134"> SOAPHeader soapHeader = env.getHeader();</span> |
| <span class="fc" id="L135"> ArrayList processedHeaderQNames = new ArrayList();</span> |
| <span class="pc bpc" id="L136" title="1 of 2 branches missed."> if(soapHeader != null) {</span> |
| <span class="fc" id="L137"> Iterator headerBlocs = soapHeader.getChildElements();</span> |
| <span class="fc bfc" id="L138" title="All 2 branches covered."> while (headerBlocs.hasNext()) {</span> |
| <span class="fc" id="L139"> SOAPHeaderBlock element = (SOAPHeaderBlock) headerBlocs.next();</span> |
| <span class="fc bfc" id="L140" title="All 2 branches covered."> if(element.isProcessed()) {</span> |
| <span class="fc" id="L141"> processedHeaderQNames.add(element.getQName());</span> |
| } |
| <span class="fc" id="L143"> }</span> |
| } |
| |
| // Check the namespace and find SOAP version and factory |
| <span class="fc" id="L147"> String nsURI = null;</span> |
| <span class="fc" id="L148"> OMMetaFactory metaFactory = OMAbstractFactory.getMetaFactory(OMAbstractFactory.FEATURE_DOM);</span> |
| SOAPFactory factory; |
| <span class="fc bfc" id="L150" title="All 2 branches covered."> if (env.getNamespace().getNamespaceURI().equals(</span> |
| SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) { |
| <span class="fc" id="L152"> nsURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;</span> |
| <span class="fc" id="L153"> factory = metaFactory.getSOAP11Factory();</span> |
| } else { |
| <span class="fc" id="L155"> nsURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;</span> |
| <span class="fc" id="L156"> factory = metaFactory.getSOAP12Factory();</span> |
| } |
| |
| <span class="fc" id="L159"> StAXSOAPModelBuilder stAXSOAPModelBuilder = new StAXSOAPModelBuilder(</span> |
| env.getXMLStreamReader(), factory, nsURI); |
| <span class="fc" id="L161"> SOAPEnvelope envelope = (stAXSOAPModelBuilder)</span> |
| .getSOAPEnvelope(); |
| <span class="fc" id="L163"> envelope.getParent().build();</span> |
| |
| //Set the processed flag of the processed headers |
| <span class="fc" id="L166"> SOAPHeader header = envelope.getHeader();</span> |
| <span class="fc" id="L167"> for (Iterator iter = processedHeaderQNames.iterator(); iter</span> |
| <span class="fc bfc" id="L168" title="All 2 branches covered."> .hasNext();) {</span> |
| <span class="fc" id="L169"> QName name = (QName) iter.next();</span> |
| <span class="fc" id="L170"> Iterator omKids = header.getChildrenWithName(name);</span> |
| <span class="pc bpc" id="L171" title="1 of 2 branches missed."> if(omKids.hasNext()) {</span> |
| <span class="fc" id="L172"> ((SOAPHeaderBlock)omKids.next()).setProcessed();</span> |
| } |
| <span class="fc" id="L174"> }</span> |
| |
| <span class="fc" id="L176"> Element envElem = (Element) envelope;</span> |
| <span class="fc" id="L177"> return envElem.getOwnerDocument();</span> |
| } else { |
| <span class="nc" id="L179"> ByteArrayOutputStream baos = new ByteArrayOutputStream();</span> |
| <span class="nc" id="L180"> env.build();</span> |
| <span class="nc" id="L181"> env.serialize(baos);</span> |
| <span class="nc" id="L182"> ByteArrayInputStream bais = new ByteArrayInputStream(baos</span> |
| .toByteArray()); |
| <span class="nc" id="L184"> DocumentBuilderFactory factory = DocumentBuilderFactory</span> |
| .newInstance(); |
| <span class="nc" id="L186"> factory.setNamespaceAware(true);</span> |
| <span class="nc" id="L187"> return factory.newDocumentBuilder().parse(bais);</span> |
| } |
| <span class="nc" id="L189"> } catch (Exception e) {</span> |
| <span class="nc" id="L190"> throw new WSSecurityException(</span> |
| "Error in converting SOAP Envelope to Document", e); |
| } |
| } |
| |
| /** |
| * Builds a SOAPEnvelope from DOM Document. |
| * @param doc - The dom document that contains a SOAP message |
| * @param useDoom |
| * @return |
| * @throws WSSecurityException |
| */ |
| public static SOAPEnvelope getSOAPEnvelopeFromDOMDocument(Document doc, boolean useDoom) |
| throws WSSecurityException { |
| |
| <span class="fc" id="L205"> Element documentElement = doc.getDocumentElement();</span> |
| <span class="pc bpc" id="L206" title="1 of 2 branches missed."> if (documentElement instanceof SOAPEnvelope) {</span> |
| <span class="fc" id="L207"> SOAPEnvelope env = (SOAPEnvelope)documentElement;</span> |
| // If the DOM tree already implements the Axiom API and the corresponding |
| // Axiom implementation is also used as default implementation, then just return |
| // the SOAPEnvelope directly. Note that this will never be the case for DOOM, |
| // but may be the case for a non standard Axiom implementation. |
| <span class="pc bpc" id="L212" title="1 of 2 branches missed."> if (env.getOMFactory().getMetaFactory() == OMAbstractFactory.getMetaFactory()) {</span> |
| <span class="nc" id="L213"> return env;</span> |
| } |
| } |
| |
| <span class="pc bpc" id="L217" title="1 of 2 branches missed."> if(useDoom) {</span> |
| try { |
| //Get processed headers |
| <span class="fc" id="L220"> SOAPEnvelope env = (SOAPEnvelope)doc.getDocumentElement(); </span> |
| <span class="fc" id="L221"> ArrayList processedHeaderQNames = new ArrayList();</span> |
| <span class="fc" id="L222"> SOAPHeader soapHeader = env.getHeader();</span> |
| |
| <span class="pc bpc" id="L224" title="1 of 2 branches missed."> if(soapHeader != null) {</span> |
| <span class="fc" id="L225"> Iterator headerBlocs = soapHeader.getChildElements();</span> |
| <span class="fc bfc" id="L226" title="All 2 branches covered."> while (headerBlocs.hasNext()) {</span> |
| |
| <span class="fc" id="L228"> OMElement element = (OMElement)headerBlocs.next();</span> |
| <span class="fc" id="L229"> SOAPHeaderBlock header = null;</span> |
| |
| <span class="fc bfc" id="L231" title="All 2 branches covered."> if (element instanceof SOAPHeaderBlock) {</span> |
| <span class="fc" id="L232"> header = (SOAPHeaderBlock) element;</span> |
| |
| // If a header block is not an instance of SOAPHeaderBlock, it means that |
| // it is a header we have added in rampart eg. EncryptedHeader and should |
| // be converted to SOAPHeaderBlock for processing |
| } else { |
| <span class="fc" id="L238"> header = soapHeader.addHeaderBlock(element.getLocalName(), element.getNamespace());</span> |
| <span class="fc" id="L239"> Iterator attrIter = element.getAllAttributes();</span> |
| <span class="pc bpc" id="L240" title="1 of 2 branches missed."> while (attrIter.hasNext()) {</span> |
| <span class="nc" id="L241"> OMAttribute attr = (OMAttribute)attrIter.next();</span> |
| <span class="nc" id="L242"> header.addAttribute(attr.getLocalName(), attr.getAttributeValue(), attr.getNamespace());</span> |
| <span class="nc" id="L243"> }</span> |
| <span class="fc" id="L244"> Iterator nsIter = element.getAllDeclaredNamespaces();</span> |
| <span class="fc bfc" id="L245" title="All 2 branches covered."> while (nsIter.hasNext()) {</span> |
| <span class="fc" id="L246"> OMNamespace ns = (OMNamespace) nsIter.next();</span> |
| <span class="fc" id="L247"> header.declareNamespace(ns);</span> |
| <span class="fc" id="L248"> }</span> |
| // retrieve all child nodes (including any text nodes) |
| // and re-attach to header block |
| <span class="fc" id="L251"> Iterator children = element.getChildren();</span> |
| <span class="fc bfc" id="L252" title="All 2 branches covered."> while (children.hasNext()) {</span> |
| <span class="fc" id="L253"> OMNode child = (OMNode)children.next();</span> |
| <span class="fc" id="L254"> children.remove();</span> |
| <span class="fc" id="L255"> header.addChild(child);</span> |
| <span class="fc" id="L256"> }</span> |
| |
| <span class="fc" id="L258"> headerBlocs.remove();</span> |
| |
| <span class="fc" id="L260"> soapHeader.build();</span> |
| |
| <span class="fc" id="L262"> header.setProcessed();</span> |
| |
| } |
| |
| <span class="fc bfc" id="L266" title="All 2 branches covered."> if(header.isProcessed()) {</span> |
| <span class="fc" id="L267"> processedHeaderQNames.add(element.getQName());</span> |
| } |
| <span class="fc" id="L269"> }</span> |
| |
| } |
| <span class="fc" id="L272"> XMLStreamReader reader = ((OMElement) doc.getDocumentElement())</span> |
| .getXMLStreamReader(); |
| <span class="fc" id="L274"> SOAPModelBuilder stAXSOAPModelBuilder = OMXMLBuilderFactory.createStAXSOAPModelBuilder(</span> |
| reader); |
| <span class="fc" id="L276"> SOAPEnvelope envelope = stAXSOAPModelBuilder.getSOAPEnvelope();</span> |
| |
| //Set the processed flag of the processed headers |
| <span class="fc" id="L279"> SOAPHeader header = envelope.getHeader();</span> |
| <span class="fc" id="L280"> for (Iterator iter = processedHeaderQNames.iterator(); iter</span> |
| <span class="fc bfc" id="L281" title="All 2 branches covered."> .hasNext();) {</span> |
| <span class="fc" id="L282"> QName name = (QName) iter.next();</span> |
| <span class="fc" id="L283"> Iterator omKids = header.getChildrenWithName(name);</span> |
| <span class="pc bpc" id="L284" title="1 of 2 branches missed."> if(omKids.hasNext()) {</span> |
| <span class="fc" id="L285"> ((SOAPHeaderBlock)omKids.next()).setProcessed();</span> |
| } |
| <span class="fc" id="L287"> }</span> |
| |
| <span class="fc" id="L289"> envelope.build();</span> |
| |
| <span class="fc" id="L291"> return envelope;</span> |
| |
| <span class="nc" id="L293"> } catch (FactoryConfigurationError e) {</span> |
| <span class="nc" id="L294"> throw new WSSecurityException(e.getMessage());</span> |
| } |
| } else { |
| try { |
| <span class="nc" id="L298"> ByteArrayOutputStream os = new ByteArrayOutputStream();</span> |
| <span class="nc" id="L299"> XMLUtils.outputDOM(doc.getDocumentElement(), os, true);</span> |
| <span class="nc" id="L300"> ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray());</span> |
| |
| <span class="nc" id="L302"> SOAPModelBuilder stAXSOAPModelBuilder = OMXMLBuilderFactory.createSOAPModelBuilder(bais, null);</span> |
| <span class="nc" id="L303"> return stAXSOAPModelBuilder.getSOAPEnvelope();</span> |
| <span class="nc" id="L304"> } catch (Exception e) {</span> |
| <span class="nc" id="L305"> throw new WSSecurityException(e.getMessage());</span> |
| } |
| } |
| } |
| |
| |
| /** |
| * Provides the appropriate key to pickup config params from the message context. |
| * This is acutally used when the outflow handler (WSDoAllSender) |
| * is repeated n number of times. |
| * @param originalKey The default key |
| * @param inHandler Whether the handler is the inflow handler or not |
| * @param repetition The current repetition number |
| * @return Returns the key to be used internally in the security module to pick |
| * up the config params. |
| */ |
| public static String getKey(String originalKey, boolean inHandler, int repetition) { |
| |
| <span class="nc bnc" id="L323" title="All 8 branches missed."> if(repetition > 0 && !inHandler && </span> |
| !originalKey.equals(WSSHandlerConstants.OUTFLOW_SECURITY)&& |
| !originalKey.equals(WSSHandlerConstants.SENDER_REPEAT_COUNT)) { |
| |
| <span class="nc" id="L327"> return originalKey + repetition;</span> |
| } |
| <span class="nc" id="L329"> return originalKey;</span> |
| } |
| |
| /** |
| * This will build a DOOM Element that is of the same <code>Document</code> |
| * @param factory |
| * @param element |
| * @return |
| */ |
| public static OMElement toDOOM(OMFactory factory, OMElement element){ |
| <span class="nc" id="L339"> StAXOMBuilder builder = new StAXOMBuilder(factory, element.getXMLStreamReader());</span> |
| <span class="nc" id="L340"> OMElement elem = builder.getDocumentElement();</span> |
| <span class="nc" id="L341"> elem.build();</span> |
| <span class="nc" id="L342"> return elem;</span> |
| } |
| |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.5.201505241946</span></div></body></html> |