blob: 4d61e1d3875b0941dc6c410b0fa6379e0f160d2b [file] [log] [blame]
/****************************************************************
* 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.tests.optional;
import java.util.Iterator;
import java.util.List;
import org.apache.jsieve.Argument;
import org.apache.jsieve.Arguments;
import org.apache.jsieve.SieveContext;
import org.apache.jsieve.StringListArgument;
import org.apache.jsieve.TagArgument;
import org.apache.jsieve.exception.SieveException;
import org.apache.jsieve.exception.SyntaxException;
import org.apache.jsieve.mail.MailAdapter;
import org.apache.jsieve.parser.generated.Token;
import org.apache.jsieve.tests.AbstractTest;
/**
* Implementation of body extension defined in
* <a href='http://tools.ietf.org/html/rfc5173'>RFC5173</a>.
*/
public class Body extends AbstractTest {
public static final String TEXT = ":text";
public static final String RAW = ":raw";
public static final String CONTENT = ":content";
private TagArgument transformation;
private StringListArgument contentTypes;
private TagArgument matcher;
private StringListArgument valuesToBeMatched;
protected void validateArguments(Arguments args, SieveContext ctx) throws SieveException {
Iterator<Argument> matchingSpecifications = retrieveTransformationAndMatchingSpecificationIterator(args.getArgumentList());
if (transformation.getTag().equals(TEXT)) {
parseDefaultArguments(matchingSpecifications);
} else if (transformation.getTag().equals(RAW)) {
parseDefaultArguments(matchingSpecifications);
} else if (transformation.getTag().equals(CONTENT)) {
parseContentArguments(matchingSpecifications);
} else {
throw new SyntaxException("Unknown transformation " + transformation.getTag() + ". See RFC-5173 section 5.");
}
}
private void parseContentArguments(Iterator<Argument> matchingSpecifications) throws SyntaxException {
retrieveContentTypes(matchingSpecifications);
retrieveMatcher(matchingSpecifications);
retrieveMatchValues(matchingSpecifications);
assureNoMoreArguments(matchingSpecifications);
}
private void parseDefaultArguments(Iterator<Argument> matchingSpecifications) throws SyntaxException {
retrieveMatcher(matchingSpecifications);
retrieveMatchValues(matchingSpecifications);
assureNoMoreArguments(matchingSpecifications);
}
private Iterator<Argument> retrieveTransformationAndMatchingSpecificationIterator(List<Argument> arglist) throws SyntaxException {
if (arglist.size() < 1 ) {
throw new SyntaxException("Transformations should be specified. See RFC-5173 section 5.");
}
Argument arg = arglist.get(0);
if (!(arg instanceof TagArgument)) {
// by default transformation should be :text
transformation = new TagArgument(new Token(0, TEXT));
return arglist.iterator();
} else {
TagArgument transformationCandidate = (TagArgument) arg;
if (transformationCandidate.getTag().equals(TEXT) ||
transformationCandidate.getTag().equals(RAW) ||
transformationCandidate.getTag().equals(CONTENT) ) {
transformation = (TagArgument) arg;
Iterator<Argument> matchingSpecifications = arglist.iterator();
matchingSpecifications.next();
return matchingSpecifications;
} else {
// by default transformation should be :text
transformation = new TagArgument(new Token(0, TEXT));
return arglist.iterator();
}
}
}
protected boolean executeBasic(MailAdapter mail, Arguments args, SieveContext ctx) throws SieveException {
if (transformation.getTag().equals(RAW)) {
return mail.isInBodyRaw(valuesToBeMatched.getList());
} else if (transformation.getTag().equals(CONTENT)) {
return mail.isInBodyContent(contentTypes.getList(), valuesToBeMatched.getList());
} else if (transformation.getTag().equals(TEXT)) {
return mail.isInBodyText(valuesToBeMatched.getList());
} else {
throw new RuntimeException("Invalid transformation caught. Is your argument parsing buggy ?");
}
}
private void retrieveContentTypes(Iterator<Argument> matchingSpecifications) throws SyntaxException {
if (!matchingSpecifications.hasNext()) {
throw new SyntaxException("Expecting the list of content types following :content");
}
Argument contentTypesArgument = matchingSpecifications.next();
if (! (contentTypesArgument instanceof StringListArgument)) {
throw new SyntaxException("Expecting a String list to specify content types and not a" + contentTypesArgument.getClass());
}
contentTypes = (StringListArgument) contentTypesArgument;
}
private void retrieveMatcher(Iterator<Argument> matchingSpecifications) throws SyntaxException {
if (!matchingSpecifications.hasNext()) {
throw new SyntaxException("Expecting a matcher :contains");
}
Argument matcherArgument = matchingSpecifications.next();
if (! (matcherArgument instanceof TagArgument)) {
throw new SyntaxException("Expecting a matcher :contains and not a" + matcherArgument.getClass());
}
if (!((TagArgument)matcherArgument).getTag().equals(":contains")) {
throw new SyntaxException("Expecting a matcher :contains. Matcher " + ((TagArgument) matcherArgument).getTag() + " is currently not supported.");
}
matcher = (TagArgument) matcherArgument;
}
private void retrieveMatchValues(Iterator<Argument> matchingSpecifications) throws SyntaxException {
if (!matchingSpecifications.hasNext()) {
throw new SyntaxException("Matcher :contains should be followed by a StringList");
}
Argument matchValues = matchingSpecifications.next();
if (! (matchValues instanceof StringListArgument)) {
throw new SyntaxException("Matcher :contains should be followed by a StringList and not a " + matchValues.getClass());
}
valuesToBeMatched = (StringListArgument) matchValues;
}
private void assureNoMoreArguments(Iterator<Argument> matchingSpecifications) throws SyntaxException {
if (matchingSpecifications.hasNext()) {
throw new SyntaxException("Too many arguments for Body test");
}
}
}