You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2007/09/13 22:28:32 UTC
svn commit: r575440 - in /james/jsieve/trunk: ./
src/main/java/org/apache/jsieve/mail/
src/main/java/org/apache/jsieve/parser/address/
src/main/java/org/apache/jsieve/samples/james/
src/main/java/org/apache/jsieve/tests/ src/main/java/org/apache/jsieve...
Author: rdonkin
Date: Thu Sep 13 13:28:31 2007
New Revision: 575440
URL: http://svn.apache.org/viewvc?rev=575440&view=rev
Log:
Support for matching headers containing more than one address. Resolves JSIEVE-6 (https://issues.apache.org/jira/browse/JSIEVE-6). JTree schema forked from Mime4J.
Added:
james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/
james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/AddressNode.java
james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/BaseAddressListVisitor.java
james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/SieveAddressBuilder.java
james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/AbstractCompatatorTest.java
james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressParseTest.java
james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/MultipleToTest.java
james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/OpenedAddress.java
james/jsieve/trunk/src/test/java/org/apache/jsieve/parser/
james/jsieve/trunk/src/test/java/org/apache/jsieve/parser/address/
james/jsieve/trunk/src/test/java/org/apache/jsieve/parser/address/SieveAddressBuilderTest.java
Modified:
james/jsieve/trunk/build.xml
james/jsieve/trunk/src/main/java/org/apache/jsieve/mail/MailAdapter.java
james/jsieve/trunk/src/main/java/org/apache/jsieve/samples/james/SieveMailAdapter.java
james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/Address.java
james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/optional/Envelope.java
james/jsieve/trunk/src/main/java/org/apache/jsieve/util/check/ScriptCheckMailAdapter.java
james/jsieve/trunk/src/main/jjtree/AddressListParser.jjt
james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressTest.java
james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/utils/SieveMailAdapter.java
Modified: james/jsieve/trunk/build.xml
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/build.xml?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/build.xml (original)
+++ james/jsieve/trunk/build.xml Thu Sep 13 13:28:31 2007
@@ -131,14 +131,21 @@
Generate JavaCC source inserting parse tree building actions
and the Java source for the parse classes.
-->
- <mkdir dir="${build.src}/org/apache/jsieve/parser/generated"/>
+ <mkdir dir="${build.src}/org/apache/jsieve/parser/generated/address"/>
<java classname="jjtree" fork="yes" failonerror="true" dir="${build.src}">
<arg line="${javacc.dir}/sieve.jjt"/>
<classpath>
<pathelement location="${javacc.jar}"/>
<pathelement path="${java.class.path}" />
</classpath>
- </java>
+ </java>
+ <java classname="jjtree" fork="yes" failonerror="true" dir="${build.src}">
+ <arg line="${javacc.dir}/AddressListParser.jjt"/>
+ <classpath>
+ <pathelement location="${javacc.jar}"/>
+ <pathelement path="${java.class.path}" />
+ </classpath>
+ </java>
<!--
Make the generated parse classes an extension of the relevant base node to add the
@@ -159,6 +166,13 @@
<pathelement path="${java.class.path}" />
</classpath>
</java>
+ <java classname="javacc" fork="yes" failonerror="true" dir="${build.src}">
+ <arg line="-output_directory=${build.src}/org/apache/jsieve/parser/generated/address ${build.src}/AddressListParser.jj"/>
+ <classpath>
+ <pathelement location="${javacc.jar}"/>
+ <pathelement path="${java.class.path}" />
+ </classpath>
+ </java>
</target>
<!--
Modified: james/jsieve/trunk/src/main/java/org/apache/jsieve/mail/MailAdapter.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/mail/MailAdapter.java?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/mail/MailAdapter.java (original)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/mail/MailAdapter.java Thu Sep 13 13:28:31 2007
@@ -23,6 +23,7 @@
import java.util.List;
import java.util.ListIterator;
+import org.apache.jsieve.InternetAddressException;
import org.apache.jsieve.SieveException;
/**
@@ -103,8 +104,6 @@
*/
public void executeActions() throws SieveException;
-
-
/**
* Method getSize answers the receiver's message size in octets.
* @return int
@@ -128,4 +127,45 @@
*/
public Object getContent() throws SieveMailException;
+ /**
+ * <p>Parses the named header value into individual addresses.</p>
+ *
+ * <p>Headers should be matched in a way that ignores case and the
+ * whitespace prefixes and suffixes of a header name when performing the
+ * match, as required by RFC 3028. Thus "From", "from ", " From" and " from "
+ * are considered equal.
+ * </p>
+ *
+ * @param headerName name of the header whose value is to be split
+ * @return addresses listed in the given header not null, possibly empty
+ * @throws InternetAddressException when the header value is not an address
+ * or list of addresses. Implemetations may elect to support only
+ * standard headers known to containing one or more addresses rather
+ * than parsing the value
+ * content
+ * @throws SieveMailException when the header value cannot be read
+ */
+ public Address[] parseAddresses(String headerName) throws SieveMailException, InternetAddressException;
+
+ /**
+ * Contains address data required for SIEVE processing.
+ */
+ public interface Address {
+
+ /**
+ * Gets the local part of the email address.
+ * Specified in
+ * <a href='http://james.apache.org/server/rfclist/basic/rfc0822.txt'>RFC822</a>.
+ * @return local part, not null
+ */
+ public String getLocalPart();
+
+ /**
+ * Gets the domain part of the email address.
+ * Specified in
+ * <a href='http://james.apache.org/server/rfclist/basic/rfc0822.txt'>RFC822</a>.
+ * @return domain, not null
+ */
+ public String getDomain();
+ }
}
Added: james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/AddressNode.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/AddressNode.java?rev=575440&view=auto
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/AddressNode.java (added)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/AddressNode.java Thu Sep 13 13:28:31 2007
@@ -0,0 +1,30 @@
+/****************************************************************
+ * 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.parser.address;
+
+import org.apache.jsieve.parser.generated.address.Token;
+
+public class AddressNode {
+
+ public Token firstToken = null;
+
+ public Token lastToken = null;
+
+}
Added: james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/BaseAddressListVisitor.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/BaseAddressListVisitor.java?rev=575440&view=auto
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/BaseAddressListVisitor.java (added)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/BaseAddressListVisitor.java Thu Sep 13 13:28:31 2007
@@ -0,0 +1,89 @@
+/****************************************************************
+ * 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.parser.address;
+
+import org.apache.jsieve.parser.generated.address.ASTaddr_spec;
+import org.apache.jsieve.parser.generated.address.ASTaddress;
+import org.apache.jsieve.parser.generated.address.ASTaddress_list;
+import org.apache.jsieve.parser.generated.address.ASTangle_addr;
+import org.apache.jsieve.parser.generated.address.ASTdomain;
+import org.apache.jsieve.parser.generated.address.ASTgroup_body;
+import org.apache.jsieve.parser.generated.address.ASTlocal_part;
+import org.apache.jsieve.parser.generated.address.ASTmailbox;
+import org.apache.jsieve.parser.generated.address.ASTname_addr;
+import org.apache.jsieve.parser.generated.address.ASTphrase;
+import org.apache.jsieve.parser.generated.address.ASTroute;
+import org.apache.jsieve.parser.generated.address.AddressListParserVisitor;
+import org.apache.jsieve.parser.generated.address.SimpleNode;
+
+/**
+ * Do nothing implementation suitablae for subclassing.
+ */
+public abstract class BaseAddressListVisitor implements
+ AddressListParserVisitor {
+
+ public Object visit(SimpleNode node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTaddress_list node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTaddress node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTmailbox node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTname_addr node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTgroup_body node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTangle_addr node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTroute node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTphrase node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTaddr_spec node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTlocal_part node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+
+ public Object visit(ASTdomain node, Object data) {
+ return node.childrenAccept(this, data);
+ }
+}
Added: james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/SieveAddressBuilder.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/SieveAddressBuilder.java?rev=575440&view=auto
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/SieveAddressBuilder.java (added)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/parser/address/SieveAddressBuilder.java Thu Sep 13 13:28:31 2007
@@ -0,0 +1,206 @@
+/****************************************************************
+ * 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.parser.address;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.mail.Header;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+
+import org.apache.jsieve.mail.MailAdapter;
+import org.apache.jsieve.mail.SieveMailException;
+import org.apache.jsieve.mail.MailAdapter.Address;
+import org.apache.jsieve.parser.generated.address.ASTaddr_spec;
+import org.apache.jsieve.parser.generated.address.ASTaddress_list;
+import org.apache.jsieve.parser.generated.address.ASTdomain;
+import org.apache.jsieve.parser.generated.address.ASTlocal_part;
+import org.apache.jsieve.parser.generated.address.AddressListParser;
+import org.apache.jsieve.parser.generated.address.ParseException;
+import org.apache.jsieve.parser.generated.address.Token;
+
+/**
+ * Builds {@link MailAdapter.Address}'s from address lists. Note that
+ * implementators of {@link MailAdapter} are recommended to use a fully featured
+ * and maintained parser such as <a href='http://james.apache.org/mime4j'>Apache
+ * Mime4J</a>. This implementation is based on Mime4J code but is intended only
+ * for internal and demonstration purposes. It is not actively maintained.
+ */
+public class SieveAddressBuilder {
+
+ /**
+ * Parses the value from the given message into addresses.
+ * @param headerName header name, to be matched case insensitively
+ * @param message <code>Message</code>, not null
+ * @return <code>Address</code> array, not null possibly empty
+ * @throws SieveMailException
+ */
+ public static Address[] parseAddresses(final String headerName, final Message message) throws SieveMailException {
+ try {
+ final SieveAddressBuilder builder = new SieveAddressBuilder();
+
+ for (Enumeration en = message.getAllHeaders();en.hasMoreElements();) {
+ final Header header = (Header) en.nextElement();
+ final String name = header.getName();
+ if (name.trim().equalsIgnoreCase(headerName)) {
+ builder.addAddresses(header.getValue());
+ }
+ }
+
+ final Address[] results = builder.getAddresses();
+ return results;
+
+ } catch (MessagingException ex) {
+ throw new SieveMailException(ex);
+ } catch (ParseException ex) {
+ throw new SieveMailException(ex);
+ }
+ }
+
+ private static final Address[] EMPTY_ADDRESSES = {};
+
+ private final Collection addresses;
+ private final Worker worker;
+
+ public SieveAddressBuilder() {
+ addresses = Collections.synchronizedCollection(new ArrayList());
+ worker = new Worker();
+ }
+
+ /**
+ * Clears the addresses currently accumulated.
+ */
+ public void reset() {
+ addresses.clear();
+ }
+
+ /**
+ * Adds addresses in the given list.
+ *
+ * @param addressList
+ * RFC822 address list
+ * @throws ParseException
+ */
+ public void addAddresses(String addressList) throws ParseException {
+ final StringReader reader = new StringReader(addressList);
+ worker.addAddressses(reader, addresses);
+ }
+
+ /**
+ * Gets addresses currently accumulated by calls to
+ * {@link #addAddresses(String)} since the last call to {@link #reset}.
+ *
+ * @return addresses, not null
+ */
+ public Address[] getAddresses() {
+ final Address[] results = (Address[]) addresses
+ .toArray(EMPTY_ADDRESSES);
+ return results;
+ }
+
+ /**
+ * Performs the actual work.
+ * Factored into an inner class so that the build interface is clean.
+ */
+ private final class Worker extends BaseAddressListVisitor {
+
+ public void addAddressses(final Reader reader, final Collection results) throws ParseException {
+ AddressListParser parser = new AddressListParser(reader);
+ ASTaddress_list root = parser.parse();
+ root.childrenAccept(this, results);
+ }
+
+ public Object visit(ASTaddr_spec node, Object data) {
+ final AddressBean address = new AddressBean();
+ node.childrenAccept(this, address);
+ if (data instanceof Collection) {
+ final Collection collection = (Collection) data;
+ collection.add(address);
+ }
+ return data;
+ }
+
+ public Object visit(final ASTdomain node, final Object data) {
+ if (data instanceof AddressBean) {
+ final AddressBean address = (AddressBean) data;
+ final String domain = contents(node);
+ address.setDomain(domain);
+ }
+ return data;
+ }
+
+ public Object visit(ASTlocal_part node, Object data) {
+ if (data instanceof AddressBean) {
+ final AddressBean address = (AddressBean) data;
+ final String localPart = contents(node);
+ address.setLocalPart(localPart);
+ }
+ return data;
+ }
+
+ private String contents(AddressNode node) {
+ StringBuffer buffer = new StringBuffer(32);
+ Token last = node.lastToken;
+ Token next = node.firstToken;
+ while(next != last) {
+ buffer.append(next.image);
+ next = next.next;
+ }
+ buffer.append(last.image);
+ return buffer.toString();
+ }
+ }
+
+ /**
+ * Bean based address implementation.
+ */
+ private final class AddressBean implements Address {
+ private String localPart;
+
+ private String domain;
+
+ public AddressBean() {
+ localPart = "";
+ domain = "";
+ }
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public void setDomain(String domain) {
+ this.domain = domain;
+ }
+
+ public String getLocalPart() {
+ return localPart;
+ }
+
+ public void setLocalPart(String localPart) {
+ this.localPart = localPart;
+ }
+ }
+}
Modified: james/jsieve/trunk/src/main/java/org/apache/jsieve/samples/james/SieveMailAdapter.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/samples/james/SieveMailAdapter.java?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/samples/james/SieveMailAdapter.java (original)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/samples/james/SieveMailAdapter.java Thu Sep 13 13:28:31 2007
@@ -38,6 +38,7 @@
import org.apache.jsieve.mail.MailUtils;
import org.apache.jsieve.mail.SieveMailException;
import org.apache.jsieve.mail.optional.EnvelopeAccessors;
+import org.apache.jsieve.parser.address.SieveAddressBuilder;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
import org.apache.mailet.MailetContext;
@@ -370,5 +371,20 @@
+ " Envelope To: "
+ (null == getEnvelopeTo() ? "null" : getEnvelopeTo())
+ " Message ID: " + (null == messageID ? "null" : messageID);
+ }
+ public Object getContent() throws SieveMailException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ public String getContentType() throws SieveMailException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ public Address[] parseAddresses(String headerName) throws SieveMailException {
+ try {
+ return SieveAddressBuilder.parseAddresses(headerName, getMail().getMessage());
+ } catch (MessagingException e) {
+ throw new SieveMailException(e);
+ }
}
}
Added: james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/AbstractCompatatorTest.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/AbstractCompatatorTest.java?rev=575440&view=auto
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/AbstractCompatatorTest.java (added)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/AbstractCompatatorTest.java Thu Sep 13 13:28:31 2007
@@ -0,0 +1,228 @@
+/****************************************************************
+ * 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;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+
+import org.apache.jsieve.Arguments;
+import org.apache.jsieve.SieveContext;
+import org.apache.jsieve.SieveException;
+import org.apache.jsieve.StringListArgument;
+import org.apache.jsieve.SyntaxException;
+import org.apache.jsieve.TagArgument;
+import org.apache.jsieve.comparators.ComparatorNames;
+import org.apache.jsieve.mail.MailAdapter;
+import org.apache.jsieve.mail.SieveMailException;
+
+public abstract class AbstractCompatatorTest extends AbstractTest implements AddressPartTags, ComparatorTags, MatchTypeTags, ComparatorNames {
+
+ public AbstractCompatatorTest() {
+ super();
+ }
+
+ /**
+ * <p>From RFC 3028, Section 5.1... </p>
+ * <code>
+ * Syntax: address [ADDRESS-PART] [COMPARATOR] [MATCH-TYPE]
+ * <header-list: string-list> <key-list: string-list>
+ * </code>
+ * <p>Note that the spec. then goes on to give an example where the
+ * order of the optional parts is different, so I am assuming that the order of
+ * the optional parts is optional too!</p>
+ *
+ * @see org.apache.jsieve.tests.AbstractTest#executeBasic(MailAdapter, Arguments, SieveContext)
+ */
+ protected boolean executeBasic(MailAdapter mail, Arguments arguments, SieveContext context) throws SieveException {
+ String addressPart = null;
+ String comparator = null;
+ String matchType = null;
+ List headerNames = null;
+ List keys = null;
+
+ ListIterator argumentsIter = arguments.getArgumentList().listIterator();
+ boolean stop = false;
+
+ // Tag processing
+ while (!stop && argumentsIter.hasNext())
+ {
+ Object argument = argumentsIter.next();
+ if (argument instanceof TagArgument)
+ {
+ String tag = ((TagArgument) argument).getTag();
+
+ // [ADDRESS-PART]?
+ if (null == addressPart
+ && (tag.equals(LOCALPART_TAG)
+ || tag.equals(DOMAIN_TAG)
+ || tag.equals(ALL_TAG)))
+ addressPart = tag;
+ // [COMPARATOR]?
+ else if (null == comparator && tag.equals(COMPARATOR_TAG))
+ {
+ // The next argument must be a stringlist
+ if (argumentsIter.hasNext())
+ {
+ argument = argumentsIter.next();
+ if (argument instanceof StringListArgument)
+ {
+ List stringList =
+ ((StringListArgument) argument).getList();
+ if (stringList.size() != 1)
+ throw new SyntaxException("Expecting exactly one String");
+ comparator = (String) stringList.get(0);
+ }
+ else
+ throw new SyntaxException("Expecting a StringList");
+ }
+ }
+ // [MATCH-TYPE]?
+ else if (
+ null == matchType
+ && (tag.equals(IS_TAG)
+ || tag.equals(CONTAINS_TAG)
+ || tag.equals(MATCHES_TAG)))
+ matchType = tag;
+ else
+ throw context.getCoordinate().syntaxException("Found unexpected TagArgument");
+ }
+ 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())
+ {
+ Object argument = argumentsIter.next();
+ if (argument instanceof StringListArgument)
+ headerNames = ((StringListArgument) argument).getList();
+ }
+ if (null == headerNames)
+ throw context.getCoordinate().syntaxException("Expecting a StringList of header names");
+
+ // The next argument MUST be a string-list of keys
+ if (argumentsIter.hasNext())
+ {
+ Object argument = argumentsIter.next();
+ if (argument instanceof StringListArgument)
+ keys = ((StringListArgument) argument).getList();
+ }
+ else if (null == keys)
+ throw context.getCoordinate().syntaxException("Expecting a StringList of keys");
+
+ if (argumentsIter.hasNext())
+ throw context.getCoordinate().syntaxException("Found unexpected arguments");
+
+ return match(
+ mail,
+ (addressPart == null ? ALL_TAG : addressPart),
+ (comparator == null ? ASCII_CASEMAP_COMPARATOR : comparator),
+ (matchType == null ? IS_TAG : matchType),
+ headerNames,
+ keys);
+ }
+
+ /**
+ * Method match.
+ * @param mail
+ * @param addressPart
+ * @param comparator
+ * @param matchType
+ * @param headerNames
+ * @param keys
+ * @return boolean
+ * @throws SieveMailException
+ */
+ protected boolean match(MailAdapter mail, String addressPart, String comparator, String matchType, List headerNames, List keys) throws SieveException {
+ // Iterate over the header names looking for a match
+ boolean isMatched = false;
+ Iterator headerNamesIter = headerNames.iterator();
+ while (!isMatched && headerNamesIter.hasNext())
+ {
+ isMatched =
+ match(
+ mail,
+ addressPart,
+ comparator,
+ matchType,
+ (String) headerNamesIter.next(),
+ keys);
+ }
+ return isMatched;
+ }
+
+ /**
+ * Method match.
+ * @param mail
+ * @param addressPart
+ * @param comparator
+ * @param matchType
+ * @param headerName
+ * @param keys
+ * @return boolean
+ * @throws SieveMailException
+ */
+ protected boolean match(MailAdapter mail, String addressPart, String comparator, String matchType, String headerName, List keys) throws SieveException {
+ // Iterate over the keys looking for a match
+ boolean isMatched = false;
+ Iterator keysIter = keys.iterator();
+ while (!isMatched && keysIter.hasNext())
+ {
+ isMatched =
+ match(
+ mail,
+ addressPart,
+ comparator,
+ matchType,
+ headerName,
+ (String) keysIter.next());
+ }
+ return isMatched;
+ }
+
+ /**
+ * Method match.
+ * @param mail
+ * @param addressPart
+ * @param comparator
+ * @param matchType
+ * @param headerName
+ * @param key
+ * @return boolean
+ * @throws SieveMailException
+ */
+ protected abstract boolean match(MailAdapter mail, String addressPart, String comparator,
+ String matchType, String headerName, String key) throws SieveException;
+
+ /**
+ * @see org.apache.jsieve.tests.AbstractTest#validateArguments(Arguments, SieveContext)
+ */
+ protected void validateArguments(Arguments arguments, SieveContext context) throws SieveException {
+ if (arguments.hasTests())
+ throw context.getCoordinate().syntaxException("Found unexpected tests");
+ }
+
+}
Modified: james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/Address.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/Address.java?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/Address.java (original)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/Address.java Thu Sep 13 13:28:31 2007
@@ -21,30 +21,22 @@
package org.apache.jsieve.tests;
import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
-import org.apache.jsieve.Arguments;
import org.apache.jsieve.InternetAddressException;
-import org.apache.jsieve.SieveContext;
import org.apache.jsieve.SieveException;
-import org.apache.jsieve.StringListArgument;
-import org.apache.jsieve.SyntaxException;
-import org.apache.jsieve.TagArgument;
-import org.apache.jsieve.comparators.ComparatorNames;
import org.apache.jsieve.comparators.ComparatorUtils;
import org.apache.jsieve.mail.MailAdapter;
import org.apache.jsieve.mail.SieveMailException;
+
/**
* Class Address implements the Addresss Test as defined in RFC 3028, section 5.1.
*/
public class Address
- extends AbstractTest
- implements AddressPartTags, ComparatorTags, MatchTypeTags, ComparatorNames
+ extends AbstractCompatatorTest
{
/**
* Constructor for Address.
@@ -54,235 +46,33 @@
super();
}
- /**
- * <p>From RFC 3028, Section 5.1... </p>
- * <code>
- * Syntax: address [ADDRESS-PART] [COMPARATOR] [MATCH-TYPE]
- * <header-list: string-list> <key-list: string-list>
- * </code>
- * <p>Note that the spec. then goes on to give an example where the
- * order of the optional parts is different, so I am assuming that the order of
- * the optional parts is optional too!</p>
- *
- * @see org.apache.jsieve.tests.AbstractTest#executeBasic(MailAdapter, Arguments, SieveContext)
- */
- protected boolean executeBasic(MailAdapter mail, Arguments arguments, SieveContext context)
- throws SieveException
- {
- String addressPart = null;
- String comparator = null;
- String matchType = null;
- List headerNames = null;
- List keys = null;
-
- ListIterator argumentsIter = arguments.getArgumentList().listIterator();
- boolean stop = false;
-
- // Tag processing
- while (!stop && argumentsIter.hasNext())
- {
- Object argument = argumentsIter.next();
- if (argument instanceof TagArgument)
- {
- String tag = ((TagArgument) argument).getTag();
-
- // [ADDRESS-PART]?
- if (null == addressPart
- && (tag.equals(LOCALPART_TAG)
- || tag.equals(DOMAIN_TAG)
- || tag.equals(ALL_TAG)))
- addressPart = tag;
- // [COMPARATOR]?
- else if (null == comparator && tag.equals(COMPARATOR_TAG))
- {
- // The next argument must be a stringlist
- if (argumentsIter.hasNext())
- {
- argument = argumentsIter.next();
- if (argument instanceof StringListArgument)
- {
- List stringList =
- ((StringListArgument) argument).getList();
- if (stringList.size() != 1)
- throw new SyntaxException("Expecting exactly one String");
- comparator = (String) stringList.get(0);
- }
- else
- throw new SyntaxException("Expecting a StringList");
- }
- }
- // [MATCH-TYPE]?
- else if (
- null == matchType
- && (tag.equals(IS_TAG)
- || tag.equals(CONTAINS_TAG)
- || tag.equals(MATCHES_TAG)))
- matchType = tag;
- else
- throw context.getCoordinate().syntaxException("Found unexpected TagArgument");
- }
- 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())
- {
- Object argument = argumentsIter.next();
- if (argument instanceof StringListArgument)
- headerNames = ((StringListArgument) argument).getList();
- }
- if (null == headerNames)
- throw context.getCoordinate().syntaxException("Expecting a StringList of header names");
-
- // The next argument MUST be a string-list of keys
- if (argumentsIter.hasNext())
- {
- Object argument = argumentsIter.next();
- if (argument instanceof StringListArgument)
- keys = ((StringListArgument) argument).getList();
- }
- else if (null == keys)
- throw context.getCoordinate().syntaxException("Expecting a StringList of keys");
-
- if (argumentsIter.hasNext())
- throw context.getCoordinate().syntaxException("Found unexpected arguments");
-
- return match(
- mail,
- (addressPart == null ? ALL_TAG : addressPart),
- (comparator == null ? ASCII_CASEMAP_COMPARATOR : comparator),
- (matchType == null ? IS_TAG : matchType),
- headerNames,
- keys);
- }
-
- /**
- * Method match.
- * @param mail
- * @param addressPart
- * @param comparator
- * @param matchType
- * @param headerNames
- * @param keys
- * @return boolean
- * @throws SieveMailException
- */
- protected boolean match(
- MailAdapter mail,
- String addressPart,
- String comparator,
- String matchType,
- List headerNames,
- List keys)
- throws SieveException
- {
- // Iterate over the header names looking for a match
- boolean isMatched = false;
- Iterator headerNamesIter = headerNames.iterator();
- while (!isMatched && headerNamesIter.hasNext())
- {
- isMatched =
- match(
- mail,
- addressPart,
- comparator,
- matchType,
- (String) headerNamesIter.next(),
- keys);
- }
- return isMatched;
- }
-
- /**
- * Method match.
- * @param mail
- * @param addressPart
- * @param comparator
- * @param matchType
- * @param headerName
- * @param keys
- * @return boolean
- * @throws SieveMailException
- */
- protected boolean match(
- MailAdapter mail,
- String addressPart,
- String comparator,
- String matchType,
- String headerName,
- List keys)
- throws SieveException
+ protected boolean match(MailAdapter mail, String addressPart, String comparator, String matchType, String headerName, String key) throws SieveException
{
- // Iterate over the keys looking for a match
+ final MailAdapter.Address[] addresses =
+ getMatchingValues(mail, headerName);
+ final int length = addresses.length;
+ int i=0;
boolean isMatched = false;
- Iterator keysIter = keys.iterator();
- while (!isMatched && keysIter.hasNext())
+ while (!isMatched && i<length)
{
isMatched =
match(
- mail,
- addressPart,
- comparator,
- matchType,
- headerName,
- (String) keysIter.next());
+ addressPart,
+ comparator,
+ matchType,
+ addresses[i++],
+ key);
}
return isMatched;
}
- /**
- * Method match.
- * @param mail
- * @param addressPart
- * @param comparator
- * @param matchType
- * @param headerName
- * @param key
- * @return boolean
- * @throws SieveMailException
- */
- protected boolean match(
- MailAdapter mail,
- String addressPart,
- String comparator,
- String matchType,
- String headerName,
- String key)
- throws SieveException
+ private MailAdapter.Address[] getMatchingValues(MailAdapter mail,
+ String valueName) throws SieveMailException,
+ InternetAddressException
{
- Iterator headerValuesIter =
- getMatchingValues(mail, headerName).iterator();
- boolean isMatched = false;
- while (!isMatched && headerValuesIter.hasNext())
- {
- isMatched =
- match(
- addressPart,
- comparator,
- matchType,
- ((String) headerValuesIter.next()),
- key);
- }
- return isMatched;
+ return mail.parseAddresses(valueName);
}
- /**
- * Method getMatchingValues.
- * @param mail
- * @param valueName
- * @return List
- * @throws SieveMailException
- */
- protected List getMatchingValues(MailAdapter mail, String valueName)
- throws SieveMailException
- {
- return mail.getMatchingHeader(valueName);
- }
/**
* Method match.
@@ -294,66 +84,35 @@
* @return boolean
* @throws SieveMailException
*/
- protected boolean match(
- String addressPart,
- String comparator,
- String matchType,
- String headerValue,
- String key)
- throws SieveException
+ protected boolean match(String addressPart, String comparator, String matchType,
+ MailAdapter.Address address, String key) throws SieveException
{
- // Attempt to create a new InternetAddress object from the headerValue
- // If this fails, the header either is not intended to contain a valid
- // Internet Address or is corrupt. Either way, its an Exception!
- String address = null;
- try
- {
- // address is a simple address; user@domain or user
- address = new InternetAddress(headerValue).getAddress();
- }
- catch (AddressException e)
- {
- throw new InternetAddressException(e.getMessage());
- }
+ final String localPart = address.getLocalPart();
+ final String domain = address.getDomain();
// Extract the part of the address we are matching on
- String matchAddress = null;
+ final String matchAddress;
if (addressPart.equals(":all"))
- matchAddress = address;
+ matchAddress = localPart + "@" + domain;
else
{
- int localStart = 0;
- int localEnd = 0;
- int domainStart = 0;
- int domainEnd = address.length();
- int splitIndex = address.indexOf('@');
- // If there is no domain part (-1), treat it as an empty String
- if (splitIndex == -1)
- {
- localEnd = domainEnd;
- domainStart = domainEnd;
- }
- else
- {
- localEnd = splitIndex;
- domainStart = splitIndex + 1;
- }
matchAddress =
(addressPart.equals(LOCALPART_TAG)
- ? address.substring(localStart, localEnd)
- : address.substring(domainStart, domainEnd));
+ ? localPart
+ : domain.toLowerCase());
}
-
+
// domain matches MUST ignore case, others should not
String matchKey = null;
if (addressPart.equals(DOMAIN_TAG))
{
matchKey = key.toLowerCase();
- matchAddress = matchAddress.toLowerCase();
}
else
+ {
matchKey = key;
-
+ }
+
// Match using the specified comparator
return ComparatorUtils.match(
comparator,
@@ -361,14 +120,4 @@
matchAddress,
matchKey);
}
-
- /**
- * @see org.apache.jsieve.tests.AbstractTest#validateArguments(Arguments, SieveContext)
- */
- protected void validateArguments(Arguments arguments, SieveContext context) throws SieveException
- {
- if (arguments.hasTests())
- throw context.getCoordinate().syntaxException("Found unexpected tests");
- }
-
}
Modified: james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/optional/Envelope.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/optional/Envelope.java?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/optional/Envelope.java (original)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/tests/optional/Envelope.java Thu Sep 13 13:28:31 2007
@@ -20,18 +20,26 @@
package org.apache.jsieve.tests.optional;
+import java.util.Iterator;
import java.util.List;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+
+import org.apache.jsieve.InternetAddressException;
+import org.apache.jsieve.SieveException;
+import org.apache.jsieve.comparators.ComparatorUtils;
import org.apache.jsieve.mail.MailAdapter;
import org.apache.jsieve.mail.SieveMailException;
import org.apache.jsieve.mail.optional.EnvelopeAccessors;
+import org.apache.jsieve.tests.AbstractCompatatorTest;
import org.apache.jsieve.tests.Address;
/**
* Class Envelope implements the optional Envelope Test as defined in RFC 3028,
* section 5.4.
*/
-public class Envelope extends Address
+public class Envelope extends AbstractCompatatorTest
{
/**
@@ -49,6 +57,94 @@
throws SieveMailException
{
return ((EnvelopeAccessors) mail).getMatchingEnvelope(valueName);
+ }
+
+ /**
+ * Method match.
+ * @param addressPart
+ * @param comparator
+ * @param matchType
+ * @param headerValue
+ * @param key
+ * @return boolean
+ * @throws SieveMailException
+ */
+ protected boolean match(String addressPart, String comparator, String matchType, String headerValue, String key) throws SieveException {
+ // Attempt to create a new InternetAddress object from the headerValue
+ // If this fails, the header either is not intended to contain a valid
+ // Internet Address or is corrupt. Either way, its an Exception!
+ String address = null;
+ try
+ {
+ // address is a simple address; user@domain or user
+ address = new InternetAddress(headerValue).getAddress();
+ }
+ catch (AddressException e)
+ {
+ throw new InternetAddressException(e.getMessage());
+ }
+
+ // Extract the part of the address we are matching on
+ String matchAddress = null;
+ if (addressPart.equals(":all"))
+ matchAddress = address;
+ else
+ {
+ int localStart = 0;
+ int localEnd = 0;
+ int domainStart = 0;
+ int domainEnd = address.length();
+ int splitIndex = address.indexOf('@');
+ // If there is no domain part (-1), treat it as an empty String
+ if (splitIndex == -1)
+ {
+ localEnd = domainEnd;
+ domainStart = domainEnd;
+ }
+ else
+ {
+ localEnd = splitIndex;
+ domainStart = splitIndex + 1;
+ }
+ matchAddress =
+ (addressPart.equals(LOCALPART_TAG)
+ ? address.substring(localStart, localEnd)
+ : address.substring(domainStart, domainEnd));
+ }
+
+ // domain matches MUST ignore case, others should not
+ String matchKey = null;
+ if (addressPart.equals(DOMAIN_TAG))
+ {
+ matchKey = key.toLowerCase();
+ matchAddress = matchAddress.toLowerCase();
+ }
+ else
+ matchKey = key;
+
+ // Match using the specified comparator
+ return ComparatorUtils.match(
+ comparator,
+ matchType,
+ matchAddress,
+ matchKey);
+ }
+
+ protected boolean match(MailAdapter mail, String addressPart, String comparator, String matchType, String headerName, String key) throws SieveException {
+ Iterator headerValuesIter =
+ getMatchingValues(mail, headerName).iterator();
+ boolean isMatched = false;
+ while (!isMatched && headerValuesIter.hasNext())
+ {
+ isMatched =
+ match(
+ addressPart,
+ comparator,
+ matchType,
+ ((String) headerValuesIter.next()),
+ key);
+ }
+ return isMatched;
}
Modified: james/jsieve/trunk/src/main/java/org/apache/jsieve/util/check/ScriptCheckMailAdapter.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/java/org/apache/jsieve/util/check/ScriptCheckMailAdapter.java?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/src/main/java/org/apache/jsieve/util/check/ScriptCheckMailAdapter.java (original)
+++ james/jsieve/trunk/src/main/java/org/apache/jsieve/util/check/ScriptCheckMailAdapter.java Thu Sep 13 13:28:31 2007
@@ -37,6 +37,7 @@
import org.apache.jsieve.mail.MailAdapter;
import org.apache.jsieve.mail.MailUtils;
import org.apache.jsieve.mail.SieveMailException;
+import org.apache.jsieve.parser.address.SieveAddressBuilder;
/**
* Checks script execution for an email.
@@ -268,6 +269,10 @@
}
}
return result;
+ }
+
+ public Address[] parseAddresses(String headerName) throws SieveMailException {
+ return SieveAddressBuilder.parseAddresses(headerName, mail);
}
}
Modified: james/jsieve/trunk/src/main/jjtree/AddressListParser.jjt
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/main/jjtree/AddressListParser.jjt?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/src/main/jjtree/AddressListParser.jjt (original)
+++ james/jsieve/trunk/src/main/jjtree/AddressListParser.jjt Thu Sep 13 13:28:31 2007
@@ -1,332 +1,317 @@
-/****************************************************************
- * 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. *
- ****************************************************************/
-
-
-/**
- * RFC2822 address list parser.
- *
- * Created 9/17/2004
- * by Joe Cheng <co...@joecheng.com>
- */
-
-options {
- STATIC=false;
- LOOKAHEAD=1;
- VISITOR=true;
- MULTI=true;
- NODE_SCOPE_HOOK=true;
- NODE_EXTENDS="org.apache.james.mime4j.field.address.parser.BaseNode";
- //DEBUG_PARSER=true;
- //DEBUG_TOKEN_MANAGER=true;
-}
-
-PARSER_BEGIN(AddressListParser)
-/****************************************************************
- * 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.james.mime4j.field.address.parser;
-
-public class AddressListParser {
- public static void main(String args[]) throws ParseException {
- while (true) {
- try {
- AddressListParser parser = new AddressListParser(System.in);
- parser.parseLine();
- ((SimpleNode)parser.jjtree.rootNode()).dump("> ");
- } catch (Exception x) {
- x.printStackTrace();
- return;
- }
- }
- }
-
- private static void log(String msg) {
- System.out.print(msg);
- }
-
- public ASTaddress_list parse() throws ParseException {
- try {
- parseAll();
- return (ASTaddress_list)jjtree.rootNode();
- } catch (TokenMgrError tme) {
- throw new ParseException(tme.getMessage());
- }
- }
-
-
- void jjtreeOpenNodeScope(Node n) {
- ((SimpleNode)n).firstToken = getToken(1);
- }
-
- void jjtreeCloseNodeScope(Node n) {
- ((SimpleNode)n).lastToken = getToken(0);
- }
-}
-
-PARSER_END(AddressListParser)
-
-void parseLine() #void :
-{}
-{
- address_list() ["\r"] "\n"
-}
-
-void parseAll() #void :
-{}
-{
- address_list() <EOF>
-}
-
-void address_list() :
-{}
-{
- [ address() ]
- (
- ","
- [ address() ]
- )*
-}
-
-void address() :
-{}
-{
- LOOKAHEAD(2147483647)
- addr_spec()
-| angle_addr()
-| ( phrase() (group_body() | angle_addr()) )
-}
-
-void mailbox() :
-{}
-{
- LOOKAHEAD(2147483647)
- addr_spec()
-| angle_addr()
-| name_addr()
-}
-
-void name_addr() :
-{}
-{
- phrase() angle_addr()
-}
-
-void group_body() :
-{}
-{
- ":"
- [ mailbox() ]
- (
- ","
- [ mailbox() ]
- )*
- ";"
-}
-
-void angle_addr() :
-{}
-{
- "<" [ route() ] addr_spec() ">"
-}
-
-void route() :
-{}
-{
- "@" domain() ( (",")* "@" domain() )* ":"
-}
-
-void phrase() :
-{}
-{
-( <DOTATOM>
-| <QUOTEDSTRING>
-)+
-}
-
-void addr_spec() :
-{}
-{
- ( local_part() "@" domain() )
-}
-
-void local_part() :
-{ Token t; }
-{
- ( t=<DOTATOM> | t=<QUOTEDSTRING> )
- ( [t="."]
- {
- if ( t.kind == AddressListParserConstants.QUOTEDSTRING || t.image.charAt(t.image.length() - 1) != '.')
- throw new ParseException("Words in local part must be separated by '.'");
- }
- ( t=<DOTATOM> | t=<QUOTEDSTRING> )
- )*
-}
-
-void domain() :
-{ Token t; }
-{
- ( t=<DOTATOM>
- ( [t="."]
- {
- if (t.image.charAt(t.image.length() - 1) != '.')
- throw new ParseException("Atoms in domain names must be separated by '.'");
- }
- t=<DOTATOM>
- )*
- )
-| <DOMAINLITERAL>
-}
-
-SPECIAL_TOKEN :
-{
- < WS: ( [" ", "\t"] )+ >
-}
-
-TOKEN :
-{
- < #ALPHA: ["a" - "z", "A" - "Z"] >
-| < #DIGIT: ["0" - "9"] >
-| < #ATEXT: ( <ALPHA> | <DIGIT>
- | "!" | "#" | "$" | "%"
- | "&" | "'" | "*" | "+"
- | "-" | "/" | "=" | "?"
- | "^" | "_" | "`" | "{"
- | "|" | "}" | "~"
- )>
-| < DOTATOM: <ATEXT> ( <ATEXT> | "." )* >
-}
-
-TOKEN_MGR_DECLS :
-{
- // Keeps track of how many levels of comment nesting
- // we've encountered. This is only used when the 2nd
- // level is reached, for example ((this)), not (this).
- // This is because the outermost level must be treated
- // specially anyway, because the outermost ")" has a
- // different token type than inner ")" instances.
- static int commentNest;
-}
-
-MORE :
-{
- // domain literal
- "[" : INDOMAINLITERAL
-}
-
-<INDOMAINLITERAL>
-MORE :
-{
- < <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
-| < ~["[", "]", "\\"] >
-}
-
-<INDOMAINLITERAL>
-TOKEN :
-{
- < DOMAINLITERAL: "]" > { matchedToken.image = image.toString(); }: DEFAULT
-}
-
-MORE :
-{
- // starts a comment
- "(" : INCOMMENT
-}
-
-<INCOMMENT>
-SKIP :
-{
- // ends a comment
- < COMMENT: ")" > : DEFAULT
- // if this is ever changed to not be a SKIP, need
- // to make sure matchedToken.token = token.toString()
- // is called.
-}
-
-<INCOMMENT>
-MORE :
-{
- < <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
-| "(" { commentNest = 1; } : NESTED_COMMENT
-| < <ANY>>
-}
-
-<NESTED_COMMENT>
-MORE :
-{
- < <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
-| "(" { ++commentNest; }
-| ")" { --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT); }
-| < <ANY>>
-}
-
-
-// QUOTED STRINGS
-
-MORE :
-{
- "\"" { image.deleteCharAt(image.length() - 1); } : INQUOTEDSTRING
-}
-
-<INQUOTEDSTRING>
-MORE :
-{
- < <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
-| < (~["\"", "\\"])+ >
-}
-
-<INQUOTEDSTRING>
-TOKEN :
-{
- < QUOTEDSTRING: "\"" > { matchedToken.image = image.substring(0, image.length() - 1); } : DEFAULT
-}
-
-// GLOBALS
-
-<*>
-TOKEN :
-{
- < #QUOTEDPAIR: "\\" <ANY> >
-| < #ANY: ~[] >
-}
-
-// ERROR!
-/*
-
-<*>
-TOKEN :
-{
- < UNEXPECTED_CHAR: <ANY> >
-}
-
-*/
\ No newline at end of file
+/****************************************************************
+ * 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. *
+ ****************************************************************/
+
+
+/**
+ * RFC2822 address list parser.
+ *
+ * Created 9/17/2004
+ * by Joe Cheng <co...@joecheng.com>
+ */
+
+options {
+ STATIC=false;
+ LOOKAHEAD=1;
+ VISITOR=true;
+ MULTI=true;
+ NODE_SCOPE_HOOK=true;
+ NODE_EXTENDS="org.apache.jsieve.parser.address.AddressNode";
+ OUTPUT_DIRECTORY="./org/apache/jsieve/parser/generated/address";
+ //DEBUG_PARSER=true;
+ //DEBUG_TOKEN_MANAGER=true;
+}
+
+PARSER_BEGIN(AddressListParser)
+/****************************************************************
+ * 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.parser.generated.address;
+
+public class AddressListParser {
+
+ public ASTaddress_list parse() throws ParseException {
+ try {
+ parseAll();
+ return (ASTaddress_list)jjtree.rootNode();
+ } catch (TokenMgrError tme) {
+ throw new ParseException(tme.getMessage());
+ }
+ }
+
+
+ void jjtreeOpenNodeScope(Node n) {
+ ((SimpleNode)n).firstToken = getToken(1);
+ }
+
+ void jjtreeCloseNodeScope(Node n) {
+ ((SimpleNode)n).lastToken = getToken(0);
+ }
+}
+
+PARSER_END(AddressListParser)
+
+void parseLine() #void :
+{}
+{
+ address_list() ["\r"] "\n"
+}
+
+void parseAll() #void :
+{}
+{
+ address_list() <EOF>
+}
+
+void address_list() :
+{}
+{
+ [ address() ]
+ (
+ ","
+ [ address() ]
+ )*
+}
+
+void address() :
+{}
+{
+ LOOKAHEAD(2147483647)
+ addr_spec()
+| angle_addr()
+| ( phrase() (group_body() | angle_addr()) )
+}
+
+void mailbox() :
+{}
+{
+ LOOKAHEAD(2147483647)
+ addr_spec()
+| angle_addr()
+| name_addr()
+}
+
+void name_addr() :
+{}
+{
+ phrase() angle_addr()
+}
+
+void group_body() :
+{}
+{
+ ":"
+ [ mailbox() ]
+ (
+ ","
+ [ mailbox() ]
+ )*
+ ";"
+}
+
+void angle_addr() :
+{}
+{
+ "<" [ route() ] addr_spec() ">"
+}
+
+void route() :
+{}
+{
+ "@" domain() ( (",")* "@" domain() )* ":"
+}
+
+void phrase() :
+{}
+{
+( <DOTATOM>
+| <QUOTEDSTRING>
+)+
+}
+
+void addr_spec() :
+{}
+{
+ ( local_part() "@" domain() )
+}
+
+void local_part() :
+{ Token t; }
+{
+ ( t=<DOTATOM> | t=<QUOTEDSTRING> )
+ ( [t="."]
+ {
+ if ( t.kind == AddressListParserConstants.QUOTEDSTRING || t.image.charAt(t.image.length() - 1) != '.')
+ throw new ParseException("Words in local part must be separated by '.'");
+ }
+ ( t=<DOTATOM> | t=<QUOTEDSTRING> )
+ )*
+}
+
+void domain() :
+{ Token t; }
+{
+ ( t=<DOTATOM>
+ ( [t="."]
+ {
+ if (t.image.charAt(t.image.length() - 1) != '.')
+ throw new ParseException("Atoms in domain names must be separated by '.'");
+ }
+ t=<DOTATOM>
+ )*
+ )
+| <DOMAINLITERAL>
+}
+
+SPECIAL_TOKEN :
+{
+ < WS: ( [" ", "\t"] )+ >
+}
+
+TOKEN :
+{
+ < #ALPHA: ["a" - "z", "A" - "Z"] >
+| < #DIGIT: ["0" - "9"] >
+| < #ATEXT: ( <ALPHA> | <DIGIT>
+ | "!" | "#" | "$" | "%"
+ | "&" | "'" | "*" | "+"
+ | "-" | "/" | "=" | "?"
+ | "^" | "_" | "`" | "{"
+ | "|" | "}" | "~"
+ )>
+| < DOTATOM: <ATEXT> ( <ATEXT> | "." )* >
+}
+
+TOKEN_MGR_DECLS :
+{
+ // Keeps track of how many levels of comment nesting
+ // we've encountered. This is only used when the 2nd
+ // level is reached, for example ((this)), not (this).
+ // This is because the outermost level must be treated
+ // specially anyway, because the outermost ")" has a
+ // different token type than inner ")" instances.
+ static int commentNest;
+}
+
+MORE :
+{
+ // domain literal
+ "[" : INDOMAINLITERAL
+}
+
+<INDOMAINLITERAL>
+MORE :
+{
+ < <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
+| < ~["[", "]", "\\"] >
+}
+
+<INDOMAINLITERAL>
+TOKEN :
+{
+ < DOMAINLITERAL: "]" > { matchedToken.image = image.toString(); }: DEFAULT
+}
+
+MORE :
+{
+ // starts a comment
+ "(" : INCOMMENT
+}
+
+<INCOMMENT>
+SKIP :
+{
+ // ends a comment
+ < COMMENT: ")" > : DEFAULT
+ // if this is ever changed to not be a SKIP, need
+ // to make sure matchedToken.token = token.toString()
+ // is called.
+}
+
+<INCOMMENT>
+MORE :
+{
+ < <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
+| "(" { commentNest = 1; } : NESTED_COMMENT
+| < <ANY>>
+}
+
+<NESTED_COMMENT>
+MORE :
+{
+ < <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
+| "(" { ++commentNest; }
+| ")" { --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT); }
+| < <ANY>>
+}
+
+
+// QUOTED STRINGS
+
+MORE :
+{
+ "\"" { image.deleteCharAt(image.length() - 1); } : INQUOTEDSTRING
+}
+
+<INQUOTEDSTRING>
+MORE :
+{
+ < <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
+| < (~["\"", "\\"])+ >
+}
+
+<INQUOTEDSTRING>
+TOKEN :
+{
+ < QUOTEDSTRING: "\"" > { matchedToken.image = image.substring(0, image.length() - 1); } : DEFAULT
+}
+
+// GLOBALS
+
+<*>
+TOKEN :
+{
+ < #QUOTEDPAIR: "\\" <ANY> >
+| < #ANY: ~[] >
+}
+
+// ERROR!
+/*
+
+<*>
+TOKEN :
+{
+ < UNEXPECTED_CHAR: <ANY> >
+}
+
+*/
Added: james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressParseTest.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressParseTest.java?rev=575440&view=auto
==============================================================================
--- james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressParseTest.java (added)
+++ james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressParseTest.java Thu Sep 13 13:28:31 2007
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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.junit;
+
+import junit.framework.TestCase;
+
+import org.apache.jsieve.junit.utils.JUnitUtils;
+import org.apache.jsieve.junit.utils.SieveMailAdapter;
+
+public class AddressParseTest extends TestCase {
+
+ private static final String MULTIPLE_ADDRESS_VALUES =
+ "coyote@desert.example.org, bugs@example.org, elmer@hunters.example.org";
+
+ private static final String SOLO_ADDRESS_VALUES =
+ "coyote@desert.example.org";
+
+ SieveMailAdapter mail;
+ OpenedAddress address;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mail = (SieveMailAdapter) JUnitUtils.createMail();
+ address = new OpenedAddress();
+ }
+
+ public void testSingleAddress() throws Exception {
+ mail.getMessage().addHeader("From", SOLO_ADDRESS_VALUES);
+ assertTrue(address.match(mail, ":all", "i;ascii-casemap", ":is", "from", "coyote@desert.example.org"));
+ assertFalse(address.match(mail, ":all", "i;ascii-casemap", ":is", "from","elmer@hunters.example.org"));
+ assertFalse(address.match(mail, ":all", "i;ascii-casemap", ":is", "from", "bugs@example.org"));
+ assertFalse(address.match(mail, ":all", "i;ascii-casemap", ":is", "from", "roadrunner@example.org"));
+ }
+
+ public void testMultipleAddresses() throws Exception {
+ mail.getMessage().addHeader("From", MULTIPLE_ADDRESS_VALUES);
+ assertTrue(address.match(mail, ":all", "i;ascii-casemap", ":is", "from", "coyote@desert.example.org"));
+ assertTrue(address.match(mail, ":all", "i;ascii-casemap", ":is", "from","elmer@hunters.example.org"));
+ assertTrue(address.match(mail, ":all", "i;ascii-casemap", ":is", "from", "bugs@example.org"));
+ assertFalse(address.match(mail, ":all", "i;ascii-casemap", ":is", "from", "roadrunner@example.org"));
+ }
+}
Modified: james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressTest.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressTest.java?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressTest.java (original)
+++ james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/AddressTest.java Thu Sep 13 13:28:31 2007
@@ -138,7 +138,7 @@
try
{
SieveMailAdapter mail = (SieveMailAdapter) JUnitUtils.createMail();
- mail.getMessage().addHeader("From ", "user@domain");
+ mail.getMessage().addHeader("From ", "user@domain");
JUnitUtils.interpret(mail, script);
}
catch (MessagingException e)
Added: james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/MultipleToTest.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/MultipleToTest.java?rev=575440&view=auto
==============================================================================
--- james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/MultipleToTest.java (added)
+++ james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/MultipleToTest.java Thu Sep 13 13:28:31 2007
@@ -0,0 +1,90 @@
+/****************************************************************
+ * 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.junit;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+import java.io.StringReader;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.jsieve.util.check.ScriptChecker;
+
+public class MultipleToTest extends TestCase {
+
+ private static final String SOLO_TO_EMAIL =
+ "Date: Sun, 1 Apr 2007 1100:00:00 +0100 (BST)\r\f" +
+ "From: roadrunner@acme.example.com\r\f" +
+ "To: coyote@desert.example.org\r\f" +
+ "Subject: Who's The Fool?\r\f" +
+ "\r\f" +
+ "Beep-Beep\r\f";
+
+ private static final String MULTIPLE_TO_EMAIL =
+ "Date: Sun, 1 Apr 2007 1100:00:00 +0100 (BST)\r\f" +
+ "From: roadrunner@acme.example.com\r\f" +
+ "To: coyote@desert.example.org, bugs@example.org, " +
+ " elmer@hunters.example.org,\r\f" +
+ "Subject: Who's The Fool?\r\f" +
+ "\r\f" +
+ "Beep-Beep\r\f";
+
+ private static final String FILTER_SCRIPT = "require \"fileinto\";\r\f" +
+ "if address :is :all \"to\" \"coyote@desert.example.org\" {\r\f" +
+ " fileinto \"coyote\";\r\f}\r\f" +
+ "if address :is :all \"to\" \"bugs@example.org\" {\r\f" +
+ " fileinto \"bugs\";\r\f}\r\f" +
+ "if address :is :all \"to\" \"roadrunneracme.@example.org\" {\r\f" +
+ " fileinto \"rr\";\r\f}\r\f" +
+ "if address :is :all \"to\" \"elmer@hunters.example.org\" {\r\f" +
+ " fileinto \"elmer\";\r\f}\r\f";
+
+ public void testSingleTo() throws Exception {
+ ScriptChecker checker = new ScriptChecker();
+ ScriptChecker.Results results = checker.check(toStream(SOLO_TO_EMAIL), toStream(FILTER_SCRIPT));
+ if (results.getException() != null) {
+ fail(results.getException().toString());
+ }
+ final List actionsExecuted = results.getActionsExecuted();
+ assertEquals(1, actionsExecuted.size());
+ assertTrue(results.isActionFileInto("coyote", 0));
+ }
+
+ public void testMultipleTo() throws Exception {
+ ScriptChecker checker = new ScriptChecker();
+ ScriptChecker.Results results = checker.check(toStream(MULTIPLE_TO_EMAIL), toStream(FILTER_SCRIPT));
+ if (results.getException() != null) {
+ fail(results.getException().toString());
+ }
+ final List actionsExecuted = results.getActionsExecuted();
+ assertEquals(3, actionsExecuted.size());
+ assertTrue(results.isActionFileInto("coyote", 0));
+ assertTrue(results.isActionFileInto("bugs", 1));
+ assertTrue(results.isActionFileInto("elmer", 2));
+ }
+
+ private InputStream toStream(String in) throws Exception {
+ byte[] bytes = in.getBytes("US-ASCII");
+ ByteArrayInputStream result = new ByteArrayInputStream(bytes);
+ return result;
+ }
+}
Added: james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/OpenedAddress.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/OpenedAddress.java?rev=575440&view=auto
==============================================================================
--- james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/OpenedAddress.java (added)
+++ james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/OpenedAddress.java Thu Sep 13 13:28:31 2007
@@ -0,0 +1,32 @@
+/****************************************************************
+ * 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.junit;
+
+import org.apache.jsieve.SieveException;
+import org.apache.jsieve.mail.MailAdapter;
+import org.apache.jsieve.tests.Address;
+
+final class OpenedAddress extends Address {
+
+ protected boolean match(MailAdapter mail, String addressPart, String comparator, String matchType, String headerName, String key) throws SieveException {
+ return super.match(mail, addressPart, comparator, matchType, headerName, key);
+ }
+
+}
Modified: james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/utils/SieveMailAdapter.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/utils/SieveMailAdapter.java?rev=575440&r1=575439&r2=575440&view=diff
==============================================================================
--- james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/utils/SieveMailAdapter.java (original)
+++ james/jsieve/trunk/src/test/java/org/apache/jsieve/junit/utils/SieveMailAdapter.java Thu Sep 13 13:28:31 2007
@@ -42,6 +42,8 @@
import org.apache.jsieve.mail.MailAdapter;
import org.apache.jsieve.mail.MailUtils;
import org.apache.jsieve.mail.SieveMailException;
+import org.apache.jsieve.parser.address.SieveAddressBuilder;
+import org.apache.jsieve.parser.generated.address.ParseException;
/**
* <p>Class SieveMailAdapter implements a mock MailAdapter for testing purposes.</p>
@@ -277,6 +279,10 @@
{
throw new SieveMailException(ex);
}
+ }
+
+ public Address[] parseAddresses(final String headerName) throws SieveMailException {
+ return SieveAddressBuilder.parseAddresses(headerName, getMessage());
}
Added: james/jsieve/trunk/src/test/java/org/apache/jsieve/parser/address/SieveAddressBuilderTest.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/src/test/java/org/apache/jsieve/parser/address/SieveAddressBuilderTest.java?rev=575440&view=auto
==============================================================================
--- james/jsieve/trunk/src/test/java/org/apache/jsieve/parser/address/SieveAddressBuilderTest.java (added)
+++ james/jsieve/trunk/src/test/java/org/apache/jsieve/parser/address/SieveAddressBuilderTest.java Thu Sep 13 13:28:31 2007
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.parser.address;
+
+import org.apache.jsieve.mail.MailAdapter.Address;
+import org.apache.jsieve.parser.generated.address.ParseException;
+
+import junit.framework.TestCase;
+
+public class SieveAddressBuilderTest extends TestCase {
+
+ public static final String DOMAIN = "example.org";
+ public static final String COYOTE = "coyote";
+ public static final String COYOTE_ADDRESS = COYOTE + "@" + DOMAIN;
+ public static final String ROADRUNNER = "roadrunner";
+ public static final String ROADRUNNER_ADDRESS = ROADRUNNER + "@" + DOMAIN;
+ public static final String BUGS = "bugs";
+ public static final String BUGS_ADDRESS = BUGS + "@" + DOMAIN;
+ public static final String HEROS = ROADRUNNER_ADDRESS + " , " + BUGS_ADDRESS;
+
+ SieveAddressBuilder builder;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ builder = new SieveAddressBuilder();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testNotAddress() throws Exception {
+ try {
+ builder.addAddresses("What a load of rubbish - not an address in sight!");
+ fail("Parsing should fail when the input is not an address");
+ } catch (ParseException e) {
+ // expected
+ }
+ }
+
+ public void testAddAddresses() throws Exception {
+ assertNotNull(builder.getAddresses());
+ builder.addAddresses(COYOTE_ADDRESS);
+ Address[] addresses = builder.getAddresses();
+ assertNotNull(addresses);
+ assertEquals(1, addresses.length);
+ assertEquals(COYOTE, addresses[0].getLocalPart());
+ assertEquals(DOMAIN, addresses[0].getDomain());
+ builder.addAddresses(HEROS);
+ addresses = builder.getAddresses();
+ assertNotNull(addresses);
+ assertEquals(3, addresses.length);
+ assertEquals(COYOTE, addresses[0].getLocalPart());
+ assertEquals(DOMAIN, addresses[0].getDomain());
+ assertEquals(ROADRUNNER, addresses[1].getLocalPart());
+ assertEquals(DOMAIN, addresses[1].getDomain());
+ assertEquals(BUGS, addresses[2].getLocalPart());
+ assertEquals(DOMAIN, addresses[2].getDomain());
+ }
+
+ public void testReset() throws Exception {
+ assertNotNull(builder.getAddresses());
+ builder.addAddresses(COYOTE_ADDRESS);
+ Address[] addresses = builder.getAddresses();
+ assertNotNull(addresses);
+ assertEquals(1, addresses.length);
+ assertEquals(COYOTE, addresses[0].getLocalPart());
+ assertEquals(DOMAIN, addresses[0].getDomain());
+ addresses = builder.getAddresses();
+ assertNotNull(addresses);
+ assertEquals(1, addresses.length);
+ assertEquals(COYOTE, addresses[0].getLocalPart());
+ assertEquals(DOMAIN, addresses[0].getDomain());
+ builder.reset();
+ addresses = builder.getAddresses();
+ assertNotNull(addresses);
+ assertEquals(0, addresses.length);
+ builder.addAddresses(COYOTE_ADDRESS);
+ addresses = builder.getAddresses();
+ assertNotNull(addresses);
+ assertEquals(1, addresses.length);
+ assertEquals(COYOTE, addresses[0].getLocalPart());
+ assertEquals(DOMAIN, addresses[0].getDomain());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org