View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.jsieve.tests;
21  
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.ListIterator;
25  
26  import org.apache.jsieve.Arguments;
27  import org.apache.jsieve.SieveContext;
28  import org.apache.jsieve.StringListArgument;
29  import org.apache.jsieve.TagArgument;
30  import org.apache.jsieve.comparators.ComparatorNames;
31  import org.apache.jsieve.comparators.MatchTypeTags;
32  import org.apache.jsieve.exception.SieveException;
33  import org.apache.jsieve.exception.SyntaxException;
34  import org.apache.jsieve.mail.MailAdapter;
35  import org.apache.jsieve.mail.SieveMailException;
36  
37  public abstract class AbstractCompatatorTest extends AbstractTest implements
38          AddressPartTags, ComparatorTags, MatchTypeTags, ComparatorNames {
39  
40      public AbstractCompatatorTest() {
41          super();
42      }
43  
44      /**
45       * <p>
46       * From RFC 3028, Section 5.1...
47       * </p>
48       * <code>  
49       * Syntax: address [ADDRESS-PART] [COMPARATOR] [MATCH-TYPE]
50       *         &lt;header-list: string-list&gt; &lt;key-list: string-list&gt;
51       * </code>
52       * <p>
53       * Note that the spec. then goes on to give an example where the order of
54       * the optional parts is different, so I am assuming that the order of the
55       * optional parts is optional too!
56       * </p>
57       * 
58       * @see org.apache.jsieve.tests.AbstractTest#executeBasic(MailAdapter,
59       *      Arguments, SieveContext)
60       */
61      protected boolean executeBasic(MailAdapter mail, Arguments arguments,
62              SieveContext context) throws SieveException {
63          String addressPart = null;
64          String comparator = null;
65          String matchType = null;
66          List headerNames = null;
67          List keys = null;
68  
69          ListIterator argumentsIter = arguments.getArgumentList().listIterator();
70          boolean stop = false;
71  
72          // Tag processing
73          while (!stop && argumentsIter.hasNext()) {
74              Object argument = argumentsIter.next();
75              if (argument instanceof TagArgument) {
76                  String tag = ((TagArgument) argument).getTag();
77  
78                  // [ADDRESS-PART]?
79                  if (null == addressPart
80                          && (tag.equals(LOCALPART_TAG) || tag.equals(DOMAIN_TAG) || tag
81                                  .equals(ALL_TAG)))
82                      addressPart = tag;
83                  // [COMPARATOR]?
84                  else if (null == comparator && tag.equals(COMPARATOR_TAG)) {
85                      // The next argument must be a stringlist
86                      if (argumentsIter.hasNext()) {
87                          argument = argumentsIter.next();
88                          if (argument instanceof StringListArgument) {
89                              List stringList = ((StringListArgument) argument)
90                                      .getList();
91                              if (stringList.size() != 1)
92                                  throw new SyntaxException(
93                                          "Expecting exactly one String");
94                              comparator = (String) stringList.get(0);
95                          } else
96                              throw new SyntaxException("Expecting a StringList");
97                      }
98                  }
99                  // [MATCH-TYPE]?
100                 else if (null == matchType
101                         && (tag.equals(IS_TAG) || tag.equals(CONTAINS_TAG) || tag
102                                 .equals(MATCHES_TAG)))
103                     matchType = tag;
104                 else
105                     throw context.getCoordinate().syntaxException(
106                             "Found unexpected TagArgument");
107             } else {
108                 // Stop when a non-tag argument is encountered
109                 argumentsIter.previous();
110                 stop = true;
111             }
112         }
113 
114         // The next argument MUST be a string-list of header names
115         if (argumentsIter.hasNext()) {
116             Object argument = argumentsIter.next();
117             if (argument instanceof StringListArgument)
118                 headerNames = ((StringListArgument) argument).getList();
119         }
120         if (null == headerNames)
121             throw context.getCoordinate().syntaxException(
122                     "Expecting a StringList of header names");
123 
124         // The next argument MUST be a string-list of keys
125         if (argumentsIter.hasNext()) {
126             Object argument = argumentsIter.next();
127             if (argument instanceof StringListArgument)
128                 keys = ((StringListArgument) argument).getList();
129         } else if (null == keys)
130             throw context.getCoordinate().syntaxException(
131                     "Expecting a StringList of keys");
132 
133         if (argumentsIter.hasNext())
134             throw context.getCoordinate().syntaxException(
135                     "Found unexpected arguments");
136 
137         return match(mail, (addressPart == null ? ALL_TAG : addressPart),
138                 (comparator == null ? ASCII_CASEMAP_COMPARATOR : comparator),
139                 (matchType == null ? IS_TAG : matchType), headerNames, keys,
140                 context);
141     }
142 
143     /**
144      * Method match.
145      * 
146      * @param mail
147      * @param addressPart
148      * @param comparator
149      * @param matchType
150      * @param headerNames
151      * @param keys
152      * @param context
153      *            TODO
154      * @return boolean
155      * @throws SieveMailException
156      */
157     protected boolean match(MailAdapter mail, String addressPart,
158             String comparator, String matchType, List headerNames, List keys,
159             SieveContext context) throws SieveException {
160         // Iterate over the header names looking for a match
161         boolean isMatched = false;
162         Iterator headerNamesIter = headerNames.iterator();
163         while (!isMatched && headerNamesIter.hasNext()) {
164             isMatched = match(mail, addressPart, comparator, matchType,
165                     (String) headerNamesIter.next(), keys, context);
166         }
167         return isMatched;
168     }
169 
170     /**
171      * Method match.
172      * 
173      * @param mail
174      * @param addressPart
175      * @param comparator
176      * @param matchType
177      * @param headerName
178      * @param keys
179      * @param context
180      *            TODO
181      * @return boolean
182      * @throws SieveMailException
183      */
184     protected boolean match(MailAdapter mail, String addressPart,
185             String comparator, String matchType, String headerName, List keys,
186             SieveContext context) throws SieveException {
187         // Iterate over the keys looking for a match
188         boolean isMatched = false;
189         Iterator keysIter = keys.iterator();
190         while (!isMatched && keysIter.hasNext()) {
191             isMatched = match(mail, addressPart, comparator, matchType,
192                     headerName, (String) keysIter.next(), context);
193         }
194         return isMatched;
195     }
196 
197     /**
198      * Method match.
199      * 
200      * @param mail
201      * @param addressPart
202      * @param comparator
203      * @param matchType
204      * @param headerName
205      * @param key
206      * @param context
207      *            TODO
208      * @return boolean
209      * @throws SieveMailException
210      */
211     protected abstract boolean match(MailAdapter mail, String addressPart,
212             String comparator, String matchType, String headerName, String key,
213             SieveContext context) throws SieveException;
214 
215     /**
216      * @see org.apache.jsieve.tests.AbstractTest#validateArguments(Arguments,
217      *      SieveContext)
218      */
219     protected void validateArguments(Arguments arguments, SieveContext context)
220             throws SieveException {
221         if (arguments.hasTests())
222             throw context.getCoordinate().syntaxException(
223                     "Found unexpected tests");
224     }
225 
226 }