<?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>SimpleTokenStore.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.rahas</a> &gt; <span class="el_source">SimpleTokenStore.java</span></div><h1>SimpleTokenStore.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.ws.security.WSConstants;
import org.apache.ws.security.message.token.Reference;

import javax.xml.namespace.QName;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * In-memory implementation of the token storage
 */
<span class="fc" id="L34">public class SimpleTokenStore implements TokenStorage, Serializable {</span>

<span class="fc" id="L36">    protected Map tokens = new Hashtable();</span>
    
    /**
     * We use a read write lock to improve concurrency while avoiding concurrent modification 
     * exceptions.  We allow concurrent reads and avoid concurrent reads and modifications
     * ReentrantReadWriteLock supports a maximum of 65535 recursive write locks and 65535 read locks
     */
<span class="fc" id="L43">     protected final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();</span>
     
<span class="fc" id="L45">     protected final Lock readLock = readWriteLock.readLock(); </span>
     
<span class="fc" id="L47">     protected final Lock writeLock = readWriteLock.writeLock();</span>

    public void add(Token token) throws TrustException {
               
<span class="pc bpc" id="L51" title="3 of 6 branches missed.">        if (token != null &amp;&amp; !&quot;&quot;.equals(token.getId()) &amp;&amp; token.getId() != null) {</span>
            
<span class="fc" id="L53">            writeLock.lock();</span>
            
            try {
<span class="pc bpc" id="L56" title="1 of 6 branches missed.">                if (this.tokens.keySet().size() == 0</span>
                    || (this.tokens.keySet().size() &gt; 0 &amp;&amp; !this.tokens
                        .keySet().contains(token.getId()))) {
<span class="fc" id="L59">                    tokens.put(token.getId(), token);</span>
                } else {
<span class="fc" id="L61">                    throw new TrustException(&quot;tokenAlreadyExists&quot;,</span>
                                            new String[]{token.getId()});
                }
            } finally {
<span class="fc" id="L65">                writeLock.unlock();</span>
<span class="fc" id="L66">            }</span>
        }           
<span class="fc" id="L68">    }</span>

    public void update(Token token) throws TrustException {
             
<span class="pc bpc" id="L72" title="3 of 6 branches missed.">        if (token != null &amp;&amp; token.getId() != null &amp;&amp; token.getId().trim().length() != 0) {</span>
    
<span class="fc" id="L74">            writeLock.lock();    </span>
            
            try {
<span class="fc bfc" id="L77" title="All 2 branches covered.">                if (!this.tokens.keySet().contains(token.getId())) {</span>
<span class="fc" id="L78">                    throw new TrustException(&quot;noTokenToUpdate&quot;, new String[]{token.getId()});</span>
                }
<span class="fc" id="L80">                this.tokens.put(token.getId(), token);</span>
            } finally {
<span class="fc" id="L82">                writeLock.unlock();</span>
<span class="fc" id="L83">            }</span>
        } 
        
<span class="fc" id="L86">    }</span>

    public String[] getTokenIdentifiers() throws TrustException {       
<span class="fc" id="L89">        List identifiers = new ArrayList();</span>
        
<span class="fc" id="L91">        readLock.lock();</span>
        try {
<span class="fc bfc" id="L93" title="All 2 branches covered.">            for (Iterator iterator = tokens.keySet().iterator(); iterator.hasNext();) {</span>
<span class="fc" id="L94">                identifiers.add(iterator.next());</span>
            }
        } finally {
<span class="pc" id="L97">            readLock.unlock();</span>
<span class="fc" id="L98">        }</span>
<span class="fc" id="L99">        return (String[]) identifiers.toArray(new String[identifiers.size()]);</span>
    }

    public Token[] getValidTokens() throws TrustException {
<span class="fc" id="L103">        return getTokens(new int[]{Token.ISSUED, Token.RENEWED});</span>
    }

    public Token[] getRenewedTokens() throws TrustException {
<span class="fc" id="L107">        return getTokens(Token.RENEWED);</span>
    }


    public Token[] getCancelledTokens() throws TrustException {
<span class="fc" id="L112">        return getTokens(Token.CANCELLED);</span>
    }

    public Token[] getExpiredTokens() throws TrustException {
<span class="fc" id="L116">        return getTokens(Token.EXPIRED);</span>
    }

    private Token[] getTokens(int[] states) throws TrustException {
<span class="fc" id="L120">        processTokenExpiry();</span>
<span class="fc" id="L121">        List tokens = new ArrayList();</span>
        
<span class="fc" id="L123">        readLock.lock();</span>
        
        try {
<span class="fc bfc" id="L126" title="All 2 branches covered.">            for (Iterator iterator = this.tokens.values().iterator(); iterator.hasNext();) {</span>
<span class="fc" id="L127">                Token token = (Token) iterator.next();</span>
<span class="fc bfc" id="L128" title="All 2 branches covered.">                for (int i = 0; i &lt; states.length; i++) {</span>
<span class="fc bfc" id="L129" title="All 2 branches covered.">                    if (token.getState() == states[i]) {</span>
<span class="fc" id="L130">                        tokens.add(token);</span>
<span class="fc" id="L131">                        break;</span>
                    }
                }
<span class="fc" id="L134">            }</span>
        } finally {
<span class="pc" id="L136">            readLock.unlock();</span>
<span class="fc" id="L137">        }</span>
<span class="fc" id="L138">        return (Token[]) tokens.toArray(new Token[tokens.size()]);</span>
    }

    private Token[] getTokens(int state) throws TrustException {
<span class="fc" id="L142">        processTokenExpiry();</span>
<span class="fc" id="L143">        List tokens = new ArrayList();</span>
        
<span class="fc" id="L145">        readLock.lock();</span>
        
        try {
<span class="fc bfc" id="L148" title="All 2 branches covered.">            for (Iterator iterator = this.tokens.values().iterator(); iterator.hasNext();) {</span>
<span class="fc" id="L149">                Token token = (Token) iterator.next();</span>
<span class="fc bfc" id="L150" title="All 2 branches covered.">                if (token.getState() == state) {</span>
<span class="fc" id="L151">                    tokens.add(token);</span>
                }
<span class="fc" id="L153">            }</span>
        } finally {
<span class="pc" id="L155">            readLock.unlock();</span>
<span class="fc" id="L156">        }</span>
<span class="fc" id="L157">        return (Token[]) tokens.toArray(new Token[tokens.size()]);</span>
    }

    public Token getToken(String id) throws TrustException {
<span class="fc" id="L161">        processTokenExpiry();</span>
        
<span class="fc" id="L163">        readLock.lock();</span>
        
        Token token;
        
        try {
            
<span class="fc" id="L169">            token = (Token) this.tokens.get(id);</span>
            
<span class="fc bfc" id="L171" title="All 2 branches covered.">            if(token == null) {</span>
                //Try to find the token using attached refs &amp; unattached refs
<span class="fc bfc" id="L173" title="All 2 branches covered.">                for (Iterator iterator = this.tokens.values().iterator(); iterator.hasNext();) {</span>
<span class="fc" id="L174">                    Token tempToken = (Token) iterator.next();</span>
<span class="fc" id="L175">                    OMElement elem = tempToken.getAttachedReference();</span>
<span class="fc bfc" id="L176" title="All 4 branches covered.">                    if(elem != null &amp;&amp; id.equals(this.getIdFromSTR(elem))) {</span>
<span class="fc" id="L177">                        token = tempToken;</span>
                    }
<span class="fc" id="L179">                    elem = tempToken.getUnattachedReference();</span>
<span class="fc bfc" id="L180" title="All 4 branches covered.">                    if(elem != null &amp;&amp; id.equals(this.getIdFromSTR(elem))) {</span>
<span class="fc" id="L181">                        token = tempToken;</span>
                    }
                    
<span class="fc" id="L184">                }</span>
                
            }
        
        } finally {
<span class="pc" id="L189">            readLock.unlock();</span>
<span class="fc" id="L190">        }        </span>
<span class="fc" id="L191">        return token;</span>
    }

    public void removeToken(String id){

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

        try {
<span class="fc" id="L199">            this.tokens.remove(id);</span>
        } finally {
<span class="pc" id="L201">            writeLock.unlock();</span>
<span class="fc" id="L202">        }        </span>
<span class="fc" id="L203">    }</span>
    
    protected void processTokenExpiry() throws TrustException {
        
<span class="fc" id="L207">        readLock.lock();</span>
        
        try {
<span class="fc bfc" id="L210" title="All 2 branches covered.">            for (Iterator iterator = tokens.values().iterator(); iterator.hasNext();) {</span>
<span class="fc" id="L211">                Token token = (Token) iterator.next();</span>
<span class="fc bfc" id="L212" title="All 4 branches covered.">                if (token.getExpires() != null &amp;&amp;</span>
                    token.getExpires().getTime() &lt; System.currentTimeMillis()) {
<span class="fc" id="L214">                    token.setState(Token.EXPIRED);</span>
                }
<span class="fc" id="L216">            }</span>
        } finally {
<span class="pc" id="L218">            readLock.unlock();</span>
<span class="fc" id="L219">        }</span>
<span class="fc" id="L220">    }</span>
    
    public static String getIdFromSTR(OMElement str) {
        //ASSUMPTION:SecurityTokenReference/KeyIdentifier
<span class="fc" id="L224">        OMElement child = str.getFirstElement();</span>
<span class="pc bpc" id="L225" title="1 of 2 branches missed.">        if(child == null) {</span>
<span class="nc" id="L226">            return null;</span>
        }
        
<span class="pc bpc" id="L229" title="1 of 2 branches missed.">        if (child.getQName().equals(new QName(WSConstants.SIG_NS, &quot;KeyInfo&quot;))) {</span>
<span class="nc" id="L230">            return child.getText();</span>
<span class="pc bpc" id="L231" title="1 of 2 branches missed.">        } else if(child.getQName().equals(Reference.TOKEN)) {</span>
<span class="fc" id="L232">            String uri = child.getAttributeValue(new QName(&quot;URI&quot;));</span>
<span class="fc bfc" id="L233" title="All 2 branches covered.">            if (uri.charAt(0) == '#') {</span>
<span class="fc" id="L234">                uri = uri.substring(1);</span>
            }
<span class="fc" id="L236">            return uri;</span>
        } else {
<span class="nc" id="L238">            return null;</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>