001    /**
002     * Copyright 2010-2012 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.common.util;
017    
018    import java.util.ArrayList;
019    import java.util.Collections;
020    import java.util.List;
021    import java.util.regex.Matcher;
022    import java.util.regex.Pattern;
023    
024    import org.slf4j.Logger;
025    import org.slf4j.LoggerFactory;
026    
027    /**
028     * This class provides logic for filtering strings based on regular expressions.
029     */
030    public class StringFilter {
031    
032            private static final Logger logger = LoggerFactory.getLogger(StringFilter.class);
033    
034            /**
035             * List of include regular expressions.
036             */
037            List<String> includes;
038    
039            /**
040             * List of exclude regular expressions.
041             */
042            List<String> excludes;
043    
044            protected List<Pattern> includePatterns;
045            protected List<Pattern> excludePatterns;
046    
047            protected StringFilter(List<String> includes, List<String> excludes) {
048                    super();
049                    this.includes = includes;
050                    this.excludes = excludes;
051            }
052    
053            public static final StringFilter getInstance(List<String> includes, List<String> excludes) {
054                    StringFilter filter = new StringFilter(includes, excludes);
055                    filter.compilePatterns();
056                    return filter;
057            }
058    
059            /**
060             * Return true if the string should be included.
061             */
062            public boolean include(String s) {
063                    if (exclude(s)) {
064                            logger.debug("Excluding {}", s);
065                            return false;
066                    } else {
067                            return CollectionUtils.isEmpty(includePatterns) || isMatch(s, includePatterns);
068                    }
069            }
070    
071            /**
072             * Return true if the string should be excluded.
073             */
074            public boolean exclude(String s) {
075                    return !CollectionUtils.isEmpty(excludePatterns) && isMatch(s, excludePatterns);
076            }
077    
078            /**
079             * Return true if the string matches any of the patterns
080             */
081            protected boolean isMatch(String s, List<Pattern> patterns) {
082                    // Loop through the patterns looking for a match
083                    for (Pattern pattern : patterns) {
084                            Matcher matcher = pattern.matcher(s);
085                            // We found a match, return true
086                            if (matcher.matches()) {
087                                    return true;
088                            }
089                    }
090                    // We cycled through all of the patterns without finding a match
091                    return false;
092            }
093    
094            /**
095             * Compile the string patterns into Pattern objects
096             */
097            protected void compilePatterns() {
098                    this.includePatterns = getPatterns(includes);
099                    this.excludePatterns = getPatterns(excludes);
100            }
101    
102            /**
103             * Convert a {@code List<String>} into {@code List<Pattern>}
104             */
105            protected List<Pattern> getPatterns(List<String> patterns) {
106                    if (CollectionUtils.isEmpty(patterns)) {
107                            return Collections.<Pattern> emptyList();
108                    }
109                    List<Pattern> regexPatterns = new ArrayList<Pattern>();
110                    for (String pattern : patterns) {
111                            Pattern regexPattern = Pattern.compile(pattern);
112                            regexPatterns.add(regexPattern);
113                    }
114                    return regexPatterns;
115            }
116    }