1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.transport.matchers;
23
24 import org.apache.mailet.base.GenericMatcher;
25 import org.apache.mailet.Mail;
26
27 import javax.mail.MessagingException;
28 import javax.mail.Multipart;
29 import javax.mail.Part;
30 import javax.mail.internet.MimeMessage;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.StringTokenizer;
35 import java.util.Locale;
36 import java.util.zip.ZipInputStream;
37 import java.util.zip.ZipEntry;
38 import java.io.UnsupportedEncodingException;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class AttachmentFileNameIs extends GenericMatcher {
56
57
58 protected static final String UNZIP_REQUEST_PARAMETER = "-z";
59
60
61 protected static final String DEBUG_REQUEST_PARAMETER = "-d";
62
63
64 protected static final String ZIP_SUFFIX = ".zip";
65
66
67
68
69 private static class Mask {
70
71 public boolean suffixMatch;
72
73
74 public String matchString;
75 }
76
77
78
79
80 protected boolean isDebug = false;
81
82
83 private Mask[] masks = null;
84
85
86 protected boolean unzipIsRequested;
87
88
89
90
91 public void init() throws MessagingException {
92
93
94 StringTokenizer st = new StringTokenizer(getCondition(), ", ", false);
95 ArrayList theMasks = new ArrayList(20);
96 while (st.hasMoreTokens()) {
97 String fileName = st.nextToken();
98
99
100 if (theMasks.size() == 0 && fileName.equalsIgnoreCase(UNZIP_REQUEST_PARAMETER)) {
101 unzipIsRequested = true;
102 log("zip file analysis requested");
103 continue;
104 }
105 if (theMasks.size() == 0 && fileName.equalsIgnoreCase(DEBUG_REQUEST_PARAMETER)) {
106 isDebug = true;
107 log("debug requested");
108 continue;
109 }
110 Mask mask = new Mask();
111 if (fileName.startsWith("*")) {
112 mask.suffixMatch = true;
113 mask.matchString = fileName.substring(1);
114 } else {
115 mask.suffixMatch = false;
116 mask.matchString = fileName;
117 }
118 mask.matchString = cleanFileName(mask.matchString);
119 theMasks.add(mask);
120 }
121 masks = (Mask[])theMasks.toArray(new Mask[0]);
122 }
123
124
125
126
127
128 public Collection match(Mail mail) throws MessagingException {
129
130 try {
131 MimeMessage message = mail.getMessage();
132
133 if (matchFound(message)) {
134 return mail.getRecipients();
135 } else {
136 return null;
137 }
138
139 } catch (Exception e) {
140 if (isDebug) {
141 log("Malformed message", e);
142 }
143 throw new MessagingException("Malformed message", e);
144 }
145 }
146
147
148
149
150 protected boolean matchFound(Part part) throws Exception {
151
152
153
154
155
156
157 if (part.getContentType() == null ||
158 part.getContentType().startsWith("multipart/alternative")) {
159 return false;
160 }
161
162 Object content;
163
164 try {
165 content = part.getContent();
166 } catch (UnsupportedEncodingException uee) {
167
168 return false;
169 }
170
171 Exception anException = null;
172
173 if (content instanceof Multipart) {
174 Multipart multipart = (Multipart) content;
175 for (int i = 0; i < multipart.getCount(); i++) {
176 try {
177 Part bodyPart = multipart.getBodyPart(i);
178 if (matchFound(bodyPart)) {
179 return true;
180 }
181 } catch (MessagingException e) {
182 anException = e;
183 }
184 }
185 } else {
186 String fileName = part.getFileName();
187 if (fileName != null) {
188 fileName = cleanFileName(fileName);
189
190 if (matchFound(fileName)) {
191 if (isDebug) {
192 log("matched " + fileName);
193 }
194 return true;
195 }
196 if (unzipIsRequested && fileName.endsWith(ZIP_SUFFIX) && matchFoundInZip(part)){
197 return true;
198 }
199 }
200 }
201
202
203 if (anException != null) {
204 throw anException;
205 }
206
207 return false;
208 }
209
210
211
212
213 protected boolean matchFound(String fileName) {
214 for (int j = 0; j < masks.length; j++) {
215 boolean fMatch;
216 Mask mask = masks[j];
217
218
219 if (mask.suffixMatch) {
220 fMatch = fileName.endsWith(mask.matchString);
221 } else {
222 fMatch = fileName.equals(mask.matchString);
223 }
224 if (fMatch) {
225 return true;
226 }
227 }
228 return false;
229 }
230
231
232
233
234 protected boolean matchFoundInZip(Part part) throws MessagingException, IOException {
235 ZipInputStream zis = new ZipInputStream(part.getInputStream());
236
237 try {
238 while (true) {
239 ZipEntry zipEntry = zis.getNextEntry();
240 if (zipEntry == null) {
241 break;
242 }
243 String fileName = zipEntry.getName();
244 if (matchFound(fileName)) {
245 if (isDebug) {
246 log("matched " + part.getFileName() + "(" + fileName + ")");
247 }
248 return true;
249 }
250 }
251 return false;
252 } finally {
253 zis.close();
254 }
255 }
256
257
258
259
260 protected String cleanFileName(String fileName) {
261 return fileName.toLowerCase(Locale.US).trim();
262 }
263 }
264