org.anyframe.iam.core.intercept.web.ReloadableRestrictedTimesFilterInvocationSecurityMetadataSource.java Source code

Java tutorial

Introduction

Here is the source code for org.anyframe.iam.core.intercept.web.ReloadableRestrictedTimesFilterInvocationSecurityMetadataSource.java

Source

/*
 * Copyright 2002-2008 the original author or authors.
 *
 * 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 org.anyframe.iam.core.intercept.web;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.anyframe.exception.BaseException;
import org.anyframe.iam.core.securedobject.ISecuredObjectService;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.MessageSource;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;

/**
 * This class extends objectDefinitionSource of Spring Security. It offers a
 * function to treat role mapping of resources related with registered
 * Restricted Times
 * 
 * @author Byunghun Woo
 * 
 */
public class ReloadableRestrictedTimesFilterInvocationSecurityMetadataSource
        implements FilterInvocationSecurityMetadataSource, InitializingBean, ApplicationContextAware {

    protected final Log logger = LogFactory.getLog(getClass());

    private MessageSource messageSource;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.messageSource = (MessageSource) applicationContext.getBean("messageSource");
    }

    protected MessageSource getMessageSource() {
        return messageSource;
    }

    private UrlMatcher urlMatcher;

    private boolean stripQueryStringFromUrls;

    public boolean isStripQueryStringFromUrls() {
        return stripQueryStringFromUrls;
    }

    public void setStripQueryStringFromUrls(boolean stripQueryStringFromUrls) {
        this.stripQueryStringFromUrls = stripQueryStringFromUrls;
    }

    public UrlMatcher getUrlMatcher() {
        return urlMatcher;
    }

    public void setUrlMatcher(UrlMatcher urlMatcher) {
        this.urlMatcher = urlMatcher;
        setStripQueryStringFromUrls(urlMatcher instanceof AntUrlPathMatcher);
    }

    private ISecuredObjectService securedObjectService;

    public void setSecuredObjectService(ISecuredObjectService securedObjectService) {
        this.securedObjectService = securedObjectService;
    }

    private List alwaysTimeRoleCheck;

    private List alwaysTimeResourceCheck;

    private Map dailyFilteredTimeRoleCheck;

    private Map dailyFilteredTimeResourceCheck;

    public List getAlwaysTimeRoleCheck() {
        return Collections.unmodifiableList(alwaysTimeRoleCheck);
    }

    public List getAlwaysTimeResourceCheck() {
        return Collections.unmodifiableList(alwaysTimeResourceCheck);
    }

    public Map getDailyFilteredTimeRoleCheck() {
        return Collections.unmodifiableMap(dailyFilteredTimeRoleCheck);
    }

    public Map getDailyFilteredTimeResourceCheck() {
        return Collections.unmodifiableMap(dailyFilteredTimeResourceCheck);
    }

    /**
     * This method is InitializingBean and executed as soon as this class runs.
     * This method only calls reloadRestrictedTimes.
     */
    public void afterPropertiesSet() throws Exception {
        reloadRestrictedTimes();
    }

    /**
     * Get restriction information of roles related time. crash/daily types will
     * be set alwaysTimeRoleCheck, other types will be
     * dailyFilteredTimeRoleCheck.
     * 
     * @return Object[] Array of mapping information about restricted time and
     * role
     * @throws Exception fail to make list
     */
    public Object[] getRestrictedTimesRoles() throws Exception {
        List alwaysTimeRoleCheck = new ArrayList();
        Map dailyFilteredTimeRoleCheck = new LinkedHashMap();

        List resultList = securedObjectService.getRestrictedTimesRoles();

        Iterator itr = resultList.iterator();
        Map tempMap = null;
        Map beforeMap = null;

        String beforeTimeId = null;
        String presentTimeType = null;
        String presentTimeId = null;
        boolean sameFlag = false;

        while (itr.hasNext()) {
            tempMap = (Map) itr.next();

            presentTimeId = (String) tempMap.get("time_id");
            sameFlag = (presentTimeId.equals(beforeTimeId) ? true : false);
            presentTimeType = (String) tempMap.get("time_type");

            if ("crash".equals(presentTimeType) || "daily".equals(presentTimeType)) {
                // time_id  ?  role_id   ??? 
                if (sameFlag) {
                    beforeMap = (Map) alwaysTimeRoleCheck.get(alwaysTimeRoleCheck.size() - 1);
                    ((List) beforeMap.get("restrictedRoleIds"))
                            .add(new SecurityConfig((String) tempMap.get("role_id")));
                } else {
                    List configList = new LinkedList();
                    configList.add(new SecurityConfig((String) tempMap.get("role_id")));
                    tempMap.put("restrictedRoleIds", configList);
                    alwaysTimeRoleCheck.add(tempMap);
                }
            } else {
                String startDate = (String) tempMap.get("start_date");
                String endDate = (String) tempMap.get("end_date");
                String[] betweenDays = getBetweenDays(startDate, endDate);
                // ? time ?  ???    ? ?? filtered ?? 
                // ?
                for (int i = 0; i < betweenDays.length; i++) {
                    // ? filtered   ?  ? ?? ?  
                    if (dailyFilteredTimeRoleCheck.containsKey(betweenDays[i])) {
                        // ? time_id  ?  - Role  add 
                        if (sameFlag) {
                            List beforeFilteredList = (List) dailyFilteredTimeRoleCheck.get(betweenDays[i]);
                            beforeMap = (Map) beforeFilteredList.get(beforeFilteredList.size() - 1);
                            ((List) beforeMap.get("restrictedRoleIds"))
                                    .add(new SecurityConfig((String) tempMap.get("role_id")));
                        } else { //  filtered  ?? ?  ? tempMap ?
                            // 
                            List beforeFilteredList = (List) dailyFilteredTimeRoleCheck.get(betweenDays[i]);

                            List configList = new LinkedList();
                            configList.add(new SecurityConfig((String) tempMap.get("role_id")));
                            tempMap.put("restrictedRoleIds", configList);
                            beforeFilteredList.add(tempMap);
                        }
                    } else { //  ?  filtered  List  ?
                        List filteredList = new ArrayList();

                        List configList = new LinkedList();
                        configList.add(new SecurityConfig((String) tempMap.get("role_id")));
                        tempMap.put("restrictedRoleIds", configList);
                        filteredList.add(tempMap);

                        dailyFilteredTimeRoleCheck.put(betweenDays[i], filteredList);
                    }
                }
            }

            beforeTimeId = presentTimeId;
        }

        return new Object[] { alwaysTimeRoleCheck, dailyFilteredTimeRoleCheck };
    }

    /**
     * Get restriction information of resources related with time. crash/daily
     * types will be set alwayTimeResourceCheck, other types will be set
     * dailyFilteredTimeResourceCheck
     * 
     * @return Object[] Array of mapping information about restricted time and
     * role
     * @throws Exception fail to make list
     */
    public Object[] getRestrictedTimesResources() throws Exception {
        List alwaysTimeResourceCheck = new ArrayList();
        Map dailyFilteredTimeResourceCheck = new LinkedHashMap();

        List resultList = securedObjectService.getRestrictedTimesResources();

        Iterator itr = resultList.iterator();
        Map tempMap = null;
        Map beforeMap = null;

        String beforeTimeResourceId = null;
        String presentTimeType = null;
        String presentTimeResourceId = null;
        boolean sameFlag = false;

        while (itr.hasNext()) {
            tempMap = (Map) itr.next();

            presentTimeResourceId = (String) tempMap.get("time_id") + (String) tempMap.get("resource_id");
            sameFlag = (presentTimeResourceId.equals(beforeTimeResourceId) ? true : false);
            presentTimeType = (String) tempMap.get("time_type");

            if ("crash".equals(presentTimeType) || "daily".equals(presentTimeType)) {
                // ? id  ?  role_id   ??? 
                if (sameFlag) {
                    if (tempMap.get("exclusion_role_id") != null) {
                        beforeMap = (Map) alwaysTimeResourceCheck.get(alwaysTimeResourceCheck.size() - 1);
                        ((List) beforeMap.get("unrestrictedRoleIds"))
                                .add(new SecurityConfig((String) tempMap.get("exclusion_role_id")));
                    }
                } else {
                    List configList = new LinkedList();

                    // ? ? Restricted Times  ROLE ?  ? - ?? 
                    // ROLE ?  ? .
                    configList
                            .add(new SecurityConfig(RestrictedResourceHolder.RESTRICTED_TIMES_RESERVED_ROLE_NAME));

                    //  Role   ROLE ?      Role ?  
                    // ? 
                    if (tempMap.get("exclusion_role_id") != null) {
                        configList.add(new SecurityConfig((String) tempMap.get("exclusion_role_id")));
                    }
                    tempMap.put("unrestrictedRoleIds", configList);
                    tempMap.put("compiledResourcePattern",
                            urlMatcher.compile((String) tempMap.get("resource_pattern")));
                    alwaysTimeResourceCheck.add(tempMap);
                }
            } else {
                String startDate = (String) tempMap.get("start_date");
                String endDate = (String) tempMap.get("end_date");
                String[] betweenDays = getBetweenDays(startDate, endDate);
                // ? time ?  ???    ? ?? filtered ?? 
                // ?
                for (int i = 0; i < betweenDays.length; i++) {
                    // ? filtered   ?  ? ?? ?  
                    if (dailyFilteredTimeResourceCheck.containsKey(betweenDays[i])) {
                        // ? id  ?  - Role  add 
                        if (sameFlag) {
                            if (tempMap.get("exclusion_role_id") != null) {
                                List beforeFilteredList = (List) dailyFilteredTimeResourceCheck.get(betweenDays[i]);
                                beforeMap = (Map) beforeFilteredList.get(beforeFilteredList.size() - 1);
                                ((List) beforeMap.get("unrestrictedRoleIds"))
                                        .add(new SecurityConfig((String) tempMap.get("exclusion_role_id")));
                            }
                        } else { //  filtered  ?? ?  ? tempMap ?
                            // 
                            List beforeFilteredList = (List) dailyFilteredTimeResourceCheck.get(betweenDays[i]);

                            List configList = new LinkedList();

                            // ? ? Restricted Times  ROLE ?  ? -
                            // ??  ROLE ?  ? .
                            configList.add(new SecurityConfig(
                                    RestrictedResourceHolder.RESTRICTED_TIMES_RESERVED_ROLE_NAME));
                            //  Role   ROLE ?      Role ?
                            //   ? 
                            if (tempMap.get("exclusion_role_id") != null) {
                                configList.add(new SecurityConfig((String) tempMap.get("exclusion_role_id")));
                            }
                            tempMap.put("unrestrictedRoleIds", configList);
                            tempMap.put("compiledResourcePattern",
                                    urlMatcher.compile((String) tempMap.get("resource_pattern")));
                            beforeFilteredList.add(tempMap);
                        }
                    } else { //  ?  filtered  List  ?
                        List filteredList = new ArrayList();

                        List configList = new LinkedList();
                        // ? ? Restricted Times  ROLE ?  ? -
                        // ??  ROLE ?  ? .
                        configList.add(
                                new SecurityConfig(RestrictedResourceHolder.RESTRICTED_TIMES_RESERVED_ROLE_NAME));
                        //  Role   ROLE ?      Role ?
                        //   ? 
                        if (tempMap.get("exclusion_role_id") != null) {
                            configList.add(new SecurityConfig((String) tempMap.get("exclusion_role_id")));
                        }
                        tempMap.put("unrestrictedRoleIds", configList);
                        tempMap.put("compiledResourcePattern",
                                urlMatcher.compile((String) tempMap.get("resource_pattern")));
                        filteredList.add(tempMap);

                        dailyFilteredTimeResourceCheck.put(betweenDays[i], filteredList);
                    }
                }
            }

            beforeTimeResourceId = presentTimeResourceId;
        }

        return new Object[] { alwaysTimeResourceCheck, dailyFilteredTimeResourceCheck };
    }

    /**
     * Reset data into ConfigAttribute of Spring security
     * 
     * @param timeCheckList List of Map includes information of always time
     * Check
     * @param configKey Map key about role that will be changed
     * ConfigAttribute
     */
    public void listToConfig(List timeCheckList, String configKey) {
        Iterator iter = timeCheckList.iterator();
        while (iter.hasNext()) {
            Map tempMap = (Map) iter.next();
            // ?? Map ? betweendays ? ? day key ?  ? ?. ?
            // ConfigAttribute  ?  skip 
            if (!(tempMap.get(configKey) instanceof List<?>)) {
                tempMap.put(configKey, (List<ConfigAttribute>) tempMap.get(configKey));
            }
        }
    }

    /**
     * Reset data into ConfigAttribute of Spring security
     * 
     * @param dailyFilteredMap Map object that contains information of daily
     * filtered time Check
     * @param configKey Map key about role that will be changed
     * ConfigAttribute
     */
    public void listToConfig(Map dailyFilteredMap, String configKey) {
        Iterator iter = dailyFilteredMap.entrySet().iterator();

        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            List filteredList = (List) entry.getValue();
            listToConfig(filteredList, configKey);
        }
    }

    /**
     * Reload mapping information of restricted times
     * 
     * @throws BaseException fail to reload data
     */
    public void reloadRestrictedTimes() throws BaseException {
        try {
            Object[] restrictedTimesRoles = getRestrictedTimesRoles();
            Object[] restrictedTimesResources = getRestrictedTimesResources();
            alwaysTimeRoleCheck = (List) restrictedTimesRoles[0];
            dailyFilteredTimeRoleCheck = (Map) restrictedTimesRoles[1];
            alwaysTimeResourceCheck = (List) restrictedTimesResources[0];
            dailyFilteredTimeResourceCheck = (Map) restrictedTimesResources[1];

            // ConfigAttribute   - Collections.unmodifiableList
            // ( )  ? ? ? ? ? .
            listToConfig(alwaysTimeRoleCheck, "restrictedRoleIds");
            listToConfig(dailyFilteredTimeRoleCheck, "restrictedRoleIds");
            listToConfig(alwaysTimeResourceCheck, "unrestrictedRoleIds");
            listToConfig(dailyFilteredTimeResourceCheck, "unrestrictedRoleIds");

            if (logger.isInfoEnabled())
                logger.info("reloadRestrictedTimes completed.");

            if (logger.isDebugEnabled()) {
                logger.debug("alwaysTimeRoleCheck : " + alwaysTimeRoleCheck);
                logger.debug("dailyFilteredTimeRoleCheck : " + dailyFilteredTimeRoleCheck);
                logger.debug("alwaysTimeResourceCheck : " + alwaysTimeResourceCheck);
                logger.debug("dailyFilteredTimeResourceCheck : " + dailyFilteredTimeResourceCheck);
            }

        } catch (Exception e) {
            logger.error(getMessageSource().getMessage(
                    "[SecuredObject Service] SecuredObject Service [" + "Reload RestrictedTimes"
                            + "]: Fail to get SecuredObject Data from Database.",
                    new Object[] {}, Locale.getDefault()), e);
            if (e instanceof BaseException) {
                throw (BaseException) e;
            } else {
                throw new BaseException(getMessageSource(), "[SecuredObject Service] SecuredObject Service ["
                        + e.getMessage() + "]: Fail to get SecuredObject Data from Database.", new Object[] {}, e);
            }
        }

    }

    /**
     * Return matched Role if current request URL matches mapping information of
     * restricted times resource
     * 
     * @param map Map object that contains mapping information of restricted
     * times resource
     * @param url current request URL
     * @return null if url does not matches, List<ConfigAttribute> about
     * exclusion Role if URL matches
     */
    private List<ConfigAttribute> checkUrlMatching(Map map, String url) {
        Object p = map.get("compiledResourcePattern");
        boolean matched = urlMatcher.pathMatchesUrl(p, url);

        if (logger.isDebugEnabled()) {
            logger.debug("Restricted Times Candidate is: '" + url + "'; pattern is " + p + "; matched=" + matched);
        }

        if (matched) {
            return (List<ConfigAttribute>) map.get("unrestrictedRoleIds");
        }

        return null;
    }

    /**
     * Get ConfigAttribute about Restricted/Allowed role list that
     * matches current date/time from Role/Resource mapping information of
     * restricted times
     * 
     * @param compareCandidateList mapping information of restricted time - all
     * list if always checking mapping list about today date if dailyfiltered
     * checking
     * @param url request url
     * @param currentDateTime current date
     * @param currentTime current time
     * @param isTimeOnlyCheck true if only time checking
     * @param isRoleCheck (role or resource) true if role checking
     * @return List<ConfigAttribute> ConfigAttribute List
     */
    public List<ConfigAttribute> lookupRoleOrUrlInCandidateListCheck(List compareCandidateList, String url,
            DateTime currentDateTime, DateTime currentTime, boolean isTimeOnlyCheck, boolean isRoleCheck) {

        List candidateFoundCadList = new ArrayList();

        List<ConfigAttribute> foundCad = null;
        if (compareCandidateList == null) {
            if (logger.isDebugEnabled())
                logger.debug("compareCandidateList is null");
            return foundCad;
        }

        String beforeResourceId = null;
        String presentResourceId = null;

        Iterator iter = compareCandidateList.iterator();

        while (iter.hasNext()) {
            Map map = (Map) iter.next();

            String startDate = (String) map.get("start_date");
            String endDate = (String) map.get("end_date");

            String startTime = (String) map.get("start_time");
            String endTime = (String) map.get("end_time");

            DateTime startJodaTime = DateTimeFormat.forPattern("HHmmss").parseDateTime(startTime);
            DateTime endJodaTime = DateTimeFormat.forPattern("HHmmss").parseDateTime(endTime);

            DateTime startDateTime = null;
            DateTime endDateTime = null;

            boolean dailyExceed = false;
            boolean dailyExceedMatched = false;

            if (isTimeOnlyCheck) {
                if ("daily".equals((String) map.get("time_type"))) {
                    // daily ?  ??  
                    if (startJodaTime.isAfter(endJodaTime.getMillis())) {
                        dailyExceed = true;
                        // dailyExceed ?   ?  <= currentTime <=  ?
                        //   match ?
                        if (!((endJodaTime.isBefore(currentTime.getMillis())
                                || endJodaTime.isEqual(currentTime.getMillis()))
                                && (currentTime.isBefore(startJodaTime.getMillis())
                                        || currentTime.isEqual(startJodaTime.getMillis())))) {
                            dailyExceedMatched = true;
                        }
                    } else {
                        startDateTime = DateTimeFormat.forPattern("yyyyMMddHHmmss")
                                .parseDateTime(currentDateTime.toString("yyyyMMdd") + startTime);
                        endDateTime = DateTimeFormat.forPattern("yyyyMMddHHmmss")
                                .parseDateTime(currentDateTime.toString("yyyyMMdd") + endTime);
                    }
                } else {
                    // ??  always(crash) check ? ?  ?? /  ?
                    // ? ??.
                    startDateTime = DateTimeFormat.forPattern("yyyyMMddHHmmss")
                            .parseDateTime(RestrictedResourceHolder.RESTRICTED_MIN_DATE + startTime);
                    endDateTime = DateTimeFormat.forPattern("yyyyMMddHHmmss")
                            .parseDateTime(RestrictedResourceHolder.RESTRICTED_MAX_DATE + endTime);
                }
            } else { // daily filtered check ?   +?  ? ?
                startDateTime = DateTimeFormat.forPattern("yyyyMMddHHmmss").parseDateTime(startDate + startTime);
                endDateTime = DateTimeFormat.forPattern("yyyyMMddHHmmss").parseDateTime(endDate + endTime);
            }

            //  ? time_id ?  ??
            // dailyExceed ?  ? ? ? ?.
            if ((dailyExceed && dailyExceedMatched)
                    || (!dailyExceed && currentDateTime.isAfter(startDateTime.getMillis())
                            && endDateTime.isAfter(currentDateTime.getMillis()))) {

                presentResourceId = (String) map.get("resource_id");
                //  resource  ? ? ? ? resource ?  foundCad  
                // resource   ?   ? ? foundCad   ??
                if (!isRoleCheck && foundCad != null && beforeResourceId != null
                        && !presentResourceId.equals(beforeResourceId)) {

                    //   
                    if (candidateFoundCadList.size() > 1) {
                        return recalculateCandidate(isRoleCheck, candidateFoundCadList);
                    } else {
                        return foundCad;
                    }
                }

                foundCad = (isRoleCheck ? (List<ConfigAttribute>) map.get("restrictedRoleIds")
                        : checkUrlMatching(map, url));
                if (foundCad != null) {
                    // role check ?    ??  role ?  ? .

                    // resource check ?  ? resource ?    time_id ? 
                    //    ? 
                    //      

                    if (isRoleCheck || (beforeResourceId == null || presentResourceId.equals(beforeResourceId))) {
                        candidateFoundCadList.add(foundCad);
                    }
                }
            } else {
                // ? restricted data ? ?
                continue;
            }
        } // end while

        // best ? url ?  ? time_id ?     ?    -  
        //    
        if (candidateFoundCadList.size() > 0) {
            foundCad = recalculateCandidate(isRoleCheck, candidateFoundCadList);
        }

        if (logger.isDebugEnabled())
            logger.debug((isRoleCheck ? "Time Role Check" : "Time Resource Check") + " found ConfigAttribute : "
                    + foundCad);

        return foundCad;

    }

    /**
     * in case of roleCheck, return sum of restricted roles in case of
     * resourceCheck, return result of re-operation with Intersection of allowed
     * roles
     * 
     * @param isRoleCheck true if roleCheck
     * @param candidateFoundCadList list of candidate permissions that matches
     * the given time
     * @return List<ConfigAttribute> ConfigAttribute List
     */
    private List<ConfigAttribute> recalculateCandidate(boolean isRoleCheck, List candidateFoundCadList) {
        List<ConfigAttribute> foundCad = new ArrayList<ConfigAttribute>();
        List configList = null;
        List presentList = null;
        List nextList = null;
        for (int i = 0; i < candidateFoundCadList.size(); i++) {
            presentList = (List<ConfigAttribute>) candidateFoundCadList.get(i);
            if (i == 0) {
                configList = presentList;
            }
            if (i + 1 < candidateFoundCadList.size()) {
                nextList = (List<ConfigAttribute>) candidateFoundCadList.get(i + 1);
                // Role Check ?  restricted Role ? add .
                if (isRoleCheck) {
                    configList = ListUtils.sum(configList, nextList);
                } else { // Resource Check ?  unrestricted Role ?  
                    //  intersection 
                    configList = ListUtils.intersection(configList, nextList);
                }
            }
        }
        foundCad.addAll(configList);
        if (logger.isDebugEnabled())
            logger.debug("candidateFoundCadList : " + candidateFoundCadList
                    + (isRoleCheck ? ", summed List : " : ", intersected List : ") + foundCad);
        return foundCad;
    }

    /**
     * In case of FilterInvocation, compare current time with mapping
     * information of restricted times. in pair of
     * RestrictedTimesFilterSecurityInterceptor, it calls alwaysTimeRoleCheck,
     * dailyFilteredTimeRoleCheck, alwaysTimeResourceCheck and
     * dailyFilteredTimeResourceCheck sequentially.
     * 
     * @see anyframe.iam.core.intercept.web.RestrictedTimesFilterSecurityInterceptor#invoke(FilterInvocation)
     * @see org.springframework.security.intercept.ObjectDefinitionSource#getAttributes(java.lang.Object)
     */
    public List<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {

        if ((object == null) || !this.supports(object.getClass())) {
            throw new IllegalArgumentException("Object must be a FilterInvocation");
        }

        String url = ((FilterInvocation) object).getRequestUrl();

        // urlMatcher ?  queryString  
        if (stripQueryStringFromUrls) {
            int firstQuestionMarkIndex = url.indexOf("?");
            if (firstQuestionMarkIndex != -1) {
                url = url.substring(0, firstQuestionMarkIndex);
            }
        }

        // lowercase ? ? 
        if (urlMatcher.requiresLowerCaseUrl()) {
            url = url.toLowerCase();
        }

        //  ?
        DateTime currentDateTime = new DateTime();
        DateTime currentTime = DateTimeFormat.forPattern("HHmmss")
                .parseDateTime(currentDateTime.toString("HHmmss"));
        String currentDay = DateTimeFormat.forPattern("yyyyMMdd").print(currentDateTime);

        // alwaysTimeRoleCheck
        if (RestrictedResourceHolder.RESTRICTED_RESOURCE_TYPE[0]
                .equals(RestrictedResourceHolder.getPresentResource())) {
            return lookupRoleOrUrlInCandidateListCheck(alwaysTimeRoleCheck, url, currentDateTime, currentTime, true,
                    true);
        }

        // dailyFilteredTimeRoleCheck
        if (RestrictedResourceHolder.RESTRICTED_RESOURCE_TYPE[1]
                .equals(RestrictedResourceHolder.getPresentResource())) {
            List todayRoleList = (List) dailyFilteredTimeRoleCheck.get(currentDay);
            return lookupRoleOrUrlInCandidateListCheck(todayRoleList, url, currentDateTime, currentTime, false,
                    true);
        }

        // alwaysTimeResourceCheck
        if (RestrictedResourceHolder.RESTRICTED_RESOURCE_TYPE[2]
                .equals(RestrictedResourceHolder.getPresentResource())) {
            return lookupRoleOrUrlInCandidateListCheck(alwaysTimeResourceCheck, url, currentDateTime, currentTime,
                    true, false);
        }

        // dailyFilteredTimeResourceCheck
        if (RestrictedResourceHolder.RESTRICTED_RESOURCE_TYPE[3]
                .equals(RestrictedResourceHolder.getPresentResource())) {
            List todayUrlList = (List) dailyFilteredTimeResourceCheck.get(currentDay);
            return lookupRoleOrUrlInCandidateListCheck(todayUrlList, url, currentDateTime, currentTime, false,
                    false);
        }

        return null;
    }

    /**
     * Get the String Array of Days between startDate and endDate.
     * @param startDate
     * @param endDate
     * @return String Array. The Days between startDate and endDate. 
     */
    public String[] getBetweenDays(String startDate, String endDate) {
        List betweenDays = new ArrayList();

        DateTime tempDate = DateTimeFormat.forPattern("yyyyMMdd").parseDateTime(startDate);
        DateTime endJodaDate = DateTimeFormat.forPattern("yyyyMMdd").parseDateTime(endDate);

        betweenDays.add(DateTimeFormat.forPattern("yyyyMMdd").print(tempDate));
        while (tempDate.isBefore(endJodaDate.getMillis())) {
            tempDate = tempDate.plusDays(1);
            betweenDays.add(DateTimeFormat.forPattern("yyyyMMdd").print(tempDate));
        }

        return (String[]) betweenDays.toArray(new String[0]);
    }

    /**
     * validateConfigAttributes not supported
     */
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        // validateConfigAttributes ? ?
        return null;
    }

    /**
     * 
     */
    public boolean supports(Class clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }
}