blob: 3bad71450313c84aaa7149454ded5ee507545fc6 [file] [log] [blame]
<?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> &gt; <a href="index.source.html" class="el_package">org.apache.rampart.util</a> &gt; <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 &quot;License&quot;);
* 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 &quot;AS IS&quot; 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(&quot;split-cdata-sections&quot;, Boolean.FALSE);</span>
<span class="fc" id="L117"> domConfig.setParameter(&quot;well-formed&quot;, Boolean.FALSE);</span>
<span class="fc" id="L118"> domConfig.setParameter(&quot;namespaces&quot;, 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>
&quot;Error in converting SOAP Envelope to Document&quot;, 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 &gt; 0 &amp;&amp; !inHandler &amp;&amp; </span>
!originalKey.equals(WSSHandlerConstants.OUTFLOW_SECURITY)&amp;&amp;
!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 &lt;code&gt;Document&lt;/code&gt;
* @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>