<?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>MessageOptimizer.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="right"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> &gt; <a href="index.html" class="el_package">org.apache.rampart.util</a> &gt; <span class="el_source">MessageOptimizer.java</span></div><h1>MessageOptimizer.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.OMElement;
import org.apache.axiom.om.OMText;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.rampart.RampartException;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSSecurityException;
import org.jaxen.JaxenException;
import org.jaxen.SimpleNamespaceContext;
import org.jaxen.XPath;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Utility class to handle MTOM-Optimizing Base64 Text values
 */
<span class="nc" id="L38">public class MessageOptimizer {</span>
	
	private static final String CIPHER_ELEMENT = &quot;//xenc:EncryptedData/xenc:CipherData/xenc:CipherValue&quot;;

	public static void optimize(SOAPEnvelope env, List&lt;String&gt; expressions, Map namespaces) throws RampartException {
		
<span class="nc" id="L44">		SimpleNamespaceContext nsCtx = new SimpleNamespaceContext();</span>
<span class="nc" id="L45">		nsCtx.addNamespace(WSConstants.ENC_PREFIX,WSConstants.ENC_NS);</span>
<span class="nc" id="L46">		nsCtx.addNamespace(WSConstants.SIG_PREFIX,WSConstants.SIG_NS);</span>
<span class="nc" id="L47">		nsCtx.addNamespace(WSConstants.WSSE_PREFIX,WSConstants.WSSE_NS);</span>
<span class="nc" id="L48">		nsCtx.addNamespace(WSConstants.WSU_PREFIX,WSConstants.WSU_NS);</span>

<span class="nc" id="L50">		Iterator keys = namespaces.keySet().iterator();</span>
<span class="nc bnc" id="L51" title="All 2 branches missed.">		while(keys.hasNext()){</span>
<span class="nc" id="L52">			String strPrefix =  (String)keys.next();</span>
<span class="nc" id="L53">			String strNS = (String)namespaces.get(strPrefix);</span>
<span class="nc" id="L54">			nsCtx.addNamespace(strPrefix,strNS);</span>
<span class="nc" id="L55">		}</span>

		try {
<span class="nc bnc" id="L58" title="All 2 branches missed.">            for (String exp : expressions) {</span>
<span class="nc" id="L59">                XPath xp = new AXIOMXPath(exp);</span>
<span class="nc" id="L60">                xp.setNamespaceContext(nsCtx);</span>
<span class="nc" id="L61">                List list = xp.selectNodes(env);</span>
<span class="nc bnc" id="L62" title="All 2 branches missed.">                for (Object aList : list) {</span>
<span class="nc" id="L63">                    OMElement element = (OMElement) aList;</span>
<span class="nc" id="L64">                    OMText text = (OMText) element.getFirstOMChild();</span>
<span class="nc" id="L65">                    text.setOptimize(true);</span>
<span class="nc" id="L66">                }</span>
<span class="nc" id="L67">            }</span>
<span class="nc" id="L68">		} catch (JaxenException e) {</span>
<span class="nc" id="L69">			throw new RampartException(&quot;Error in XPath &quot;, e);</span>
<span class="nc" id="L70">		}</span>

<span class="nc" id="L72">	}</span>


	/**
	 * Mark the requied Base64 text values as optimized
	 * @param env
	 * @param optimizeParts This is a set of xPath expressions
	 *  
	 * @throws WSSecurityException
	 */
	public static void optimize(SOAPEnvelope env, String optimizeParts) throws WSSecurityException {
<span class="nc" id="L83">		String separater = &quot;&lt;&gt;&quot;;</span>
<span class="nc" id="L84">		StringTokenizer tokenizer = new StringTokenizer(optimizeParts, separater);</span>

<span class="nc bnc" id="L86" title="All 2 branches missed.">		while(tokenizer.hasMoreTokens()) {</span>

<span class="nc" id="L88">			String xpathExpr = tokenizer.nextToken(); </span>

			//Find binary content
<span class="nc" id="L91">			List list = findElements(env,xpathExpr);</span>

<span class="nc" id="L93">			Iterator cipherValueElements = list.iterator();</span>

<span class="nc bnc" id="L95" title="All 2 branches missed.">			while (cipherValueElements.hasNext()) {</span>
<span class="nc" id="L96">				OMElement element = (OMElement) cipherValueElements.next();</span>
<span class="nc" id="L97">				OMText text = (OMText)element.getFirstOMChild();</span>
<span class="nc" id="L98">				text.setOptimize(true);</span>
<span class="nc" id="L99">			}</span>
<span class="nc" id="L100">		}</span>
<span class="nc" id="L101">	}</span>


	private static List findElements(OMElement elem, String expression) throws WSSecurityException {
		try {
<span class="nc" id="L106">			XPath xp = new AXIOMXPath(expression);</span>

			//Set namespaces
<span class="nc" id="L109">			SimpleNamespaceContext nsCtx = new SimpleNamespaceContext();</span>
<span class="nc" id="L110">			nsCtx.addNamespace(WSConstants.ENC_PREFIX,WSConstants.ENC_NS);</span>
<span class="nc" id="L111">			nsCtx.addNamespace(WSConstants.SIG_PREFIX,WSConstants.SIG_NS);</span>
<span class="nc" id="L112">			nsCtx.addNamespace(WSConstants.WSSE_PREFIX,WSConstants.WSSE_NS);</span>
<span class="nc" id="L113">			nsCtx.addNamespace(WSConstants.WSU_PREFIX,WSConstants.WSU_NS);</span>

<span class="nc" id="L115">			xp.setNamespaceContext(nsCtx);</span>

<span class="nc" id="L117">			return xp.selectNodes(elem);</span>

<span class="nc" id="L119">		} catch (JaxenException e) {</span>
<span class="nc" id="L120">			throw new WSSecurityException(e.getMessage(), e);</span>
		}

	}



}
</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.6.1.201212231917</span></div></body></html>