use of org.apache.jsieve.TagArgument in project zm-mailbox by Zimbra.
the class SieveVisitor method acceptTest.
private void acceptTest(Node node, RuleProperties props) throws ServiceException {
visitTest(node, VisitPhase.begin, props);
String nodeName = getNodeName(node);
if ("not".equalsIgnoreCase(nodeName)) {
props.isNegativeTest = true;
accept(node, props);
} else {
if ("allof".equalsIgnoreCase(nodeName)) {
props.condition = Sieve.Condition.allof;
visitRule(node, VisitPhase.begin, props);
accept(node, props);
visitRule(node, VisitPhase.end, props);
} else if ("anyof".equalsIgnoreCase(nodeName)) {
props.condition = Sieve.Condition.anyof;
visitRule(node, VisitPhase.begin, props);
accept(node, props);
visitRule(node, VisitPhase.end, props);
} else if ("header".equalsIgnoreCase(nodeName) || "mime_header".equalsIgnoreCase(nodeName)) {
boolean caseSensitive = false;
List<String> headers;
String value;
Sieve.ValueComparison valueComparison = null;
boolean isCount = false;
Sieve.StringComparison comparison = null;
Sieve.Comparator comparator = null;
int headersArgIndex = 0;
// There can be up to two tag arguments
SieveNode firstTagArgNode, secondTagArgNode;
firstTagArgNode = (SieveNode) getNode(node, 0, 0);
if (firstTagArgNode.getValue() instanceof TagArgument) {
String argStr = stripLeadingColon(firstTagArgNode.getValue().toString());
try {
if ("count".equals(argStr) || "value".equals(argStr)) {
if ("count".equals(argStr)) {
isCount = true;
}
valueComparison = Sieve.ValueComparison.valueOf(getValue(node, 0, 1, 0, 0));
headersArgIndex += 2;
secondTagArgNode = (SieveNode) getNode(node, 0, 2);
if (secondTagArgNode.getValue() instanceof TagArgument) {
comparator = Sieve.Comparator.fromString(getValue(node, 0, 3, 0, 0));
headersArgIndex += 2;
}
} else {
// assume that the first tag arg is match-type arg
comparison = Sieve.StringComparison.valueOf(argStr);
headersArgIndex++;
secondTagArgNode = (SieveNode) getNode(node, 0, 1);
if (secondTagArgNode.getValue() instanceof TagArgument) {
caseSensitive = Sieve.Comparator.ioctet == Sieve.Comparator.fromString(getValue(node, 0, 2, 0, 0));
headersArgIndex += 2;
}
}
} catch (IllegalArgumentException e) {
// so the first tag arg is not match-type arg, it must be :comparator arg then
caseSensitive = Sieve.Comparator.ioctet == Sieve.Comparator.fromString(getValue(node, 0, 1, 0, 0));
headersArgIndex += 2;
secondTagArgNode = (SieveNode) getNode(node, 0, 2);
if (secondTagArgNode.getValue() instanceof TagArgument) {
argStr = stripLeadingColon(secondTagArgNode.getValue().toString());
comparison = Sieve.StringComparison.fromString(argStr);
headersArgIndex++;
}
}
}
headers = getMultiValue(node, 0, headersArgIndex, 0);
value = getValue(node, 0, headersArgIndex + 1, 0, 0);
validateCountComparator(isCount, comparator);
if ("header".equalsIgnoreCase(nodeName)) {
if (valueComparison != null) {
visitHeaderTest(node, VisitPhase.begin, props, headers, valueComparison, isCount, value);
accept(node, props);
visitHeaderTest(node, VisitPhase.end, props, headers, valueComparison, isCount, value);
} else {
visitHeaderTest(node, VisitPhase.begin, props, headers, comparison, caseSensitive, value);
accept(node, props);
visitHeaderTest(node, VisitPhase.end, props, headers, comparison, caseSensitive, value);
}
} else {
visitMimeHeaderTest(node, VisitPhase.begin, props, headers, comparison, caseSensitive, value);
accept(node, props);
visitMimeHeaderTest(node, VisitPhase.end, props, headers, comparison, caseSensitive, value);
}
} else if ("address".equalsIgnoreCase(nodeName) || "envelope".equalsIgnoreCase(nodeName)) {
Sieve.AddressPart part = Sieve.AddressPart.all;
Sieve.StringComparison comparison = Sieve.StringComparison.is;
boolean caseSensitive = false;
List<String> headers;
String value;
int nextArgIndex = 0;
boolean isCount = false;
Sieve.ValueComparison valueComparison = null;
Sieve.Comparator comparator = null;
SieveNode firstTagArgNode;
firstTagArgNode = (SieveNode) getNode(node, 0, 0);
if (firstTagArgNode.getValue() instanceof TagArgument) {
String firstArgStr = firstTagArgNode.getValue().toString();
if (":count".equals(firstArgStr) || ":value".equals(firstArgStr)) {
if (":count".equals(firstArgStr)) {
isCount = true;
}
valueComparison = Sieve.ValueComparison.valueOf(getValue(node, 0, 1, 0, 0));
nextArgIndex += 2;
}
}
SieveNode argNode = (SieveNode) getNode(node, 0, nextArgIndex);
// There can be up to three tag arguments
for (int i = 0; i < 3 && argNode.getValue() instanceof TagArgument; i++) {
TagArgument tagArg = (TagArgument) argNode.getValue();
if (tagArg.isComparator()) {
comparator = Sieve.Comparator.fromString(getValue(node, 0, nextArgIndex + 1, 0, 0));
caseSensitive = Sieve.Comparator.ioctet == comparator;
nextArgIndex += 2;
} else {
String argStr = stripLeadingColon(argNode.getValue().toString());
try {
// first assume that the next tag arg is match-type arg
comparison = Sieve.StringComparison.valueOf(argStr);
} catch (IllegalArgumentException e) {
// so the next tag arg is not match-type arg, it must be address-part arg then
part = Sieve.AddressPart.fromString(argStr);
}
nextArgIndex++;
}
argNode = (SieveNode) getNode(node, 0, nextArgIndex);
}
headers = getMultiValue(node, 0, nextArgIndex, 0);
value = getValue(node, 0, nextArgIndex + 1, 0, 0);
validateCountComparator(isCount, comparator);
if ("envelope".equalsIgnoreCase(nodeName)) {
if (valueComparison != null) {
visitEnvelopeTest(node, VisitPhase.begin, props, headers, part, valueComparison, isCount, value);
accept(node, props);
visitEnvelopeTest(node, VisitPhase.end, props, headers, part, valueComparison, isCount, value);
} else {
visitEnvelopeTest(node, VisitPhase.begin, props, headers, part, comparison, caseSensitive, value);
accept(node, props);
visitEnvelopeTest(node, VisitPhase.end, props, headers, part, comparison, caseSensitive, value);
}
} else {
if (valueComparison != null) {
visitAddressTest(node, VisitPhase.begin, props, headers, part, valueComparison, isCount, value);
accept(node, props);
visitAddressTest(node, VisitPhase.end, props, headers, part, valueComparison, isCount, value);
} else {
visitAddressTest(node, VisitPhase.begin, props, headers, part, comparison, caseSensitive, value);
accept(node, props);
visitAddressTest(node, VisitPhase.end, props, headers, part, comparison, caseSensitive, value);
}
}
} else if ("exists".equalsIgnoreCase(nodeName)) {
String header = getValue(node, 0, 0, 0, 0);
visitHeaderExistsTest(node, VisitPhase.begin, props, header);
accept(node, props);
visitHeaderExistsTest(node, VisitPhase.end, props, header);
} else if ("size".equalsIgnoreCase(nodeName)) {
String s = stripLeadingColon(getValue(node, 0, 0));
Sieve.NumberComparison comparison = Sieve.NumberComparison.fromString(s);
SieveNode sizeNode = (SieveNode) getNode(node, 0, 1);
String sizeString = sizeNode.getFirstToken().toString();
int size;
try {
size = FilterUtil.parseSize(sizeString);
} catch (NumberFormatException e) {
throw ServiceException.INVALID_REQUEST("Invalid size value " + sizeString, e);
}
visitSizeTest(node, VisitPhase.begin, props, comparison, size, sizeString);
accept(node, props);
visitSizeTest(node, VisitPhase.end, props, comparison, size, sizeString);
} else if ("date".equalsIgnoreCase(nodeName)) {
String s = stripLeadingColon(getValue(node, 0, 0));
Sieve.DateComparison comparison = Sieve.DateComparison.fromString(s);
String dateString = getValue(node, 0, 1, 0, 0);
Date date = Sieve.DATE_PARSER.parse(dateString);
if (date == null) {
throw ServiceException.PARSE_ERROR("Invalid date value: " + dateString, null);
}
visitDateTest(node, VisitPhase.begin, props, comparison, date);
accept(node, props);
visitDateTest(node, VisitPhase.end, props, comparison, date);
} else if ("body".equalsIgnoreCase(nodeName)) {
boolean caseSensitive = false;
String value;
if (getNode(node, 0, 1).jjtGetNumChildren() == 0) {
// must be :comparator
if (!":comparator".equals(getValue(node, 0, 1)))
throw ServiceException.PARSE_ERROR("Expected :comparator argument", null);
caseSensitive = Sieve.Comparator.ioctet == Sieve.Comparator.fromString(getValue(node, 0, 2, 0, 0));
value = getValue(node, 0, 3, 0, 0);
} else {
value = getValue(node, 0, 1, 0, 0);
}
visitBodyTest(node, VisitPhase.begin, props, caseSensitive, value);
accept(node, props);
visitBodyTest(node, VisitPhase.end, props, caseSensitive, value);
} else if ("attachment".equalsIgnoreCase(nodeName)) {
visitAttachmentTest(node, VisitPhase.begin, props);
accept(node, props);
visitAttachmentTest(node, VisitPhase.end, props);
} else if ("addressbook".equalsIgnoreCase(nodeName)) {
StringBuilder format = new StringBuilder();
Node argNode = getNode(node, 0, 1, 0);
int argNodeLen = argNode.jjtGetNumChildren();
for (int i = 0; i < argNodeLen; i++) {
if (i > 0) {
format.append(",");
}
format.append(getValue(argNode, i));
}
String header = format.toString();
visitAddressBookTest(node, VisitPhase.begin, props, header);
accept(node, props);
visitAddressBookTest(node, VisitPhase.end, props, header);
} else if ("contact_ranking".equalsIgnoreCase(nodeName)) {
String header = getValue(node, 0, 1, 0, 0);
visitContactRankingTest(node, VisitPhase.begin, props, header);
accept(node, props);
visitContactRankingTest(node, VisitPhase.end, props, header);
} else if ("me".equalsIgnoreCase(nodeName)) {
String header = getValue(node, 0, 1, 0, 0);
visitMeTest(node, VisitPhase.begin, props, header);
accept(node, props);
visitMeTest(node, VisitPhase.end, props, header);
} else if ("invite".equalsIgnoreCase(nodeName)) {
List<String> methods = Collections.emptyList();
if (getNode(node, 0).jjtGetNumChildren() > 0) {
// Arguments node has children.
methods = getMultiValue(node, 0, 1, 0);
}
visitInviteTest(node, VisitPhase.begin, props, methods);
accept(node, props);
visitInviteTest(node, VisitPhase.end, props, methods);
} else if ("current_time".equalsIgnoreCase(nodeName)) {
String s = stripLeadingColon(getValue(node, 0, 0));
Sieve.DateComparison comparison = Sieve.DateComparison.fromString(s);
String timeString = getValue(node, 0, 1, 0, 0);
visitCurrentTimeTest(node, VisitPhase.begin, props, comparison, timeString);
accept(node, props);
visitCurrentTimeTest(node, VisitPhase.end, props, comparison, timeString);
} else if ("current_day_of_week".equalsIgnoreCase(nodeName)) {
List<String> days = getMultiValue(node, 0, 1, 0);
visitCurrentDayOfWeekTest(node, VisitPhase.begin, props, days);
accept(node, props);
visitCurrentDayOfWeekTest(node, VisitPhase.end, props, days);
} else if ("conversation".equalsIgnoreCase(nodeName)) {
String where = getValue(node, 0, 1, 0, 0);
visitConversationTest(node, VisitPhase.begin, props, where);
accept(node, props);
visitConversationTest(node, VisitPhase.end, props, where);
} else if ("facebook".equalsIgnoreCase(nodeName)) {
visitFacebookTest(node, VisitPhase.begin, props);
accept(node, props);
visitFacebookTest(node, VisitPhase.end, props);
} else if ("linkedin".equalsIgnoreCase(nodeName)) {
visitLinkedInTest(node, VisitPhase.begin, props);
accept(node, props);
visitLinkedInTest(node, VisitPhase.end, props);
} else if ("socialcast".equalsIgnoreCase(nodeName)) {
visitSocialcastTest(node, VisitPhase.begin, props);
accept(node, props);
visitSocialcastTest(node, VisitPhase.end, props);
} else if ("twitter".equalsIgnoreCase(nodeName)) {
visitTwitterTest(node, VisitPhase.begin, props);
accept(node, props);
visitTwitterTest(node, VisitPhase.end, props);
} else if ("list".equalsIgnoreCase(nodeName)) {
visitListTest(node, VisitPhase.begin, props);
accept(node, props);
visitListTest(node, VisitPhase.end, props);
} else if ("bulk".equalsIgnoreCase(nodeName)) {
visitBulkTest(node, VisitPhase.begin, props);
accept(node, props);
visitBulkTest(node, VisitPhase.end, props);
} else if ("importance".equalsIgnoreCase(nodeName)) {
FilterTest.Importance importance = FilterTest.Importance.fromString(getValue(node, 0, 0, 0, 0));
visitImportanceTest(node, VisitPhase.begin, props, importance);
accept(node, props);
visitImportanceTest(node, VisitPhase.end, props, importance);
} else if ("flagged".equalsIgnoreCase(nodeName)) {
Sieve.Flag flag = Sieve.Flag.fromString(getValue(node, 0, 0, 0, 0));
visitFlaggedTest(node, VisitPhase.begin, props, flag);
accept(node, props);
visitFlaggedTest(node, VisitPhase.end, props, flag);
} else if ("true".equalsIgnoreCase(nodeName)) {
visitTrueTest(node, VisitPhase.begin, props);
accept(node, props);
visitTrueTest(node, VisitPhase.end, props);
} else if ("community_requests".equalsIgnoreCase(nodeName)) {
visitCommunityRequestsTest(node, VisitPhase.begin, props);
accept(node, props);
visitCommunityRequestsTest(node, VisitPhase.end, props);
} else if ("community_content".equalsIgnoreCase(nodeName)) {
visitCommunityContentTest(node, VisitPhase.begin, props);
accept(node, props);
visitCommunityContentTest(node, VisitPhase.end, props);
} else if ("community_connections".equalsIgnoreCase(nodeName)) {
visitCommunityConnectionsTest(node, VisitPhase.begin, props);
accept(node, props);
visitCommunityConnectionsTest(node, VisitPhase.end, props);
} else {
ZimbraLog.filter.debug("Ignoring unrecognized test type '%s'.", nodeName);
accept(node, props);
}
// Done processing the current test. Reset the negative test flag for
// the next test (bug 46007).
props.isNegativeTest = false;
}
visitTest(node, VisitPhase.end, props);
}
use of org.apache.jsieve.TagArgument in project zm-mailbox by Zimbra.
the class NotifyMethodCapabilityTest method executeBasic.
@Override
protected boolean executeBasic(MailAdapter mail, Arguments arguments, SieveContext context) throws SieveException {
String comparator = ASCII_CASEMAP_COMPARATOR;
String matchType = IS_TAG;
String uri = null;
String capability = null;
List<String> keys = null;
ListIterator<Argument> argumentsIter = arguments.getArgumentList().listIterator();
boolean stop = false;
/*
* Test notify_method_capability
* Usage: notify_method_capability [COMPARATOR] [MATCH-TYPE]
* <notification-uri: string>
* <notification-capability: string>
* <key-list: string-list>
*/
while (!stop && argumentsIter.hasNext()) {
Argument argument = argumentsIter.next();
if (argument instanceof TagArgument) {
final String tag = ((TagArgument) argument).getTag();
if (comparator == null && COMPARATOR_TAG.equalsIgnoreCase(tag)) {
// The next argument must be a stringlist
if (argumentsIter.hasNext()) {
argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> stringList = ((StringListArgument) argument).getList();
if (stringList.size() != 1) {
throw context.getCoordinate().syntaxException("Expecting exactly one String");
}
comparator = stringList.get(0);
} else {
throw context.getCoordinate().syntaxException("Expecting a StringList");
}
}
} else // [MATCH-TYPE]?
if (matchType == null && (IS_TAG.equalsIgnoreCase(tag) || CONTAINS_TAG.equalsIgnoreCase(tag) || MATCHES_TAG.equalsIgnoreCase(tag) || COUNT_TAG.equalsIgnoreCase(tag) || VALUE_TAG.equalsIgnoreCase(tag))) {
matchType = tag;
} else {
throw context.getCoordinate().syntaxException("Found unexpected TagArgument: \"" + tag + "\"");
}
} else {
// Stop when a non-tag argument is encountered
argumentsIter.previous();
stop = true;
}
}
// The next argument MUST be a string of notification-uri
if (argumentsIter.hasNext()) {
final Argument argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
uri = ((StringListArgument) argument).getList().get(0);
}
}
if (null == uri) {
throw context.getCoordinate().syntaxException("Expecting a String of uri");
}
// The next argument MUST be a string of notification-capability
if (argumentsIter.hasNext()) {
final Argument argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
capability = ((StringListArgument) argument).getList().get(0);
}
}
if (null == capability) {
throw context.getCoordinate().syntaxException("Expecting a String of capability");
}
// The next argument MUST be a string-list of keys
if (argumentsIter.hasNext()) {
final Argument argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
keys = ((StringListArgument) argument).getList();
}
}
if (null == keys) {
throw context.getCoordinate().syntaxException("Expecting a StringList of keys");
} else {
for (String key : keys) {
if (!CAPABILITY_YES.equalsIgnoreCase(key) && !CAPABILITY_NO.equalsIgnoreCase(key) && !CAPABILITY_MAYBE.equalsIgnoreCase(key)) {
throw context.getCoordinate().syntaxException("Invalid key value: [" + key + "]");
}
}
}
if (argumentsIter.hasNext()) {
throw context.getCoordinate().syntaxException("Found unexpected arguments");
}
return test(comparator, matchType, uri, capability, keys);
}
use of org.apache.jsieve.TagArgument in project zm-mailbox by Zimbra.
the class SetVariable method validateArguments.
@Override
protected void validateArguments(Arguments arguments, SieveContext context) throws SieveException {
List<Argument> args = arguments.getArgumentList();
// RFC 5229
// ":lower" / ":upper" / ":lowerfirst" / ":upperfirst" /
// ":quotewildcard" / ":length"
// set "name" "Ethelbert"
// set "a" "juMBlEd lETteRS"; => "juMBlEd lETteRS"
// set :length "b" "${a}"; => "15"
// set :lower "b" "${a}"; => "jumbled letters"
// set :upperfirst "b" "${a}"; => "JuMBlEd lETteRS"
// set :upperfirst :lower "b" "${a}"; => "Jumbled letters"
// set :quotewildcard "b" "Rock*"; => "Rock\*"
// RFC 5435
// ":encodeurl"
// set :encodeurl "body_param" "Safe body&evil=evilbody"; => "safe+body%26evil%3Devilbody"
int varArgCount = 0;
String key = null;
String[] operations = new String[OPERATIONS_IDX];
if (args.size() >= 2) {
for (Argument arg : arguments.getArgumentList()) {
if (arg instanceof TagArgument) {
TagArgument tag = (TagArgument) arg;
String tagValue = tag.getTag();
if (!isValidModifier(tagValue)) {
throw new SyntaxException("Invalid variable modifier:" + tagValue);
} else {
int index = getIndex(tagValue);
if (StringUtil.isNullOrEmpty(operations[index])) {
operations[index] = tagValue.toLowerCase();
} else {
throw new SyntaxException("Cannot use two or more modifiers of the same" + " precedence in a single \"set\" action. Modifiers used: " + tagValue + " and " + operations[index]);
}
}
} else {
String argument = ((StringListArgument) arg).getList().get(0);
ZimbraLog.filter.debug("set variable argument: " + argument);
if (varArgCount == 0) {
key = argument;
}
++varArgCount;
}
}
if (varArgCount != 2) {
throw new SyntaxException("Exactly 2 arguments permitted. Found " + varArgCount);
} else {
if (!(isValidIdentifier(key))) {
throw new SyntaxException("Variable identifier is invalid, got identifier " + key);
}
}
} else {
throw new SyntaxException("Minimum 2 arguments are needed. Usage: set :upperfirst \"b\" \"hello\";. Arguments found: " + arguments);
}
}
use of org.apache.jsieve.TagArgument in project zm-mailbox by Zimbra.
the class StringTest method executeBasic.
/*
* (non-Javadoc)
*
* @see
* org.apache.jsieve.tests.AbstractTest#executeBasic(org.apache.jsieve.mail.
* MailAdapter, org.apache.jsieve.Arguments, org.apache.jsieve.SieveContext)
*/
@Override
protected boolean executeBasic(MailAdapter mail, Arguments arguments, SieveContext context) throws SieveException {
if (mail instanceof DummyMailAdapter) {
return true;
}
if (!(mail instanceof ZimbraMailAdapter)) {
return false;
}
ZimbraMailAdapter mailAdapter = (ZimbraMailAdapter) mail;
String matchType = null;
String comparator = null;
String operator = null;
List<String> sourceValues = null;
List<String> keyValues = null;
boolean nextArgumentIsRelationalSign = false;
ListIterator<Argument> argumentsIter = arguments.getArgumentList().listIterator();
boolean stop = false;
// <source: string-list> <key-list: string-list>
while (!stop && argumentsIter.hasNext()) {
Argument argument = argumentsIter.next();
if (argument instanceof TagArgument) {
final String tag = ((TagArgument) argument).getTag();
// [COMPARATOR]?
if (comparator == null && COMPARATOR_TAG.equalsIgnoreCase(tag)) {
// The next argument must be a stringlist
if (argumentsIter.hasNext()) {
argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> stringList = ((StringListArgument) argument).getList();
if (stringList.size() != 1) {
throw context.getCoordinate().syntaxException("Expecting exactly one String");
}
comparator = stringList.get(0);
} else {
throw context.getCoordinate().syntaxException("Expecting a StringList");
}
}
} else // [MATCH-TYPE]?
if (matchType == null && (IS_TAG.equalsIgnoreCase(tag) || CONTAINS_TAG.equalsIgnoreCase(tag) || MATCHES_TAG.equalsIgnoreCase(tag) || COUNT_TAG.equalsIgnoreCase(tag) || VALUE_TAG.equalsIgnoreCase(tag))) {
matchType = tag;
nextArgumentIsRelationalSign = true;
} else {
throw context.getCoordinate().syntaxException("Found unexpected TagArgument: \"" + tag + "\"");
}
} else {
if (nextArgumentIsRelationalSign && argument instanceof StringListArgument) {
String symbol = ((StringListArgument) argument).getList().get(0);
if (matchType != null && (GT_OP.equalsIgnoreCase(symbol) || GE_OP.equalsIgnoreCase(symbol) || LT_OP.equalsIgnoreCase(symbol) || LE_OP.equalsIgnoreCase(symbol) || EQ_OP.equalsIgnoreCase(symbol) || NE_OP.equalsIgnoreCase(symbol))) {
operator = symbol;
} else {
argumentsIter.previous();
stop = true;
}
nextArgumentIsRelationalSign = false;
} else {
// Stop when a non-tag argument is encountered
argumentsIter.previous();
stop = true;
}
}
}
// The next argument MUST be a string-list of header names
if (argumentsIter.hasNext()) {
final Argument argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> sourceStringList = ((StringListArgument) argument).getList();
if (null == sourceStringList || 0 == sourceStringList.size()) {
throw context.getCoordinate().syntaxException("Expecting a StringListof header names");
}
sourceValues = new ArrayList<String>();
for (String source : sourceStringList) {
sourceValues.add(FilterUtil.replaceVariables(mailAdapter, source));
}
}
}
// The next argument MUST be a string-list of keys
if (argumentsIter.hasNext()) {
final Argument argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> keyStringList = ((StringListArgument) argument).getList();
if (null == keyStringList || 0 == keyStringList.size()) {
throw context.getCoordinate().syntaxException("Expecting a StringList of keys");
}
keyValues = new ArrayList<String>();
for (String key : keyStringList) {
keyValues.add(FilterUtil.replaceVariables(mailAdapter, key));
}
}
}
if (argumentsIter.hasNext()) {
throw context.getCoordinate().syntaxException("Found unexpected arguments");
}
if (null == matchType) {
matchType = IS_TAG;
}
if (null == comparator) {
if (matchType.equalsIgnoreCase(VALUE_TAG) || matchType.equalsIgnoreCase(COUNT_TAG)) {
comparator = ASCII_NUMERIC_COMPARATOR;
} else {
comparator = ASCII_CASEMAP_COMPARATOR;
}
}
boolean result = match(mail, comparator, matchType, operator, sourceValues, keyValues, context);
if (result) {
if (matchType.equals(MatchTypeTags.MATCHES_TAG)) {
try {
HeaderTest.evaluateVarExp(mailAdapter, sourceValues, HeaderTest.SourceType.LITERAL, keyValues);
} catch (MessagingException e) {
throw new SieveException("Exception occured while evaluating variable expression.", e);
}
}
}
return result;
}
use of org.apache.jsieve.TagArgument in project zm-mailbox by Zimbra.
the class NotifyMailto method execute.
/**
* Execute RFC Compliant notify
* @param mail The ZimbraMailAdapter
* @param arguments The Sieve Arguments
* @param context The Sieve Context
* @throws SyntaxException
*/
private Object execute(MailAdapter mail, Arguments arguments, SieveContext context) throws SyntaxException {
if (!(mail instanceof ZimbraMailAdapter)) {
return null;
}
ZimbraMailAdapter mailAdapter = (ZimbraMailAdapter) mail;
/*
* RFC 5435 3.1. Notify Action
* usage: notify [":from" string]
* [":importance" <"1" / "2" / "3">]
* [":options" string-list]
* [":message" string]
* <method: string>
*/
String from = null;
int importance = 0;
String message = null;
String method = null;
String mailto = null;
Map<String, String> options = null;
Map<String, List<String>> mailtoParams = null;
ListIterator<Argument> argumentsIter = arguments.getArgumentList().listIterator();
boolean stop = false;
// Tag processing
while (!stop && argumentsIter.hasNext()) {
Argument argument = argumentsIter.next();
if (argument instanceof TagArgument) {
final String tag = ((TagArgument) argument).getTag();
if (from == null && NOTIFY_FROM.equals(tag)) {
// The next argument must be a string
if (argumentsIter.hasNext()) {
argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> stringList = ((StringListArgument) argument).getList();
if (stringList.size() != 1) {
throw new SyntaxException("Expecting exactly one String for " + NOTIFY_FROM);
}
String email = FilterUtil.replaceVariables(mailAdapter, (String) stringList.get(0));
// Validate email address using javax.mail.internet.InternetAddress
try {
InternetAddress addr = new InternetAddress(email);
addr.validate();
from = email;
} catch (AddressException ex) {
// if the :from addr is not valid, the FilterUtil.notifyMailto() method takes
// care of the From header before composing the notification message.
ZimbraLog.filter.info("The value of the \":from\" [" + email + "] is not valid");
}
} else {
throw new SyntaxException("Expecting a StringList for " + NOTIFY_FROM);
}
} else {
throw new SyntaxException("Expecting a parameter for " + NOTIFY_FROM);
}
} else if (importance == 0 && NOTIFY_IMPORTANCE.equals(tag)) {
// The next argument must be a number
if (argumentsIter.hasNext()) {
argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> stringList = ((StringListArgument) argument).getList();
if (stringList.size() != 1) {
throw new SyntaxException("Expecting exactly one String for " + NOTIFY_IMPORTANCE);
}
String strImportance = (String) stringList.get(0);
FilterUtil.replaceVariables(mailAdapter, strImportance);
importance = Integer.parseInt(strImportance);
if (!(importance == 1 || importance == 2 || importance == 3)) {
throw new SyntaxException("Expecting an integer number (1, 2, 3) for " + NOTIFY_IMPORTANCE);
}
} else {
throw new SyntaxException("Expecting a StringList for " + NOTIFY_IMPORTANCE);
}
} else {
throw new SyntaxException("Expecting a parameter for " + NOTIFY_IMPORTANCE);
}
} else if (options == null && NOTIFY_OPTIONS.equals(tag)) {
// The next argument must be a string-list of options "<optionname>=<value>[,<optionname>=<value]*"
if (argumentsIter.hasNext()) {
argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> listOptions = ((StringListArgument) argument).getList();
if (listOptions.size() == 0) {
throw new SyntaxException("Expecting exactly one String for " + NOTIFY_OPTIONS);
}
options = new HashMap<String, String>();
for (String option : listOptions) {
String[] token = option.split("=");
String key = null;
String value = null;
if (token.length == 2) {
key = token[0];
value = token[1];
} else if (token.length == 1) {
key = token[0];
value = "";
} else {
key = "";
value = "";
}
key = FilterUtil.replaceVariables(mailAdapter, key);
value = FilterUtil.replaceVariables(mailAdapter, value);
options.put(key, value);
}
} else {
throw new SyntaxException("Expecting a StringList for " + NOTIFY_OPTIONS);
}
} else {
throw new SyntaxException("Expecting a parameter for " + NOTIFY_OPTIONS);
}
} else if (message == null && NOTIFY_MESSAGE.equals(tag)) {
// The next argment must be a string
if (argumentsIter.hasNext()) {
argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> stringList = ((StringListArgument) argument).getList();
if (stringList.size() != 1) {
throw new SyntaxException("Expecting exactly one String for " + NOTIFY_MESSAGE);
}
message = FilterUtil.replaceVariables(mailAdapter, (String) stringList.get(0));
} else {
throw new SyntaxException("Expecting a StringList for " + NOTIFY_MESSAGE);
}
} else {
throw new SyntaxException("Expecting a parameter for " + NOTIFY_MESSAGE);
}
}
} else {
// Stop when a non-tag argument is encountered
argumentsIter.previous();
stop = true;
}
}
// The next argument MUST be a <method: string>
if (argumentsIter.hasNext()) {
Argument argument = argumentsIter.next();
if (argument instanceof StringListArgument) {
List<String> stringList = ((StringListArgument) argument).getList();
if (stringList.size() != 1) {
throw new SyntaxException("Expecting exactly one String");
}
method = (String) stringList.get(0);
} else {
throw new SyntaxException("Expecting a StringList");
}
}
if (method == null) {
throw context.getCoordinate().syntaxException("Expecting a method string");
} else {
method = FilterUtil.replaceVariables(mailAdapter, method);
}
mailtoParams = new HashMap<String, List<String>>();
try {
URL url = new URL(method);
mailto = FilterUtil.replaceVariables(mailAdapter, url.getPath());
String query = url.getQuery();
if (!StringUtil.isNullOrEmpty(query)) {
String[] params = query.split("&");
for (String param : params) {
String[] token = param.split("=");
if (token.length > 2) {
throw new SyntaxException("'mailto' method syntax error: too many parameters");
} else {
if (StringUtils.isEmpty(token[0])) {
throw new SyntaxException("'mailto' method syntax error: empty parameter name");
}
FilterUtil.headerNameHasSpace(token[0]);
}
// If the value or parameter name is URL encoded, it should be
// decoded. If it is not even URL encoded, more or less decoding
// the string does not do harm the contents.
String headerName = null;
String headerValue = null;
try {
headerName = URLDecoder.decode(token[0].toLowerCase(), "UTF-8");
} catch (UnsupportedEncodingException e) {
// No exception should be thrown because the charset is always "UTF-8"
} catch (IllegalArgumentException e) {
headerName = token[0].toLowerCase();
}
if (token.length == 1) {
// The value must be empty
headerValue = "";
} else {
headerValue = token[1];
}
try {
headerValue = URLDecoder.decode(headerValue, "UTF-8");
} catch (UnsupportedEncodingException e) {
// No exception should be thrown because the charset is always "UTF-8"
} catch (IllegalArgumentException e) {
// Use token[1] as is
}
if (!mailtoParams.containsKey(headerName)) {
// Create a new entry for a header
List<String> value = new ArrayList<String>();
value.add(headerValue);
mailtoParams.put(headerName, value);
} else {
// Some headers, such as to or cc fields, can be specified multiple times
mailtoParams.get(headerName).add(headerValue);
}
}
}
} catch (MalformedURLException e) {
throw new SyntaxException("'mailto' method syntax error", e);
}
mail.addAction(new ActionNotifyMailto(from, options, importance, message, mailto, mailtoParams));
return null;
}
Aggregations