1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.ai.classic;
21
22 import java.io.BufferedReader;
23 import java.io.ByteArrayOutputStream;
24 import java.io.StringReader;
25 import java.sql.Connection;
26 import java.util.Enumeration;
27
28 import javax.annotation.Resource;
29 import javax.mail.Header;
30 import javax.mail.MessagingException;
31 import javax.mail.internet.MimeMessage;
32 import javax.sql.DataSource;
33
34 import org.apache.mailet.Mail;
35 import org.apache.mailet.base.GenericMailet;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 public class BayesianAnalysisFeeder extends GenericMailet {
128
129
130
131 private final JDBCUtil theJDBCUtil = new JDBCUtil() {
132 protected void delegatedLog(String logString) {
133 log("BayesianAnalysisFeeder: " + logString);
134 }
135 };
136
137
138
139
140 private JDBCBayesianAnalyzer analyzer = new JDBCBayesianAnalyzer() {
141 protected void delegatedLog(String logString) {
142 log("BayesianAnalysisFeeder: " + logString);
143 }
144 };
145
146 private DataSource datasource;
147 private String repositoryPath;
148
149 private String feedType;
150
151
152
153
154
155
156 public String getMailetInfo() {
157 return "BayesianAnalysisFeeder Mailet";
158 }
159
160
161
162
163 private int maxSize = 100000;
164
165 private SystemContext fs;
166
167
168
169
170
171
172 public int getMaxSize() {
173
174 return this.maxSize;
175 }
176
177 @Resource(name = "datasource")
178 public void setDataSource(DataSource datasource) {
179 this.datasource = datasource;
180 }
181
182
183
184
185
186
187
188 public void setMaxSize(int maxSize) {
189
190 this.maxSize = maxSize;
191 }
192
193 @Resource(name = "filesystem")
194 public void setFileSystem(SystemContext fs) {
195 this.fs = fs;
196 }
197
198
199
200
201
202
203
204 public void init() throws MessagingException {
205 repositoryPath = getInitParameter("repositoryPath");
206
207 if (repositoryPath == null) {
208 throw new MessagingException("repositoryPath is null");
209 }
210
211 feedType = getInitParameter("feedType");
212 if (feedType == null) {
213 throw new MessagingException("feedType is null");
214 }
215
216 String maxSizeParam = getInitParameter("maxSize");
217 if (maxSizeParam != null) {
218 setMaxSize(Integer.parseInt(maxSizeParam));
219 }
220 log("maxSize: " + getMaxSize());
221
222 initDb();
223
224 }
225
226 private void initDb() throws MessagingException {
227
228 try {
229 analyzer.initSqlQueries(datasource.getConnection(), fs.readXml("sqlResources.xml"));
230 } catch (Exception e) {
231 throw new MessagingException("Exception initializing queries", e);
232 }
233
234 }
235
236
237
238
239
240
241
242
243
244
245 public void service(Mail mail) {
246 boolean dbUpdated = false;
247
248 mail.setState(Mail.GHOST);
249
250 ByteArrayOutputStream baos = new ByteArrayOutputStream();
251
252 Connection conn = null;
253
254 try {
255
256 MimeMessage message = mail.getMessage();
257
258 String messageId = message.getMessageID();
259
260 if (message.getSize() > getMaxSize()) {
261 log(messageId + " Feeding HAM/SPAM ignored because message size > " + getMaxSize() + ": " + message.getSize());
262 return;
263 }
264
265 clearAllHeaders(message);
266
267 message.writeTo(baos);
268
269 BufferedReader br = new BufferedReader(new StringReader(baos.toString()));
270
271
272 synchronized (JDBCBayesianAnalyzer.DATABASE_LOCK) {
273
274 conn = datasource.getConnection();
275
276 if (conn.getAutoCommit()) {
277 conn.setAutoCommit(false);
278 }
279
280 dbUpdated = true;
281
282
283 analyzer.clear();
284
285 if ("ham".equalsIgnoreCase(feedType)) {
286 log(messageId + " Feeding HAM");
287
288 analyzer.addHam(br);
289
290
291 analyzer.updateHamTokens(conn);
292 } else {
293 log(messageId + " Feeding SPAM");
294
295 analyzer.addSpam(br);
296
297
298 analyzer.updateSpamTokens(conn);
299 }
300
301
302 if (conn != null && dbUpdated && !conn.getAutoCommit()) {
303 conn.commit();
304 dbUpdated = false;
305 log(messageId + " Training ended successfully");
306 JDBCBayesianAnalyzer.touchLastDatabaseUpdateTime();
307 }
308
309 }
310
311 } catch (java.sql.SQLException se) {
312 log("SQLException: " + se.getMessage());
313 } catch (java.io.IOException ioe) {
314 log("IOException: " + ioe.getMessage());
315 } catch (javax.mail.MessagingException me) {
316 log("MessagingException: " + me.getMessage());
317 } finally {
318
319 try {
320 if (conn != null && dbUpdated && !conn.getAutoCommit()) {
321 conn.rollback();
322 dbUpdated = false;
323 }
324 } catch (Exception e) {
325 }
326 theJDBCUtil.closeJDBCConnection(conn);
327 }
328 }
329
330 private void clearAllHeaders(MimeMessage message) throws javax.mail.MessagingException {
331 @SuppressWarnings("rawtypes")
332 Enumeration headers = message.getAllHeaders();
333
334 while (headers.hasMoreElements()) {
335 Header header = (Header) headers.nextElement();
336 try {
337 message.removeHeader(header.getName());
338 } catch (javax.mail.MessagingException me) {
339 }
340 }
341 message.saveChanges();
342 }
343
344 }