<?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="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>DefaultFilterChainManager.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Apache Shiro :: Jar Bundle</a> &gt; <a href="../index.html" class="el_bundle">shiro-web</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.web.filter.mgt</a> &gt; <span class="el_source">DefaultFilterChainManager.java</span></div><h1>DefaultFilterChainManager.java</h1><pre class="source lang-java linenums">/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.shiro.web.filter.mgt;

import org.apache.shiro.config.ConfigurationException;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.util.Nameable;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.PathConfigProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * Default {@link FilterChainManager} implementation maintaining a map of {@link Filter Filter} instances
 * (key: filter name, value: Filter) as well as a map of {@link NamedFilterList NamedFilterList}s created from these
 * {@code Filter}s (key: filter chain name, value: NamedFilterList).  The {@code NamedFilterList} is essentially a
 * {@link FilterChain} that also has a name property by which it can be looked up.
 *
 * @see NamedFilterList
 * @since 1.0
 */
public class DefaultFilterChainManager implements FilterChainManager {

<span class="fc" id="L49">    private static transient final Logger log = LoggerFactory.getLogger(DefaultFilterChainManager.class);</span>

    private FilterConfig filterConfig;

    private Map&lt;String, Filter&gt; filters; //pool of filters available for creating chains

    private Map&lt;String, NamedFilterList&gt; filterChains; //key: chain name, value: chain

<span class="fc" id="L57">    public DefaultFilterChainManager() {</span>
<span class="fc" id="L58">        this.filters = new LinkedHashMap&lt;String, Filter&gt;();</span>
<span class="fc" id="L59">        this.filterChains = new LinkedHashMap&lt;String, NamedFilterList&gt;();</span>
<span class="fc" id="L60">        addDefaultFilters(false);</span>
<span class="fc" id="L61">    }</span>

<span class="fc" id="L63">    public DefaultFilterChainManager(FilterConfig filterConfig) {</span>
<span class="fc" id="L64">        this.filters = new LinkedHashMap&lt;String, Filter&gt;();</span>
<span class="fc" id="L65">        this.filterChains = new LinkedHashMap&lt;String, NamedFilterList&gt;();</span>
<span class="fc" id="L66">        setFilterConfig(filterConfig);</span>
<span class="fc" id="L67">        addDefaultFilters(true);</span>
<span class="fc" id="L68">    }</span>

    /**
     * Returns the {@code FilterConfig} provided by the Servlet container at webapp startup.
     *
     * @return the {@code FilterConfig} provided by the Servlet container at webapp startup.
     */
    public FilterConfig getFilterConfig() {
<span class="fc" id="L76">        return filterConfig;</span>
    }

    /**
     * Sets the {@code FilterConfig} provided by the Servlet container at webapp startup.
     *
     * @param filterConfig the {@code FilterConfig} provided by the Servlet container at webapp startup.
     */
    public void setFilterConfig(FilterConfig filterConfig) {
<span class="fc" id="L85">        this.filterConfig = filterConfig;</span>
<span class="fc" id="L86">    }</span>

    public Map&lt;String, Filter&gt; getFilters() {
<span class="fc" id="L89">        return filters;</span>
    }

    @SuppressWarnings({&quot;UnusedDeclaration&quot;})
    public void setFilters(Map&lt;String, Filter&gt; filters) {
<span class="fc" id="L94">        this.filters = filters;</span>
<span class="fc" id="L95">    }</span>

    public Map&lt;String, NamedFilterList&gt; getFilterChains() {
<span class="fc" id="L98">        return filterChains;</span>
    }

    @SuppressWarnings({&quot;UnusedDeclaration&quot;})
    public void setFilterChains(Map&lt;String, NamedFilterList&gt; filterChains) {
<span class="fc" id="L103">        this.filterChains = filterChains;</span>
<span class="fc" id="L104">    }</span>

    public Filter getFilter(String name) {
<span class="fc" id="L107">        return this.filters.get(name);</span>
    }

    public void addFilter(String name, Filter filter) {
<span class="fc" id="L111">        addFilter(name, filter, false);</span>
<span class="fc" id="L112">    }</span>

    public void addFilter(String name, Filter filter, boolean init) {
<span class="fc" id="L115">        addFilter(name, filter, init, true);</span>
<span class="fc" id="L116">    }</span>

