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 }