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;
}
}