blob: 6246e6016acd2a96e24db16cd6fd3d55fa96cca7 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.persistence.util;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* Utility class with static methods to create search pattern
*
* @author Phong Nguyen Le
* @since 1.0
*/
public class PatternConstructor {
private PatternConstructor() {
// don't instantiate
}
public static Pattern createPattern(String pattern,
boolean isCaseSensitive, boolean isRegex)
throws PatternSyntaxException {
return createPattern(pattern, isRegex, true, isCaseSensitive, false);
}
/**
* Creates a pattern element from the pattern string which is either a
* reg-ex expression or in our old 'StringMatcher' format.
*
* @param pattern
* The search pattern
* @param isRegex
* <code>true</code> if the passed string already is a reg-ex
* pattern
* @param isStringMatcher
* <code>true</code> if the passed string is in the
* StringMatcher format.
* @param isCaseSensitive
* Set to <code>true</code> to create a case insensitive
* pattern
* @param isWholeWord
* <code>true</code> to create a pattern that requires a word
* boundary at the beginning and the end.
* @return The created pattern
* @throws PatternSyntaxException
*/
public static Pattern createPattern(String pattern, boolean isRegex,
boolean isStringMatcher, boolean isCaseSensitive,
boolean isWholeWord) throws PatternSyntaxException {
if (isRegex) {
if (isWholeWord) {
StringBuffer buffer = new StringBuffer(pattern.length() + 10);
buffer.append("\\b(?:").append(pattern).append(")\\b"); //$NON-NLS-1$ //$NON-NLS-2$
pattern = buffer.toString();
}
} else {
int len = pattern.length();
StringBuffer buffer = new StringBuffer(len + 10);
// don't add a word boundary if the search text does not start with
// a word char. (this works around a user input error).
if (isWholeWord && len > 0 && isWordChar(pattern.charAt(0))) {
buffer.append("\\b"); //$NON-NLS-1$
}
appendAsRegEx(isStringMatcher, pattern, buffer);
if (isWholeWord && len > 0 && isWordChar(pattern.charAt(len - 1))) {
buffer.append("\\b"); //$NON-NLS-1$
}
pattern = buffer.toString();
}
int regexOptions = Pattern.MULTILINE;
if (!isCaseSensitive) {
regexOptions |= Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
}
return Pattern.compile(pattern, regexOptions);
}
private static boolean isWordChar(char c) {
return Character.isLetterOrDigit(c);
}
/**
* Creates a pattern element from an array of patterns in the old
* 'StringMatcher' format.
*
* @param patterns
* The search patterns
* @param isCaseSensitive
* Set to <code>true</code> to create a case insensitive
* pattern
* @return The created pattern
* @throws PatternSyntaxException
*/
public static Pattern createPattern(String[] patterns,
boolean isCaseSensitive) throws PatternSyntaxException {
StringBuffer pattern = new StringBuffer();
for (int i = 0; i < patterns.length; i++) {
if (i > 0) {
// note that this works only as we know that the operands of the
// or expression will be simple and need no brackets.
pattern.append('|');
}
appendAsRegEx(true, patterns[i], pattern);
}
return createPattern(pattern.toString(), true, true, isCaseSensitive,
false);
}
public static StringBuffer appendAsRegEx(boolean isStringMatcher,
String pattern, StringBuffer buffer) {
boolean isEscaped = false;
for (int i = 0; i < pattern.length(); i++) {
char c = pattern.charAt(i);
switch (c) {
// the backslash
case '\\':
// the backslash is escape char in string matcher
if (isStringMatcher && !isEscaped) {
isEscaped = true;
} else {
buffer.append("\\\\"); //$NON-NLS-1$
isEscaped = false;
}
break;
// characters that need to be escaped in the regex.
case '(':
case ')':
case '{':
case '}':
case '.':
case '[':
case ']':
case '$':
case '^':
case '+':
case '|':
if (isEscaped) {
buffer.append("\\\\"); //$NON-NLS-1$
isEscaped = false;
}
buffer.append('\\');
buffer.append(c);
break;
case '?':
if (isStringMatcher && !isEscaped) {
buffer.append('.');
} else {
buffer.append('\\');
buffer.append(c);
isEscaped = false;
}
break;
case '*':
if (isStringMatcher && !isEscaped) {
buffer.append(".*"); //$NON-NLS-1$
} else {
buffer.append('\\');
buffer.append(c);
isEscaped = false;
}
break;
default:
if (isEscaped) {
buffer.append("\\\\"); //$NON-NLS-1$
isEscaped = false;
}
buffer.append(c);
break;
}
}
if (isEscaped) {
buffer.append("\\\\"); //$NON-NLS-1$
isEscaped = false;
}
return buffer;
}
}