org.sourcepit.common.utils.path.PathMatcher.java Source code

Java tutorial

Introduction

Here is the source code for org.sourcepit.common.utils.path.PathMatcher.java

Source

/*
 * Copyright 2014 Bernd Vogt and others.
 * 
 * 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.sourcepit.common.utils.path;

import java.io.File;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.commons.io.FilenameUtils;

public class PathMatcher {
    private static class PatternParser {
        private String patternString;
        private String patternSeparator;
        private String segmentSeparator;

        public void setPatternString(String patterns) {
            this.patternString = patterns;
        }

        public void setPatternSeparator(String pathSeparator) {
            this.patternSeparator = pathSeparator;
        }

        public void setSegmentSeparator(String segmentSeparator) {
            this.segmentSeparator = segmentSeparator;
        }

        public PathMatcher parse() {
            final Set<String> includes = new HashSet<String>();
            final Set<String> excludes = new HashSet<String>();
            if (patternString.length() != 0) {
                final String[] rawPatterns = split();
                for (String rawPattern : rawPatterns) {
                    rawPattern = rawPattern.trim();
                    final boolean isExclude = isExclude(rawPattern);
                    final Set<String> target = isExclude ? excludes : includes;
                    target.add(toSegmentRegex(prepareRawPattern(rawPattern, isExclude), segmentSeparator));
                }
            }
            return createMacher(includes, excludes);
        }

        protected boolean isExclude(String rawPattern) {
            return rawPattern.startsWith("!");
        }

        protected String[] split() {
            if (patternSeparator == null) {
                return new String[] { patternString };
            } else {
                return patternString.split(escRegEx(patternSeparator));
            }
        }

        protected String prepareRawPattern(String rawPattern, boolean isExclude) {
            if (isExclude) {
                rawPattern = rawPattern.length() > 1 ? rawPattern.substring(1) : "";
            }
            return rawPattern;
        }

        protected PathMatcher createMacher(final Set<String> includes, final Set<String> excludes) {
            return new PathMatcher(includes, excludes);
        }
    }

    private final Set<String> includes;
    private final Set<String> excludes;

    public PathMatcher(Set<String> includes, Set<String> excludes) {
        this.includes = includes;
        this.excludes = excludes;
    }

    public static PathMatcher parsePackagePatterns(String patterns) {
        final PatternParser parser = new PatternParser();
        parser.setPatternString(patterns);
        parser.setPatternSeparator(",");
        parser.setSegmentSeparator(".");
        return parser.parse();
    }

    public static PathMatcher parseFilePatterns(final File baseDir, String filePatterns) {
        final PatternParser parser = new PatternParser() {
            protected String prepareRawPattern(String rawPattern, boolean isExclude) {
                String result = super.prepareRawPattern(rawPattern, isExclude);
                if (!result.startsWith("**") && !new File(result).isAbsolute()) {
                    result = new File(baseDir, result).getAbsolutePath();
                }
                result = FilenameUtils.separatorsToUnix(result);
                return result;
            };

            @Override
            protected PathMatcher createMacher(Set<String> includes, Set<String> excludes) {
                return new PathMatcher(includes, excludes) {
                    @Override
                    public boolean isMatch(String path) {
                        return super.isMatch(FilenameUtils.separatorsToUnix(new File(path).getAbsolutePath()));
                    }
                };
            }
        };
        parser.setPatternString(FilenameUtils.separatorsToUnix(filePatterns));
        parser.setPatternSeparator(",");
        parser.setSegmentSeparator("/");
        return parser.parse();
    }

    public static PathMatcher parse(String patterns, String segmentSeparator, String patternSeparator) {
        final PatternParser parser = new PatternParser();
        parser.setPatternString(patterns);
        parser.setPatternSeparator(patternSeparator);
        parser.setSegmentSeparator(segmentSeparator);
        return parser.parse();
    }

    public Set<String> getExcludes() {
        return excludes;
    }

    public Set<String> getIncludes() {
        return includes;
    }

    public boolean isInclude(String path) {
        return isPatternMatch(includes, path, true);
    }

    public boolean isExclude(String path) {
        return isPatternMatch(excludes, path, false);
    }

    public boolean isMatch(String path) {
        return isInclude(path) && !isExclude(path);
    }

    private boolean isPatternMatch(Set<String> patterns, String path, boolean defaultValue) {
        if (patterns != null && !patterns.isEmpty()) {
            for (String exclude : patterns) {
                if (path.matches(exclude)) {
                    return true;
                }
            }
            return false;
        }
        return defaultValue;
    }

    public static String toSegmentRegex(String pattern, String separator) {
        final String segmentPattern = "[^" + escRegEx(separator) + "]*";
        final int segmentPatternLength = segmentPattern.length();
        final StringTokenizer t = new StringTokenizer(pattern, "\\*", true);
        final StringBuilder sb = new StringBuilder();
        boolean skip = false;
        while (t.hasMoreTokens()) {
            String token = t.nextToken();
            if ("*".equals(token)) {
                if (skip) {
                    sb.delete(sb.length() - segmentPatternLength, sb.length());
                    sb.append(".*");
                } else {
                    sb.append(segmentPattern);
                }
                skip = true;
            } else {
                sb.append(escRegEx(token));
                skip = false;
            }
        }
        return sb.toString();
    }

    public static String escRegEx(String inStr) {
        // will replace the char with \char
        return inStr.replaceAll("([\\\\*+\\[\\](){}\\$.?\\^|])", "\\\\$1");
    }
}