    public void createChain(String chainName, String chainDefinition) {
<span class="fc bfc" id="L119" title="All 2 branches covered.">        if (!StringUtils.hasText(chainName)) {</span>
<span class="fc" id="L120">            throw new NullPointerException(&quot;chainName cannot be null or empty.&quot;);</span>
        }
<span class="fc bfc" id="L122" title="All 2 branches covered.">        if (!StringUtils.hasText(chainDefinition)) {</span>
<span class="fc" id="L123">            throw new NullPointerException(&quot;chainDefinition cannot be null or empty.&quot;);</span>
        }

<span class="fc bfc" id="L126" title="All 2 branches covered.">        if (log.isDebugEnabled()) {</span>
<span class="fc" id="L127">            log.debug(&quot;Creating chain [&quot; + chainName + &quot;] from String definition [&quot; + chainDefinition + &quot;]&quot;);</span>
        }

        //parse the value by tokenizing it to get the resulting filter-specific config entries
        //
        //e.g. for a value of
        //
        //     &quot;authc, roles[admin,user], perms[file:edit]&quot;
        //
        // the resulting token array would equal
        //
        //     { &quot;authc&quot;, &quot;roles[admin,user]&quot;, &quot;perms[file:edit]&quot; }
        //
<span class="fc" id="L140">        String[] filterTokens = splitChainDefinition(chainDefinition);</span>

        //each token is specific to each filter.
        //strip the name and extract any filter-specific config between brackets [ ]
<span class="fc bfc" id="L144" title="All 2 branches covered.">        for (String token : filterTokens) {</span>
<span class="fc" id="L145">            String[] nameConfigPair = toNameConfigPair(token);</span>

            //now we have the filter name, path and (possibly null) path-specific config.  Let's apply them:
<span class="fc" id="L148">            addToChain(chainName, nameConfigPair[0], nameConfigPair[1]);</span>
        }
<span class="fc" id="L150">    }</span>

    /**
     * Splits the comma-delimited filter chain definition line into individual filter definition tokens.
     * &lt;p/&gt;
     * Example Input:
     * &lt;pre&gt;
     *     foo, bar[baz], blah[x, y]
     * &lt;/pre&gt;
     * Resulting Output:
     * &lt;pre&gt;
     *     output[0] == foo
     *     output[1] == bar[baz]
     *     output[2] == blah[x, y]
     * &lt;/pre&gt;
     * @param chainDefinition the comma-delimited filter chain definition.
     * @return an array of filter definition tokens
     * @since 1.2
     * @see &lt;a href=&quot;https://issues.apache.org/jira/browse/SHIRO-205&quot;&gt;SHIRO-205&lt;/a&gt;
     */
    protected String[] splitChainDefinition(String chainDefinition) {
<span class="fc" id="L171">        return StringUtils.split(chainDefinition, StringUtils.DEFAULT_DELIMITER_CHAR, '[', ']', true, true);</span>
    }

