KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jsmtpd > plugins > filters > snippets > ReplaceSnippetFilter


1 /*
2  *
3  * Copyright (C) 2005 Pierre-Alexandre Losson, plosson@users.sourceforge.net
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  */

20 package org.jsmtpd.plugins.filters.snippets;
21
22 import java.io.BufferedReader JavaDoc;
23 import java.io.ByteArrayInputStream JavaDoc;
24 import java.io.ByteArrayOutputStream JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.FileReader JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.regex.Matcher JavaDoc;
32 import java.util.regex.Pattern JavaDoc;
33
34 import javax.mail.MessagingException JavaDoc;
35 import javax.mail.internet.MimeBodyPart JavaDoc;
36 import javax.mail.internet.MimeMessage JavaDoc;
37 import javax.mail.internet.MimeMultipart JavaDoc;
38 import javax.mail.internet.MimePart JavaDoc;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.jsmtpd.core.common.PluginInitException;
43 import org.jsmtpd.core.common.filter.FilterTreeFailureException;
44 import org.jsmtpd.core.common.filter.FilterTreeSuccesException;
45 import org.jsmtpd.core.common.filter.IFilter;
46 import org.jsmtpd.core.mail.Email;
47 import org.jsmtpd.tools.ByteArrayTool;
48
49 /**
50  * This filter adds a signature to mail bodies
51  *
52  * @author Pierre-Alexandre Losson, plosson@users.sourceforge.net
53  *
54  * jfp : format to jsmtpd coding style, added logs, relative path in patterns fix.
55  *
56  *
57  *
58  */

