blob: 07e995b4a6f5008582907d1fd91e8c215f674eec [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2015 Sonatype, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
*******************************************************************************/
package org.eclipse.sisu.space;
import java.util.regex.Pattern;
/**
* Enumerates various optimized filename globbing strategies.
*/
enum GlobberStrategy
{
// ----------------------------------------------------------------------
// Enumerated values
// ----------------------------------------------------------------------
ANYTHING
{
@Override
final Object compile( final String glob )
{
return null;
}
@Override
final boolean matches( final Object globPattern, final String filename )
{
return true;
}
},
SUFFIX
{
@Override
final Object compile( final String glob )
{
return glob.substring( 1 ); // remove leading asterisk
}
@Override
final boolean matches( final Object globPattern, final String filename )
{
return filename.endsWith( (String) globPattern ); // no need for basename(...)
}
},
PREFIX
{
@Override
final Object compile( final String glob )
{
return glob.substring( 0, glob.length() - 1 ); // remove trailing asterisk
}
@Override
final boolean matches( final Object globPattern, final String filename )
{
return basename( filename ).startsWith( (String) globPattern );
}
},
EXACT
{
@Override
final Object compile( final String glob )
{
return glob;
}
@Override
final boolean matches( final Object globPattern, final String filename )
{
return globPattern.equals( basename( filename ) );
}
},
PATTERN
{
@Override
final Object compile( final String glob )
{
return Pattern.compile( "\\Q" + glob.replaceAll( "\\*+", "\\\\E.*\\\\Q" ) + "\\E" );
}
@Override
final boolean matches( final Object globPattern, final String filename )
{
return ( (Pattern) globPattern ).matcher( basename( filename ) ).matches();
}
};
// ----------------------------------------------------------------------
// Local methods
// ----------------------------------------------------------------------
/**
* Selects the optimal globber strategy for the given plain-text glob.
*
* @param glob The plain-text glob
* @return Optimal globber strategy
*/
static final GlobberStrategy selectFor( final String glob )
{
if ( null == glob || "*".equals( glob ) )
{
return GlobberStrategy.ANYTHING;
}
final int firstWildcard = glob.indexOf( '*' );
if ( firstWildcard < 0 )
{
return GlobberStrategy.EXACT;
}
final int lastWildcard = glob.lastIndexOf( '*' );
if ( firstWildcard == lastWildcard )
{
if ( firstWildcard == 0 )
{
return GlobberStrategy.SUFFIX;
}
if ( lastWildcard == glob.length() - 1 )
{
return GlobberStrategy.PREFIX;
}
}
return GlobberStrategy.PATTERN;
}
/**
* Compiles the given plain-text glob into an optimized pattern.
*
* @param glob The plain-text glob
* @return Compiled glob pattern
*/
abstract Object compile( final String glob );
/**
* Attempts to match the given compiled glob pattern against a filename.
*
* @param globPattern The compiled glob pattern
* @param filename The candidate filename
* @return {@code true} if the pattern matches; otherwise {@code false}
*/
abstract boolean matches( final Object globPattern, final String filename );
// ----------------------------------------------------------------------
// Implementation methods
// ----------------------------------------------------------------------
/**
* Extracts the basename segment from the given filename.
*
* @param filename The filename
* @return Basename segment
*/
static final String basename( final String filename )
{
return filename.substring( 1 + filename.lastIndexOf( '/' ) );
}
}