    /**
     * Based on the given filter chain definition token (e.g. 'foo' or 'foo[bar, baz]'), this will return the token
     * as a name/value pair, removing any brackets as necessary.  Examples:
     * &lt;table&gt;
     *     &lt;tr&gt;
     *         &lt;th&gt;Input&lt;/th&gt;
     *         &lt;th&gt;Result&lt;/th&gt;
     *     &lt;/tr&gt;
     *     &lt;tr&gt;
     *         &lt;td&gt;{@code foo}&lt;/td&gt;
     *         &lt;td&gt;returned[0] == {@code foo}&lt;br/&gt;returned[1] == {@code null}&lt;/td&gt;
     *     &lt;/tr&gt;
     *     &lt;tr&gt;
     *         &lt;td&gt;{@code foo[bar, baz]}&lt;/td&gt;
     *         &lt;td&gt;returned[0] == {@code foo}&lt;br/&gt;returned[1] == {@code bar, baz}&lt;/td&gt;
     *     &lt;/tr&gt;
     * &lt;/table&gt;
     * @param token the filter chain definition token
     * @return A name/value pair representing the filter name and a (possibly null) config value.
     * @throws ConfigurationException if the token cannot be parsed
     * @since 1.2
     * @see &lt;a href=&quot;https://issues.apache.org/jira/browse/SHIRO-205&quot;&gt;SHIRO-205&lt;/a&gt;
     */
    protected String[] toNameConfigPair(String token) throws ConfigurationException {

        try {
<span class="fc" id="L200">            String[] pair = token.split(&quot;\\[&quot;, 2);</span>
<span class="fc" id="L201">            String name = StringUtils.clean(pair[0]);</span>

<span class="pc bpc" id="L203" title="1 of 2 branches missed.">            if (name == null) {</span>
<span class="nc" id="L204">                throw new IllegalArgumentException(&quot;Filter name not found for filter chain definition token: &quot; + token);</span>
            }
<span class="fc" id="L206">            String config = null;</span>

<span class="fc bfc" id="L208" title="All 2 branches covered.">            if (pair.length == 2) {</span>
<span class="fc" id="L209">                config = StringUtils.clean(pair[1]);</span>
                //if there was an open bracket, it assumed there is a closing bracket, so strip it too:
<span class="fc" id="L211">                config = config.substring(0, config.length() - 1);</span>
<span class="fc" id="L212">                config = StringUtils.clean(config);</span>

                //backwards compatibility prior to implementing SHIRO-205:
                //prior to SHIRO-205 being implemented, it was common for end-users to quote the config inside brackets
                //if that config required commas.  We need to strip those quotes to get to the interior quoted definition
                //to ensure any existing quoted definitions still function for end users:
<span class="fc bfc" id="L218" title="All 6 branches covered.">                if (config != null &amp;&amp; config.startsWith(&quot;\&quot;&quot;) &amp;&amp; config.endsWith(&quot;\&quot;&quot;)) {</span>
<span class="fc" id="L219">                    String stripped = config.substring(1, config.length() - 1);</span>
<span class="fc" id="L220">                    stripped = StringUtils.clean(stripped);</span>

                    //if the stripped value does not have any internal quotes, we can assume that the entire config was
                    //quoted and we can use the stripped value.
<span class="pc bpc" id="L224" title="1 of 4 branches missed.">                    if (stripped != null &amp;&amp; stripped.indexOf('&quot;') == -1) {</span>
<span class="fc" id="L225">                        config = stripped;</span>
                    }
                    //else:
                    //the remaining config does have internal quotes, so we need to assume that each comma delimited
                    //pair might be quoted, in which case we need the leading and trailing quotes that we stripped
                    //So we ignore the stripped value.
                }
            }
            
<span class="fc" id="L234">            return new String[]{name, config};</span>

<span class="nc" id="L236">        } catch (Exception e) {</span>
<span class="nc" id="L237">            String msg = &quot;Unable to parse filter chain definition token: &quot; + token;</span>
<span class="nc" id="L238">            throw new ConfigurationException(msg, e);</span>
        }
    }

    protected void addFilter(String name, Filter filter, boolean init, boolean overwrite) {
<span class="fc" id="L243">        Filter existing = getFilter(name);</span>
<span class="pc bpc" id="L244" title="1 of 4 branches missed.">        if (existing == null || overwrite) {</span>
<span class="fc bfc" id="L245" title="All 2 branches covered.">            if (filter instanceof Nameable) {</span>
<span class="fc" id="L246">                ((Nameable) filter).setName(name);</span>
            }
<span class="fc bfc" id="L248" title="All 2 branches covered.">            if (init) {</span>
<span class="fc" id="L249">                initFilter(filter);</span>
            }
<span class="fc" id="L251">            this.filters.put(name, filter);</span>
        }
<span class="fc" id="L253">    }</span>

    public void addToChain(String chainName, String filterName) {
<span class="fc" id="L256">        addToChain(chainName, filterName, null);</span>
<span class="fc" id="L257">    }</span>

    public void addToChain(String chainName, String filterName, String chainSpecificFilterConfig) {
<span class="fc bfc" id="L260" title="All 2 branches covered.">        if (!StringUtils.hasText(chainName)) {</span>
<span class="fc" id="L261">            throw new IllegalArgumentException(&quot;chainName cannot be null or empty.&quot;);</span>
        }
<span class="fc" id="L263">        Filter filter = getFilter(filterName);</span>
<span class="fc bfc" id="L264" title="All 2 branches covered.">        if (filter == null) {</span>
<span class="fc" id="L265">            throw new IllegalArgumentException(&quot;There is no filter with name '&quot; + filterName +</span>
                    &quot;' to apply to chain [&quot; + chainName + &quot;] in the pool of available Filters.  Ensure a &quot; +
                    &quot;filter with that name/path has first been registered with the addFilter method(s).&quot;);
        }

<span class="fc" id="L270">        applyChainConfig(chainName, filter, chainSpecificFilterConfig);</span>

<span class="fc" id="L272">        NamedFilterList chain = ensureChain(chainName);</span>
<span class="fc" id="L273">        chain.add(filter);</span>
<span class="fc" id="L274">    }</span>

    protected void applyChainConfig(String chainName, Filter filter, String chainSpecificFilterConfig) {
<span class="fc bfc" id="L277" title="All 2 branches covered.">        if (log.isDebugEnabled()) {</span>
<span class="fc" id="L278">            log.debug(&quot;Attempting to apply path [&quot; + chainName + &quot;] to filter [&quot; + filter + &quot;] &quot; +</span>
                    &quot;with config [&quot; + chainSpecificFilterConfig + &quot;]&quot;);
        }
<span class="fc bfc" id="L281" title="All 2 branches covered.">        if (filter instanceof PathConfigProcessor) {</span>
<span class="fc" id="L282">            ((PathConfigProcessor) filter).processPathConfig(chainName, chainSpecificFilterConfig);</span>
        } else {
<span class="fc bfc" id="L284" title="All 2 branches covered.">            if (StringUtils.hasText(chainSpecificFilterConfig)) {</span>
                //they specified a filter configuration, but the Filter doesn't implement PathConfigProcessor
                //this is an erroneous config:
<span class="fc" id="L287">                String msg = &quot;chainSpecificFilterConfig was specified, but the underlying &quot; +</span>
                        &quot;Filter instance is not an 'instanceof' &quot; +
<span class="fc" id="L289">                        PathConfigProcessor.class.getName() + &quot;.  This is required if the filter is to accept &quot; +</span>
                        &quot;chain-specific configuration.&quot;;
<span class="fc" id="L291">                throw new ConfigurationException(msg);</span>
            }
        }
<span class="fc" id="L294">    }</span>

    protected NamedFilterList ensureChain(String chainName) {
<span class="fc" id="L297">        NamedFilterList chain = getChain(chainName);</span>
<span class="fc bfc" id="L298" title="All 2 branches covered.">        if (chain == null) {</span>
<span class="fc" id="L299">            chain = new SimpleNamedFilterList(chainName);</span>
<span class="fc" id="L300">            this.filterChains.put(chainName, chain);</span>
        }
<span class="fc" id="L302">        return chain;</span>
    }

    public NamedFilterList getChain(String chainName) {
<span class="fc" id="L306">        return this.filterChains.get(chainName);</span>
    }

    public boolean hasChains() {
<span class="fc bfc" id="L310" title="All 2 branches covered.">        return !CollectionUtils.isEmpty(this.filterChains);</span>
    }

    public Set&lt;String&gt; getChainNames() {
        //noinspection unchecked
<span class="pc bpc" id="L315" title="1 of 2 branches missed.">        return this.filterChains != null ? this.filterChains.keySet() : Collections.EMPTY_SET;</span>
    }

    public FilterChain proxy(FilterChain original, String chainName) {
<span class="fc" id="L319">        NamedFilterList configured = getChain(chainName);</span>
<span class="fc bfc" id="L320" title="All 2 branches covered.">        if (configured == null) {</span>
<span class="fc" id="L321">            String msg = &quot;There is no configured chain under the name/key [&quot; + chainName + &quot;].&quot;;</span>
<span class="fc" id="L322">            throw new IllegalArgumentException(msg);</span>
        }
<span class="fc" id="L324">        return configured.proxy(original);</span>
    }

    /**
     * Initializes the filter by calling &lt;code&gt;filter.init( {@link #getFilterConfig() getFilterConfig()} );&lt;/code&gt;.
     *
     * @param filter the filter to initialize with the {@code FilterConfig}.
     */
    protected void initFilter(Filter filter) {
<span class="fc" id="L333">        FilterConfig filterConfig = getFilterConfig();</span>
<span class="pc bpc" id="L334" title="1 of 2 branches missed.">        if (filterConfig == null) {</span>
<span class="nc" id="L335">            throw new IllegalStateException(&quot;FilterConfig attribute has not been set.  This must occur before filter &quot; +</span>
                    &quot;initialization can occur.&quot;);
        }
        try {
<span class="fc" id="L339">            filter.init(filterConfig);</span>
<span class="nc" id="L340">        } catch (ServletException e) {</span>
<span class="nc" id="L341">            throw new ConfigurationException(e);</span>
<span class="fc" id="L342">        }</span>
<span class="fc" id="L343">    }</span>

    protected void addDefaultFilters(boolean init) {
<span class="fc bfc" id="L346" title="All 2 branches covered.">        for (DefaultFilter defaultFilter : DefaultFilter.values()) {</span>
<span class="fc" id="L347">            addFilter(defaultFilter.name(), defaultFilter.newInstance(), init, false);</span>
        }
<span class="fc" id="L349">    }</span>
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.7.201606060606</span></div></body></html>