001package org.andromda.core.common;
002
003import java.util.regex.PatternSyntaxException;
004import org.apache.commons.lang.StringUtils;
005
006/**
007 * Provides wild card matching on file paths (i.e. Cartridge.java will match <code>*.java</code>, etc).
008 *
009 * @author Chad Brandon
010 */
011public class PathMatcher
012{
013    /**
014     * A forward slash.
015     */
016    private static final String FORWARD_SLASH = "/";
017
018    /**
019     * A double star within a pattern.
020     */
021    private static final String DOUBLE_STAR = "**/*";
022
023    /**
024     * A tripple star within a pattern.
025     */
026    private static final String TRIPPLE_STAR = "***";
027
028    /**
029     * Provides matching of simple wildcards. (i.e. '*.java' etc.)
030     *
031     * @param path the path to match against.
032     * @param pattern the pattern to check if the path matches.
033     * @return true if the <code>path</code> matches the given <code>pattern</code>, false otherwise.
034     */
035    public static boolean wildcardMatch(
036        String path,
037        String pattern)
038    {
039        ExceptionUtils.checkNull(
040            "path",
041            path);
042        ExceptionUtils.checkNull(
043            "pattern",
044            pattern);
045
046        // - remove any starting slashes, as they interfere with the matching
047        if (path.startsWith(FORWARD_SLASH))
048        {
049            path =
050                path.substring(
051                    1,
052                    path.length());
053        }
054        path = path.trim();
055        pattern = pattern.trim();
056        boolean matches;
057        pattern =
058            StringUtils.replace(
059                pattern,
060                ".",
061                "\\.");
062        boolean matchAll = pattern.contains(DOUBLE_STAR) && !pattern.contains(TRIPPLE_STAR);
063        if (matchAll)
064        {
065            String replacement = ".*";
066            if (!path.contains(FORWARD_SLASH))
067            {
068                replacement = ".*";
069            }
070            pattern =
071                StringUtils.replaceOnce(
072                    pattern,
073                    DOUBLE_STAR,
074                    replacement);
075        }
076        pattern =
077            StringUtils.replace(
078                pattern,
079                "*",
080                ".*");
081        try
082        {
083            matches = path.matches(pattern);
084        }
085        catch (final PatternSyntaxException exception)
086        {
087            matches = false;
088        }
089        if (!matchAll)
090        {
091            matches =
092                matches &&
093                StringUtils.countMatches(
094                    pattern,
095                    FORWARD_SLASH) == StringUtils.countMatches(
096                    path,
097                    FORWARD_SLASH);
098        }
099        return matches;
100    }
101}