package javax.ide.extension.spi; /** * A simple glob pattern matcher. * * @since 2.0 */ public final class SimpleGlobMatcher { private final String _pattern; private final boolean _caseSensitive; /** * Constructs a simple case insensitive glob mapper for the specified * pattern. * * @param pattern a glob pattern. Must not be null. * @throws NullPointerException if pattern is null. */ public SimpleGlobMatcher( String pattern ) { this( pattern, false ); } /** * Constructs a simple glob mapper for the specified pattern. * * @param pattern a glob pattern. Must not be null. * @param caseSensitive if true, matching is case sensitive. Else * it is case insensitive. * @throws NullPointerException if pattern is null. */ public SimpleGlobMatcher( String pattern, boolean caseSensitive ) { if ( pattern == null ) throw new NullPointerException( "pattern is null" ); if ( caseSensitive ) _pattern = pattern; else _pattern = pattern.toLowerCase(); _caseSensitive = caseSensitive; } /** * Returns true if the pattern matches the specified String. * * @param target the target String. Must not be null. * @return true if the pattern matches the target, false * otherwise. * @throws NullPointerException if target is null. */ public boolean matches( String target ) { if ( target == null ) throw new NullPointerException( "target is null" ); return matchImpl( target, _pattern ); } private boolean matchImpl( String target, String pattern ) { if ( !_caseSensitive ) { target = target.toLowerCase(); } int ppos = 0; int tpos = 0; int tlen = target.length(); int plen = pattern.length(); while ( true ) { if ( tpos == tlen ) { // Reached the end of the target string without a mismatch. Still // we're mismatched if the pattern contains any more characters. return ppos == plen; } char pchar = pattern.charAt( ppos ); char pnext = nextChar( pattern, ppos, plen ); char tchar = target.charAt( tpos ); char tnext = nextChar( target, tpos, tlen ); if ( pchar == '*' ) { tpos++; // * matches any character, but look ahead to see if the next char of // the pattern and target match. Only advance tpos if so. if ( pnext != 0 && tnext != 0 && pnext == tnext ) { ppos++; } continue; } if ( pchar != tchar ) return false; tpos++; ppos++; } } private char nextChar(String string, int pos, int length) { return pos+1 < length ? string.charAt( pos + 1 ) : (char)0; } }