<?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>STSMessageReceiver.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.rahas</a> &gt; <span class="el_source">STSMessageReceiver.java</span></div><h1>STSMessageReceiver.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.rahas;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.receivers.AbstractInOutMessageReceiver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;

<span class="fc" id="L30">public class STSMessageReceiver extends AbstractInOutMessageReceiver {</span>
    
<span class="fc" id="L32">    private static final Log log = LogFactory.getLog(STSMessageReceiver.class);</span>
    
    public void invokeBusinessLogic(MessageContext inMessage,
            MessageContext outMessage) throws AxisFault {

        try {
<span class="fc" id="L38">            Parameter param = inMessage</span>
                    .getParameter(TokenRequestDispatcherConfig.CONFIG_PARAM_KEY);
<span class="fc" id="L40">            Parameter paramFile = inMessage</span>
                    .getParameter(TokenRequestDispatcherConfig.CONFIG_FILE_KEY);
<span class="fc" id="L42">            TokenRequestDispatcher dispatcher = null;</span>
<span class="pc bpc" id="L43" title="1 of 2 branches missed.">            if (param != null) {</span>
<span class="fc" id="L44">                dispatcher = new TokenRequestDispatcher(param</span>
                        .getParameterElement().getFirstChildWithName(
                                new QName(&quot;token-dispatcher-configuration&quot;)));
<span class="nc bnc" id="L47" title="All 2 branches missed.">            } else if (paramFile != null) {</span>
<span class="nc" id="L48">                dispatcher = new TokenRequestDispatcher((String) paramFile</span>
                        .getValue());
            } else {
<span class="nc" id="L51">                dispatcher = new TokenRequestDispatcher(</span>
                        (OMElement) inMessage
                                .getProperty(TokenRequestDispatcherConfig.CONFIG_PARAM_KEY));
            }
            
<span class="pc bpc" id="L56" title="1 of 2 branches missed.">            if(dispatcher != null) {</span>
<span class="fc" id="L57">                SOAPEnvelope responseEnv = dispatcher.handle(inMessage, outMessage);</span>
<span class="fc" id="L58">                outMessage.setEnvelope(responseEnv);</span>
<span class="fc" id="L59">            } else {</span>
<span class="nc" id="L60">                throw new TrustException(&quot;missingDispatcherConfiguration&quot;);</span>
            }
<span class="nc" id="L62">        } catch (TrustException e) {</span>
<span class="nc" id="L63">            e.printStackTrace();</span>
            //Log the exception
<span class="nc" id="L65">            log.error(e);</span>
<span class="nc" id="L66">            throw new AxisFault(e.getFaultString(), e.getFaultCode());</span>
<span class="fc" id="L67">        }</span>
<span class="fc" id="L68">    }</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>