/****************************************************************
* 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 org.apache.jsieve.comparators;
import org.apache.jsieve.*;
import org.apache.jsieve.exception.LookupException;
import org.apache.jsieve.exception.SieveException;
import org.apache.jsieve.exception.SievePatternException;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* Class ComparatorUtils implements utility methods used by Comparators.
*/
public class ComparatorUtils implements MatchTypeTags {
/**
* Constructor for ComparatorUtils.
*/
private ComparatorUtils() {
super();
}
/**
* Method <code>match</code> answers a boolean indicating if the parameter
* <code>matchTarget</code> compares to parameter
* <code>matchArgument</code> is a match of <code>matchType</code> using
* the comparator <code>comparatorName</code>.
*
* @param comparatorName
* @param matchType
* @param matchArgument
* @param matchTarget
* @return boolean
*/
public static boolean match(String comparatorName, String matchType,
String matchTarget, String matchArgument) throws SieveException {
boolean isMatched = false;
if (matchType.equals(IS_TAG))
isMatched = is(comparatorName, matchTarget, matchArgument);
else if (matchType.equals(CONTAINS_TAG))
isMatched = contains(comparatorName, matchTarget, matchArgument);
else if (matchType.equals(MATCHES_TAG))
isMatched = matches(comparatorName, matchTarget, matchArgument);
return isMatched;
}
/**
* <p>
* Method <code>matches</code> answers a boolean indicating if the
* parameter <code>string</code> matches the glob pattern described by
* parameter <code>glob</code>.
*
* @param string
* @param glob
* @return boolean
* @throws SievePatternException
*/
static public boolean matches(String string, String glob)
throws SievePatternException {
// TODO Is there a way to re-use the compiled pattern?
try {
String regex = sieveToJavaRegex(glob);
return Pattern.compile(regex).matcher(
string).matches();
} catch (PatternSyntaxException e) {
throw new SievePatternException(e.getMessage());
}
}
/**
* <p>
* Method <code>contains</code> answers a boolean indicating if the
* parameter <code>container</code> contains the parameter
* <code>contents</code>.
* </p>
*
* @param container
* @param contents
* @return boolean
*/
static public boolean contains(String container, String contents) {
return container.indexOf(contents) > -1;
}
/**
* <p>
* Method <code>equals</code> answers a boolean indicating if the
* parameter <code>string1</code> is equal to the parameter
* <code>string2</code>.
* </p>
*
* @param string1
* @param string2
* @return boolean
*/
static public boolean equals(String string1, String string2) {
return string1.equals(string2);
}
/**
* Returns true if the char is a special char for regex
*/
private static boolean isRegexSpecialChar(char ch) {
return (ch == '*' || ch == '?' || ch == '+' || ch == '[' || ch == ']'
|| ch == '(' || ch == ')' || ch == '|' || ch == '^'
|| ch == '$' || ch == '.' || ch == '{' || ch == '}' || ch == '\\');
}
/**
* Returns true if the char is a special char for sieve matching
*/
private static boolean isSieveMatcherSpecialChar(char ch) {
return (ch == '*' || ch == '?' || ch == '\\');
}
/**
* Converts a Sieve pattern in a java regex pattern
*/
public static String sieveToJavaRegex(String pattern) {
int ch;
StringBuffer buffer = new StringBuffer(2 * pattern.length());
for (ch = 0; ch < pattern.length(); ch++) {
switch (pattern.charAt(ch)) {
case '*':
buffer.append(".*");
break;
case '?':
buffer.append('.');
break;
case '\\':
buffer.append('\\');
if (ch == pattern.length() - 1)
buffer.append('\\');
else if (isSieveMatcherSpecialChar(pattern.charAt(ch + 1)))
buffer.append(pattern.charAt(++ch));
else
buffer.append('\\');
break;
default:
if (isRegexSpecialChar(pattern.charAt(ch)))
buffer.append('\\');
buffer.append(pattern.charAt(ch));
break;
}
}
return buffer.toString();
}
/**
* Method <code>contains<code> answers a boolean indicating if the parameter
* <code>container</code> contains the parameter <code>contents</code> using an
* instance of <code>comparatorName</code>.
* @param comparatorName
* @param container
* @param contents
* @return boolean
*/
public static boolean contains(String comparatorName, String container,
String contents) throws LookupException {
Contains comparatorObj = ComparatorManager.getInstance().newInstance(
comparatorName);
return comparatorObj.contains(container, contents);
}
/**
* Method <code>is<code> answers a boolean indicating if the parameter
* <code>container</code> is equal to the parameter <code>contents</code> using
* an instance of <code>comparatorName</code>.
* @param comparatorName
* @param string1
* @param string2
* @return boolean
*/
public static boolean is(String comparatorName, String string1,
String string2) throws LookupException {
Equals comparatorObj = ComparatorManager.getInstance().newInstance(
comparatorName);
return comparatorObj.equals(string1, string2);
}
/**
* Method <code>matches</code> answers a boolean indicating if the
* parameter
* <code>string/code> is matched by the patterm <code>glob</code> using an
* instance of <code>comparatorName</code>.
* @param comparatorName
* @param string
* @param glob
* @return boolean
*/
public static boolean matches(String comparatorName, String string,
String glob) throws SieveException {
Matches comparatorObj = ComparatorManager.getInstance().newInstance(
comparatorName);
return comparatorObj.matches(string, glob);
}
}