it.scoppelletti.programmerpower.web.spring.config.CompositeRequestMatcher.java Source code

Java tutorial

Introduction

Here is the source code for it.scoppelletti.programmerpower.web.spring.config.CompositeRequestMatcher.java

Source

/*
 * Copyright (C) 2012 Dario Scoppelletti, <http://www.scoppelletti.it/>.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * 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 "AS IS" 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 it.scoppelletti.programmerpower.web.spring.config;

import java.util.*;
import javax.servlet.http.*;
import org.slf4j.*;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.context.ApplicationContext;
import org.springframework.security.web.util.*;
import it.scoppelletti.programmerpower.*;
import it.scoppelletti.programmerpower.reflect.*;
import it.scoppelletti.programmerpower.types.*;

/**
 * Componente {@code RequestMatcher} che riconosce un insieme di
 * <ACRONYM TITLE="Uniform Resource Locator">URL</ACRONYM> definito dai
 * componenti {@code CompositeRequestMatcherContributor} collegati.
 * 
 * @see it.scoppelletti.programmerpower.web.spring.config.CompositeRequestMatcherContributor
 * @see <A HREF="http:///www.springsource.org/spring-security"
 *      TARGET="_blank">Spring Security</A>     
 * @since 1.0.0
 */
@Final
public class CompositeRequestMatcher implements BeanNameAware, RequestMatcher {
    private static final Logger myLogger = LoggerFactory.getLogger(CompositeRequestMatcher.class);
    private final Object mySyncRoot = new Object();
    private String myBeanName;
    private List<RequestMatcher> myPatterns;

    @Autowired
    private ApplicationContext myApplCtx;

    /**
     * Costruttore.
     */
    public CompositeRequestMatcher() {
    }

    /**
     * Imposta il nome del bean.
     * 
     * @param value Valore.
     */
    public void setBeanName(String value) {
        myBeanName = value;
    }

    /**
     * Verifica se una richiesta corrisponde al modello.
     * 
     * @param  req Richiesta.
     * @return     Esito della verifica. 
     */
    public boolean matches(HttpServletRequest req) {
        List<String> patterns;
        List<RequestMatcher> compiledPatterns;

        synchronized (mySyncRoot) {
            if (myPatterns == null) {
                myPatterns = new ArrayList<RequestMatcher>();
                patterns = listPatterns(myBeanName, myApplCtx);
                for (String pattern : patterns) {
                    myPatterns.add(new AntPathRequestMatcher(pattern));
                }
            }

            // Uso una copia della collezione per rilasciare il lock appena
            // possibile
            compiledPatterns = new ArrayList<RequestMatcher>(myPatterns);
        }

        for (RequestMatcher pattern : compiledPatterns) {
            if (pattern.matches(req)) {
                myLogger.trace("Request {} match {}.", req, myBeanName);
                return true;
            }
        }

        return false;
    }

    /**
     * Restituisce la lista dei modelli di URL che devono essere gestiti da un
     * componente.
     * 
     * @param  beanName Nome del bean.
     * @param  applCtx  Contesto dell&rsquo;applicazione.
     * @return          Collezione.
     */
    private List<String> listPatterns(String beanName, ApplicationContext applCtx) {
        String targetName;
        List<String> list;
        List<String> patterns;
        Map<String, CompositeRequestMatcherContributor> contributorMap;

        if (Strings.isNullOrEmpty(beanName)) {
            throw new ArgumentNullException("beanName");
        }
        if (applCtx == null) {
            throw new ArgumentNullException("applCtx");
        }

        list = new ArrayList<String>();

        myLogger.trace("Searching for CompositeRequestMatcherContributor " + "beans with targetName={}.", beanName);
        contributorMap = applCtx.getBeansOfType(CompositeRequestMatcherContributor.class, true, true);
        if (contributorMap == null || contributorMap.isEmpty()) {
            myLogger.trace("No CompositeRequestMatcherContributor bean found.");
            return list;
        }

        for (Map.Entry<String, CompositeRequestMatcherContributor> entry : contributorMap.entrySet()) {
            targetName = entry.getValue().getTargetName();
            if (Strings.isNullOrEmpty(targetName)) {
                myLogger.warn("Invalid CompositeRequestMatcherContributor bean.",
                        new PropertyNotSetException(entry.getKey(), "targetName"));
                continue;
            }
            if (!targetName.equals(beanName)) {
                continue;
            }

            myLogger.trace("Found CompositeRequestMatcherContributor bean {} " + "for bean {}.", entry.getKey(),
                    beanName);

            patterns = entry.getValue().getPatterns();
            if (patterns == null) {
                myLogger.warn("Invalid CompositeRequestMatcherContributor bean.",
                        new PropertyNotSetException(entry.getKey(), "patterns"));
                continue;
            }

            list.addAll(patterns);
        }
        if (list.isEmpty()) {
            myLogger.debug("Pattern list is empty for bean {}.", beanName);
        }

        return list;
    }
}