59 public class ReplaceSnippetFilter implements IFilter {
60
61     protected static final int BUFFER_SIZE = 5 * 1024; // 5k
62
protected static final String JavaDoc CR_LF = "\r\n";
63     protected static final String JavaDoc SNIPPET_RE = "[A-Za-z0-9]+";
64     private Log log = LogFactory.getLog(ReplaceSnippetFilter.class);
65
66     private String JavaDoc suffix;
67     private String JavaDoc prefix;
68     private String JavaDoc path;
69     private Pattern JavaDoc pattern;
70     private String JavaDoc encoding = "utf-8";
71     
72     public ReplaceSnippetFilter() {
73     }
74
75     public void setPath(String JavaDoc path) {
76         this.path = path;
77     }
78
79     public void setPrefix(String JavaDoc prefix) {
80         this.prefix = prefix;
81     }
82
83     public void setSuffix(String JavaDoc suffix) {
84         this.suffix = suffix;
85     }
86
87     public void initPlugin() throws PluginInitException {
88         pattern = Pattern.compile(prefix + "(" + SNIPPET_RE + ")" + suffix, Pattern.MULTILINE);
89         log.debug("Filter initialised with pattern " + pattern.pattern());
90     }
91
92     public boolean doFilter(Email input) throws FilterTreeFailureException, FilterTreeSuccesException {
93         try {
94             MimeMessage JavaDoc part = new MimeMessage JavaDoc(null, new ByteArrayInputStream JavaDoc(input.getDataAsByte()));
95             replaceSnippets(input.getFrom().getUser(), part);
96             part.saveChanges();
97             ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
98             part.writeTo(bos);
99             input.setDataBuffer(ByteArrayTool.crlfFix(bos.toByteArray()));
100         } catch (Exception JavaDoc e) {
101             log.error("An error occured", e);
102         }
103         return true;
104     }
105
106     private boolean replaceSnippets(String JavaDoc user, MimePart JavaDoc part) throws MessagingException JavaDoc, IOException JavaDoc {
107         if (part.isMimeType("text/plain")) {
108             addToText(user, part);
109             return true;
110         } else if (part.isMimeType("text/html")) {
111             addToHTML(user, part);
112             return true;
113         } else if (part.isMimeType("multipart/mixed")) {
114             MimeMultipart JavaDoc multipart = (MimeMultipart JavaDoc) part.getContent();
115             MimeBodyPart JavaDoc firstPart = (MimeBodyPart JavaDoc) multipart.getBodyPart(0);
116             boolean isFooterAttached = replaceSnippets(user, firstPart);
117             //We have to do this because of a bug in JavaMail (ref id 4404733)
118
part.setContent(multipart);
119             return isFooterAttached;
120         } else if (part.isMimeType("multipart/alternative")) {
121             MimeMultipart JavaDoc multipart = (MimeMultipart JavaDoc) part.getContent();
122             int count = multipart.getCount();
123             boolean isFooterAttached = false;
124             for (int index = 0; index < count; index++) {
125                 MimeBodyPart JavaDoc mimeBodyPart = (MimeBodyPart JavaDoc) multipart.getBodyPart(index);
126                 isFooterAttached |= replaceSnippets(user, mimeBodyPart);
127             }
128             //We have to do this because of a bug in JavaMail (ref id 4404733)
129
part.setContent(multipart);
130             return isFooterAttached;
131         } else {
132             //Give up... we won't attach the footer to this MimePart
133
log.error("Can't attach signature to mail ");
134             return false;
135         }
136     }
137
138     public String JavaDoc getPluginName() {
139         return "Replace Snippet Filter";
140     }
141
142     public void shutdownPlugin() {
143     }
144
145     /**
146      * Prepends the content of the MimePart as HTML to the existing footer
147      *
148      * @param part the MimePart to attach
149      * @throws javax.mail.MessagingException
150      * @throws java.io.IOException
151      */

152     protected void addToHTML(String JavaDoc user, MimePart JavaDoc part) throws MessagingException JavaDoc, IOException JavaDoc {
153         String JavaDoc content = part.getContent().toString();
154         part.setContent(replaceSnippets(user, content, "text/html"), part.getContentType());
155     }
156
157     protected void addToText(String JavaDoc user, MimePart JavaDoc part) throws MessagingException JavaDoc, IOException JavaDoc {
158         String JavaDoc content = part.getContent().toString();
159         part.setText(replaceSnippets(user, content, "text/plain"),encoding);
160     }
161
162     protected String JavaDoc replaceSnippets(String JavaDoc user, String JavaDoc content, String JavaDoc contentType) {
163         Matcher JavaDoc m = pattern.matcher(content);
164         Set JavaDoc<String JavaDoc> snippets = new HashSet JavaDoc<String JavaDoc>();
165         while (m.find()) {
166             String JavaDoc match = m.group(1);
167             if (hasSnippet(user, match, contentType)) {
168                 snippets.add(match);
169             }
170         }
171
172         Iterator JavaDoc<String JavaDoc> it = snippets.iterator();
173         String JavaDoc newContent = content;
174         while (it.hasNext()) {
175             String JavaDoc match = it.next();
176             String JavaDoc pattern = prefix + match + suffix;
177             String JavaDoc replace = getSnippet(user, match, contentType);
178             if (replace != null) {
179                 newContent = Pattern.compile(pattern, Pattern.MULTILINE).matcher(newContent).replaceAll(replace);
180             } else {
181                 log.error("Could not replace content for snippet" + match + " in " + contentType + " for user " + user);
182                 return content;
183             }
184         }
185         return newContent;
186     }
187
188     public boolean hasSnippet(String JavaDoc user, String JavaDoc pattern, String JavaDoc contentType) {
189         
190         if (pattern.contains("../"))
191             return false;
192         
193         String JavaDoc snippetPath = getSnippetPath(user, pattern, contentType);
194         boolean result = new File JavaDoc(snippetPath).exists();
195         if (!result) {
196             log.debug("Signature " + snippetPath + " not found");
197         }
198         return result;
199     }
200
201     public String JavaDoc getSnippet(String JavaDoc user, String JavaDoc pattern, String JavaDoc contentType) {
202         StringBuffer JavaDoc content = new StringBuffer JavaDoc();
203         try {
204             BufferedReader JavaDoc in = new BufferedReader JavaDoc(new FileReader JavaDoc(getSnippetPath(user, pattern, contentType)));
205             String JavaDoc str;
206             while ((str = in.readLine()) != null) {
207                 content.append(str);
208                 content.append(CR_LF);
209             }
210             in.close();
211         } catch (IOException JavaDoc e) {
212             log.error("Error getting snippet content", e);
213             return null;
214         }
215         return content.toString();
216     }
217
218     private String JavaDoc getSnippetPath(String JavaDoc user, String JavaDoc pattern, String JavaDoc contentType) {
219         String JavaDoc snippet = path + File.separator + user + File.separator + pattern;
220         if (contentType.equals("text/html"))
221             snippet = snippet + ".html";
222         else
223             snippet = snippet + ".txt";
224         return snippet;
225     }
226
227     public void setEncoding(String JavaDoc encoding) {
228         this.encoding = encoding;
229     }
230
231 }
232
Popular Tags