blob: 83bb499b3e177ddf47fbd5a228f3a05e372d6e58 [file] [log] [blame]
/*
JSPWiki - a JSP-based WikiWiki clone.
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
package com.ecyrd.jspwiki.util;
/**
* Copied code from the org.apache.oro.text.regex.GlobCompiler
* All credits to the author's
*/
public final class RegExpUtil
{
private RegExpUtil()
{
// private constructor prevents construction
}
/**
* The default mask . It is equal to 0
* The default behavior is for a glob expression to be case sensitive
* unless it is compiled with the CASE_INSENSITIVE_MASK option.
*/
public static final int DEFAULT_MASK = 0;
/**
* A mask passed as an option to
* indicate a compiled glob expression should be case insensitive.
*/
public static final int CASE_INSENSITIVE_MASK = 0x0001;
/**
* A mask to indicate that a * should not be allowed to match the null string.
* Thenormal behavior of the * metacharacter is that it may match any 0 or more
* characters. This mask causes it to match 1 or more characters of
* anything.
*/
public static final int STAR_CANNOT_MATCH_NULL_MASK = 0x0002;
/**
* A mask to indicate that a ? should not be allowed to match the null string.
* The normal behavior of the ? metacharacter is that it may match any 1
* character. This mask causes it to match 0 or 1 characters.
*/
public static final int QUESTION_MATCHES_ZERO_OR_ONE_MASK = 0x0004;
/**
* A mask to indicate that the resulting Perl5Pattern should be treated as a read only
* data structure by Perl5Matcher, making it safe to share a single
* Perl5Pattern instance among multiple threads without needing
* synchronization. Without this option, Perl5Matcher reserves the right to
* store heuristic or other information in Perl5Pattern that might
* accelerate future matches. When you use this option, Perl5Matcher will
* not store or modify any information in a Perl5Pattern. Use this option
* when you want to share a Perl5Pattern instance among multiple threads
* using different Perl5Matcher instances.
*/
public static final int READ_ONLY_MASK = 0x0008;
/**
* This static method is the basic engine of the Glob PatternCompiler
* implementation. It takes a glob expression in the form of a character
* array and converts it into a String representation of a Perl5 pattern.
* The method is made public so that programmers may use it for their own
* purposes. However, the GlobCompiler compile methods work by converting
* the glob pattern to a Perl5 pattern using this method, and then invoking
* the compile() method of an internally stored Perl5Compiler instance.
* <p>
*
* @param pattern A character array representation of a Glob pattern.
* @return A String representation of a Perl5 pattern equivalent to the Glob
* pattern.
*/
public static String globToPerl5( char[] pattern, int options )
{
boolean inCharSet = false;
boolean starCannotMatchNull = false;
boolean questionMatchesZero = false;
int ch;
StringBuffer buffer;
buffer = new StringBuffer( 2 * pattern.length );
inCharSet = false;
questionMatchesZero = (options & QUESTION_MATCHES_ZERO_OR_ONE_MASK) != 0;
starCannotMatchNull = (options & STAR_CANNOT_MATCH_NULL_MASK) != 0;
for( ch = 0; ch < pattern.length; ch++ )
{
switch( pattern[ch] )
{
case '*':
if( inCharSet )
buffer.append( '*' );
else
{
if( starCannotMatchNull )
buffer.append( ".+" );
else
buffer.append( ".*" );
}
break;
case '?':
if( inCharSet )
buffer.append( '?' );
else
{
if( questionMatchesZero )
buffer.append( ".?" );
else
buffer.append( '.' );
}
break;
case '[':
inCharSet = true;
buffer.append( pattern[ch] );
if( ch + 1 < pattern.length )
{
switch( pattern[ch + 1] )
{
case '!':
case '^':
buffer.append( '^' );
++ch;
continue;
case ']':
buffer.append( ']' );
++ch;
continue;
}
}
break;
case ']':
inCharSet = false;
buffer.append( pattern[ch] );
break;
case '\\':
buffer.append( '\\' );
if( ch == pattern.length - 1 )
{
buffer.append( '\\' );
}
else if( isGlobMetaCharacter( pattern[ch + 1] ) )
buffer.append( pattern[++ch] );
else
buffer.append( '\\' );
break;
default:
if( !inCharSet && isPerl5MetaCharacter( pattern[ch] ) )
buffer.append( '\\' );
buffer.append( pattern[ch] );
break;
}
}
return buffer.toString();
}
private static boolean isPerl5MetaCharacter( char ch )
{
return "'*?+[]()|^$.{}\\".indexOf( ch ) >= 0;
}
private static boolean isGlobMetaCharacter( char ch )
{
return "*?[]".indexOf( ch ) >= 0;
}
}