| /******************************************************************************* |
| * 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( '/' ) ); |
| } |
| } |