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

import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * This is a basic implementation of UniqueMessageAttributeCache. In this implementation we will cache incomming
 * nonce value for a period of time. The life time can be defined in the services.xml. If not defined
 * the default value will be 5 minutes.
 */
public class NonceCache extends AbstractUniqueMessageAttributeCache {

    class Nonce
    {
        String nonceValue;
        String userName;

        public Nonce(String nonce, String user)
<span class="fc" id="L34">        {</span>
<span class="fc" id="L35">            this.nonceValue = nonce;</span>
<span class="fc" id="L36">            this.userName = user;</span>
<span class="fc" id="L37">        }</span>

        @Override
        public boolean equals(Object another)
        {
<span class="pc bpc" id="L42" title="1 of 2 branches missed.">        	if (another == null){</span>
<span class="nc" id="L43">        		return false;</span>
        	} 
        	
<span class="pc bpc" id="L46" title="1 of 2 branches missed.">        	if (another == this) {</span>
<span class="nc" id="L47">        		return true;</span>
        	}
        	
<span class="pc bpc" id="L50" title="1 of 2 branches missed.">        	if (!(another instanceof Nonce)){</span>
<span class="nc" id="L51">        		return false;</span>
        	} 
        	
        	
<span class="fc" id="L55">            Nonce otherNonce = (Nonce)another;</span>
<span class="pc bpc" id="L56" title="2 of 4 branches missed.">            if (this.userName.equals(otherNonce.userName) &amp;&amp; this.nonceValue.equals(otherNonce.nonceValue))</span>
            {
<span class="fc" id="L58">                return true;</span>
            }
<span class="nc" id="L60">            return false;</span>
        }

        @Override
        public int hashCode()
        {
<span class="fc" id="L66">            return (this.userName.hashCode() * 13 +  this.nonceValue.hashCode() * 7);</span>
        }
    }

<span class="fc" id="L70">    private Map&lt;Nonce, Calendar&gt; mapIdNonce = new HashMap&lt;Nonce, Calendar&gt;();</span>

<span class="fc" id="L72">    private final ReentrantLock lock = new ReentrantLock();</span>

    public NonceCache()
    {
<span class="fc" id="L76">        super();</span>
<span class="fc" id="L77">    }</span>
    
    public NonceCache(int maxLifeTime)
    {
<span class="fc" id="L81">        super(maxLifeTime);</span>
<span class="fc" id="L82">    }</span>

    public void addToCache(String id, String userName) {

<span class="fc" id="L86">        Nonce nonce = new Nonce(id, userName);</span>
<span class="fc" id="L87">        Calendar rightNow = Calendar.getInstance();</span>

<span class="fc" id="L89">        lock.lock();</span>
        try {
<span class="fc" id="L91">            mapIdNonce.put(nonce, rightNow);</span>
        } finally {
<span class="pc" id="L93">            lock.unlock();</span>
<span class="fc" id="L94">        }</span>

<span class="fc" id="L96">    }</span>

    public boolean valueExistsInCache(String id, String userName) {

<span class="fc" id="L100">        lock.lock();</span>

        try {
<span class="fc" id="L103">            clearStaleNonceIds();</span>
        } finally {
<span class="pc" id="L105">            lock.unlock();</span>
<span class="fc" id="L106">        }</span>
        
<span class="fc" id="L108">        Nonce nonce = new Nonce(id, userName);</span>
<span class="fc" id="L109">        return mapIdNonce.containsKey(nonce);</span>
    }

    public void clearCache() {

<span class="nc" id="L114">        lock.lock();</span>
        try {
<span class="nc" id="L116">            mapIdNonce.clear();</span>
        } finally {
<span class="nc" id="L118">            lock.unlock();</span>
<span class="nc" id="L119">        }</span>
<span class="nc" id="L120">    }</span>

    /**
     * This method will clear stale nonce ids from the map.
     */
    private void clearStaleNonceIds()
    {
<span class="fc" id="L127">        Calendar rightNow = Calendar.getInstance();</span>

<span class="fc" id="L129">        int maxLifeTime = getMaximumLifeTimeOfAnAttribute();</span>

<span class="fc" id="L131">        rightNow.add(Calendar.SECOND, -(maxLifeTime));</span>
<span class="fc" id="L132">        long timeBeforeMaxLifeTime = rightNow.getTimeInMillis();</span>
        
<span class="fc" id="L134">        Iterator&lt;Map.Entry&lt;Nonce, Calendar&gt;&gt; iterator = mapIdNonce.entrySet().iterator();</span>

<span class="fc bfc" id="L136" title="All 2 branches covered.">        while (iterator.hasNext()) {</span>

<span class="fc" id="L138">            Map.Entry&lt;Nonce, Calendar&gt; pair = iterator.next();</span>
<span class="fc" id="L139">            Calendar itemDate = pair.getValue();</span>

<span class="fc" id="L141">            long itemAddedTime = itemDate.getTimeInMillis();</span>

<span class="fc bfc" id="L143" title="All 2 branches covered.">            if (timeBeforeMaxLifeTime &gt; itemAddedTime)</span>
            {
<span class="fc" id="L145">                iterator.remove();</span>
            }
<span class="fc" id="L147">        }</span>


<span class="fc" id="L150">    }</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>