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  
21  
22  
23  package org.apache.james.management;
24  
25  import org.apache.oro.text.regex.MalformedPatternException;
26  import org.apache.oro.text.regex.Pattern;
27  import org.apache.oro.text.regex.Perl5Compiler;
28  
29  import java.util.HashMap;
30  import java.util.Iterator;
31  import java.util.Map;
32  
33  /**
34   * immutual collection of filters used to specify which mail should be processed by SpoolManagement
35   * criterias are:
36   * exact state match
37   * headerValue regular expressions match all related headers 
38   */
39  public class SpoolFilter {
40  
41      public static final String ERROR_STATE = "error";
42      
43      public static final SpoolFilter ERRORMAIL_FILTER = new SpoolFilter(ERROR_STATE);
44  
45      private String state = null;
46  
47      /**
48       * Map<String headerName, String headerValueRegex>
49       */
50      private final Map headerFilters = new HashMap();
51  
52      /**
53       * Map<String headerName, Pattern>
54       */
55      private final Map headerFiltersCompiled = new HashMap();
56  
57      /**
58       * Construct the SpoolFilter
59       * 
60       * @param state the message state on which message the filter should be used
61       * @param header the headername on which the given regex should be used
62       * @param headerValueRegex the regex to use on the value of the given header
63       */
64      public SpoolFilter(String state, String header, String headerValueRegex) {
65          this.state = state;
66          if (header != null) headerFilters.put(header, headerValueRegex);
67      }
68  
69      /**
70       * Construct the SpoolFilter
71       * 
72       * @param state the message state on which message the filter should be used
73       */
74      public SpoolFilter(String state) {
75          this.state = state;
76      }
77  
78      /**
79       * Construct the SpoolFilter
80       * 
81       * @param header the headername on which the given regex should be used
82       * @param headerValueRegex the regex to use on the value of the given header
83       */
84      public SpoolFilter(String header, String headerValueRegex) {
85          this.state = null;
86          if (header != null) headerFilters.put(header, headerValueRegex);
87      }
88  
89      /**
90       * Construct the SpoolFilter
91       * 
92       * @param state the message state on which message the filter should be used
93       * @param headerFilters a Map which contains filters to use
94       */
95      public SpoolFilter(String state, Map headerFilters) {
96          this.state = state;
97          this.headerFilters.putAll(headerFilters);
98          this.headerFilters.remove(null); // NULL is not acceptable here
99      }
100 
101     public boolean doFilter() {
102         return doFilterHeader() || doFilterState();
103     }
104 
105     /**
106      * Return true if any state was given on init the SpoolFilter
107      * 
108      * @return true if state was given on init. False otherwise 
109      */
110     public boolean doFilterState() {
111         return state != null;
112     }
113 
114     /**
115      * Return true if any filters should be used on the headers
116      * 
117      * @return true if filters should be used. False if not
118      */
119     public boolean doFilterHeader() {
120         return headerFilters.size() > 0;
121     }
122 
123     /**
124      * Return the message state on which the filter will be used
125      * 
126      * @return state the message state
127      */
128     public String getState() {
129         return state;
130     }
131 
132     /**
133      * Return an Iterator which contains all headers which should be filtered
134      * 
135      * @return headers an Iterator which contains all headers which should be filtered
136      */
137     public Iterator getHeaders() {
138         return headerFilters.keySet().iterator();
139     }
140 
141     /**
142      * Return the regex which should be used on the given header. 
143      * Return null if the header not exists in the Map
144      * 
145      * @param header the headername for which the regex should be retrieven. 
146      * @return regex the regex for the given header
147      */
148     public String getHeaderValueRegex(String header) {
149         return (String) headerFilters.get(header);
150     }
151 
152     /**
153      * Return the compiled Pattern for the given header. 
154      * Return null if the header not exists in the Map
155      * 
156      * @param header the header for which the pattern should be returned
157      * @return pattern the Pattern which was compiled for the given header
158      * @throws SpoolManagementException get thrown if an invalid regex is used with the given header
159      */
160     public Pattern getHeaderValueRegexCompiled(String header) throws SpoolManagementException {
161         Perl5Compiler compiler = new Perl5Compiler();
162 
163         // try to reuse cached pattern
164         if (headerFiltersCompiled.get(header) != null) return (Pattern)headerFiltersCompiled.get(header); 
165 
166         String headerValueRegex = getHeaderValueRegex(header);
167         if (headerValueRegex == null) return null;
168         try {
169             Pattern pattern = compiler.compile(headerValueRegex, Perl5Compiler.READ_ONLY_MASK);
170             headerFiltersCompiled.put(header, pattern); // cache
171             return pattern;
172         } catch (MalformedPatternException e) {
173             throw new SpoolManagementException("failed to compile regular expression", e);
174         }
175     }
176     
177 }