You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by sb...@apache.org on 2012/01/25 18:28:47 UTC
svn commit: r1235842 - in /james/jsieve/trunk:
mailet/src/main/java/org/apache/jsieve/mailet/
main/src/main/java/org/apache/jsieve/
Author: sbrewin
Date: Wed Jan 25 17:28:47 2012
New Revision: 1235842
URL: http://svn.apache.org/viewvc?rev=1235842&view=rev
Log:
JSIEVE-78 Add a Mail notification mechanism for when Sieve scripts failAdd a Mail notification mechanism for when Sieve scripts fail
JSIEVE-80 Add the ability to advertise the available Sieve extensions
Modified:
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailboxMailet.java
james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManager.java
james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManagerImpl.java
james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java
james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java
james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java
james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManager.java
james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManagerImpl.java
Modified: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailboxMailet.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailboxMailet.java?rev=1235842&r1=1235841&r2=1235842&view=diff
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailboxMailet.java (original)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailboxMailet.java Wed Jan 25 17:28:47 2012
@@ -19,21 +19,33 @@
package org.apache.jsieve.mailet;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
+import java.util.Scanner;
import java.util.Vector;
+import javax.activation.DataHandler;
import javax.mail.Header;
import javax.mail.MessagingException;
import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.util.ByteArrayDataSource;
import org.apache.commons.logging.Log;
import org.apache.jsieve.ConfigurationManager;
import org.apache.jsieve.SieveConfigurationException;
import org.apache.jsieve.SieveFactory;
+import org.apache.jsieve.exception.SieveException;
+import org.apache.jsieve.parser.generated.ParseException;
+import org.apache.jsieve.parser.generated.TokenMgrError;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
import org.apache.mailet.MailetConfig;
@@ -54,7 +66,7 @@ import org.apache.mailet.base.RFC2822Hea
* </table>
*/
public class SieveMailboxMailet extends GenericMailet {
-
+
/**
* The delivery header
*/
@@ -315,7 +327,6 @@ public class SieveMailboxMailet extends
* @param mail
* @throws MessagingException
*/
- @SuppressWarnings("deprecation")
public void storeMail(MailAddress sender, MailAddress recipient,
Mail mail) throws MessagingException {
if (recipient == null) {
@@ -331,42 +342,49 @@ public class SieveMailboxMailet extends
}
- void sieveMessage(MailAddress recpient, Mail aMail) throws MessagingException {
- String username = getUsername(recpient);
- // Evaluate the script against the mail
- String relativeUri = "//" + username +"/sieve";
- try
- {
- final InputStream ins = locator.get(relativeUri);
-
- SieveMailAdapter aMailAdapter = new SieveMailAdapter(aMail,
- getMailetContext(), actionDispatcher, poster);
- aMailAdapter.setLog(log);
- // This logging operation is potentially costly
- if (verbose) {
- log("Evaluating " + aMailAdapter.toString() + "against \""
- + relativeUri + "\"");
- }
- factory.evaluate(aMailAdapter, factory.parse(ins));
- }
- catch (Exception ex)
- {
- //
- // SLIEVE is a mail filtering protocol.
+ protected void sieveMessage(MailAddress recipient, Mail aMail) throws MessagingException {
+ String username = getUsername(recipient);
+ try {
+ final InputStream ins = locator.get(getScriptUri(recipient));
+ sieveMessageEvaluate(recipient, aMail, ins);
+ } catch (Exception ex) {
+ // SIEVE is a mail filtering protocol.
// Rejecting the mail because it cannot be filtered
// seems very unfriendly.
- // So just log and store in INBOX.
- //
+ // So just log and store in INBOX
if (isInfoLoggingOn()) {
log("Cannot evaluate Sieve script. Storing mail in user INBOX.", ex);
}
- storeMessageInbox(username, aMail);
+ storeMessageInbox(username, aMail.getMessage());
}
}
- void storeMessageInbox(String username, Mail mail) throws MessagingException {
+ private void sieveMessageEvaluate(MailAddress recipient, Mail aMail, InputStream ins) throws MessagingException, IOException {
+ try {
+ SieveMailAdapter aMailAdapter = new SieveMailAdapter(aMail,
+ getMailetContext(), actionDispatcher, poster);
+ aMailAdapter.setLog(log);
+ // This logging operation is potentially costly
+ if (verbose) {
+ log("Evaluating " + aMailAdapter.toString() + "against \""
+ + getScriptUri(recipient) + "\"");
+ }
+ factory.evaluate(aMailAdapter, factory.parse(ins));
+ } catch (SieveException ex) {
+ handleFailure(recipient, aMail, ex);
+ }
+ catch (ParseException ex) {
+ handleFailure(recipient, aMail, ex);
+ }
+ catch (TokenMgrError ex)
+ {
+ handleFailure(recipient, aMail, new SieveException(ex));
+ }
+ }
+
+ protected void storeMessageInbox(String username, MimeMessage message) throws MessagingException {
String url = "mailbox://" + username + "/";
- poster.post(url, mail.getMessage());
+ poster.post(url, message);
}
/**
@@ -396,6 +414,62 @@ public class SieveMailboxMailet extends
* @return username
*/
protected String getUsername(MailAddress m) {
- return m.getLocalPart() + "@localhost";
+ return m.getLocalPart() + "@localhost";
+ }
+
+ /**
+ * Return the URI for the sieve script
+ *
+ * @param m
+ * @return
+ */
+ protected String getScriptUri(MailAddress m) {
+ return "//" + getUsername(m) + "/sieve";
}
+
+ /**
+ * Deliver the original mail as an attachment with the main part being an error report.
+ *
+ * @param recipient
+ * @param aMail
+ * @param ex
+ * @throws MessagingException
+ * @throws IOException
+ */
+ protected void handleFailure(MailAddress recipient, Mail aMail, Exception ex)
+ throws MessagingException, IOException {
+ String user = getUsername(recipient);
+
+ MimeMessage originalMessage = aMail.getMessage();
+ MimeMessage message = new MimeMessage(originalMessage);
+ MimeMultipart multipart = new MimeMultipart();
+
+ MimeBodyPart noticePart = new MimeBodyPart();
+ noticePart.setText(new StringBuilder()
+ .append("An error was encountered while processing this mail with the active sieve script for user \"")
+ .append(user)
+ .append("\". The error encountered was:\r\n")
+ .append(ex.getLocalizedMessage())
+ .append("\r\n")
+ .toString());
+ multipart.addBodyPart(noticePart);
+
+ MimeBodyPart originalPart = new MimeBodyPart();
+ originalPart.setContent(originalMessage, "message/rfc822");
+ if ((originalMessage.getSubject() != null) && (!originalMessage.getSubject().trim().isEmpty())) {
+ originalPart.setFileName(originalMessage.getSubject().trim());
+ } else {
+ originalPart.setFileName("No Subject");
+ }
+ originalPart.setDisposition(MimeBodyPart.INLINE);
+ multipart.addBodyPart(originalPart);
+
+ message.setContent(multipart);
+ message.setSubject("[SIEVE ERROR] " + originalMessage.getSubject());
+ message.setHeader("X-Priority", "1");
+ message.saveChanges();
+
+ storeMessageInbox(user, message);
+ }
+
}
Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManager.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManager.java?rev=1235842&r1=1235841&r2=1235842&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManager.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManager.java Wed Jan 25 17:28:47 2012
@@ -19,6 +19,8 @@
package org.apache.jsieve;
+import java.util.List;
+
import org.apache.jsieve.exception.LookupException;
/**
@@ -49,4 +51,11 @@ public interface CommandManager {
* @return boolean - True if the Command name is configured.
*/
public boolean isCommandSupported(String name);
+
+ /**
+ * Answer a List of the names of supported Sieve extensions.
+ *
+ * @return
+ */
+ public List<String> getExtensions();
}
Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManagerImpl.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManagerImpl.java?rev=1235842&r1=1235841&r2=1235842&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManagerImpl.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/CommandManagerImpl.java Wed Jan 25 17:28:47 2012
@@ -19,18 +19,28 @@
package org.apache.jsieve;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.ConcurrentMap;
import org.apache.jsieve.exception.LookupException;
/**
- * <p>Maps command names to comman implementations.</p>
+ * <p>Maps command names to common implementations.</p>
* <h4>Thread Safety</h4>
* <p>
* Instances may safely be accessed concurrently by multiple threads.
* </p>
*/
public class CommandManagerImpl implements CommandManager {
+
+ private static List<String> IMPLICITLY_DECLARED = Arrays.asList("if", "else", "elsif",
+ "require", "stop", "keep", "discard", "redirect");
+
+ private static boolean isImplicitlyDeclared(String name) {
+ return IMPLICITLY_DECLARED.contains(name);
+ }
private final ConcurrentMap<String, String> classNameMap;
@@ -123,4 +133,19 @@ public class CommandManagerImpl implemen
+ "' not mapped.");
return className;
}
+
+ /**
+ * @see org.apache.jsieve.CommandManager#getExtensions()
+ */
+ public List<String> getExtensions() {
+ List<String> extensions = new ArrayList<String>(classNameMap.size());
+ for (String key : classNameMap.keySet())
+ {
+ if (!isImplicitlyDeclared(key))
+ {
+ extensions.add(key);
+ }
+ }
+ return extensions;
+ }
}
Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java?rev=1235842&r1=1235841&r2=1235842&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManager.java Wed Jan 25 17:28:47 2012
@@ -19,6 +19,8 @@
package org.apache.jsieve;
+import java.util.List;
+
import org.apache.jsieve.comparators.Comparator;
import org.apache.jsieve.exception.LookupException;
@@ -56,4 +58,11 @@ public interface ComparatorManager {
* @return true when supported, false otherwise
*/
public boolean isSupported(String name);
+
+ /**
+ * Answer a List of the names of supported Sieve extensions.
+ *
+ * @return
+ */
+ public List<String> getExtensions();
}
Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java?rev=1235842&r1=1235841&r2=1235842&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/ComparatorManagerImpl.java Wed Jan 25 17:28:47 2012
@@ -22,6 +22,8 @@ package org.apache.jsieve;
import static org.apache.jsieve.Constants.COMPARATOR_ASCII_CASEMAP_NAME;
import static org.apache.jsieve.Constants.COMPARATOR_OCTET_NAME;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -162,4 +164,19 @@ public class ComparatorManagerImpl imple
return false;
}
}
+
+ /**
+ * @see org.apache.jsieve.ComparatorManager#getExtensions()
+ */
+ public List<String> getExtensions() {
+ List<String> extensions = new ArrayList<String>(classNameMap.size());
+ for (String key : classNameMap.keySet())
+ {
+ if (!isImplicitlyDeclared(key))
+ {
+ extensions.add(key);
+ }
+ }
+ return extensions;
+ }
}
Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java?rev=1235842&r1=1235841&r2=1235842&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/SieveFactory.java Wed Jan 25 17:28:47 2012
@@ -20,6 +20,8 @@
package org.apache.jsieve;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.jsieve.exception.SieveException;
@@ -198,4 +200,22 @@ public class SieveFactory {
throws ParseException, SieveException {
evaluate(mail, parse(inputStream));
}
+
+ /**
+ * <p>Answer a List of supported Sieve extensions. This depends on the configured Command, Comparator
+ * and Test managers.
+ *
+ * @return a List of supported Sieve extensions
+ */
+ public List<String> getExtensions() {
+ List<String> commands = commandManager.getExtensions();
+ List<String> comparators = comparatorManager.getExtensions();
+ List<String> tests = testManager.getExtensions();
+ List<String> extensions = new ArrayList<String>(commands.size() + comparators.size()
+ + tests.size());
+ extensions.addAll(commands);
+ extensions.addAll(comparators);
+ extensions.addAll(tests);
+ return extensions;
+ }
}
Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManager.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManager.java?rev=1235842&r1=1235841&r2=1235842&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManager.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManager.java Wed Jan 25 17:28:47 2012
@@ -19,6 +19,8 @@
package org.apache.jsieve;
+import java.util.List;
+
import org.apache.jsieve.exception.LookupException;
import org.apache.jsieve.tests.ExecutableTest;
@@ -40,4 +42,11 @@ public interface TestManager {
* @throws LookupException
*/
public ExecutableTest getTest(String name) throws LookupException;
+
+ /**
+ * Answer a List of the names of supported Sieve extensions.
+ *
+ * @return
+ */
+ public List<String> getExtensions();
}
Modified: james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManagerImpl.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManagerImpl.java?rev=1235842&r1=1235841&r2=1235842&view=diff
==============================================================================
--- james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManagerImpl.java (original)
+++ james/jsieve/trunk/main/src/main/java/org/apache/jsieve/TestManagerImpl.java Wed Jan 25 17:28:47 2012
@@ -19,6 +19,9 @@
package org.apache.jsieve;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.ConcurrentMap;
import org.apache.jsieve.exception.LookupException;
@@ -32,6 +35,13 @@ import org.apache.jsieve.tests.Executabl
* </p>
*/
public class TestManagerImpl implements TestManager {
+
+ private static List<String> IMPLICITLY_DECLARED = Arrays.asList("address",
+ "allof", "anyof", "exists", "false", "header", "not", "size", "true");
+
+ private static boolean isImplicitlyDeclared(String name) {
+ return IMPLICITLY_DECLARED.contains(name);
+ }
private final ConcurrentMap<String, String> classNameMap;
@@ -106,4 +116,20 @@ public class TestManagerImpl implements
throw new LookupException("Test named '" + name + "' not mapped.");
return className;
}
+
+ /**
+ * @see org.apache.jsieve.TestManager#getExtensions()
+ */
+ public List<String> getExtensions() {
+ List<String> extensions = new ArrayList<String>(classNameMap.size());
+ for (String key : classNameMap.keySet())
+ {
+ if (!isImplicitlyDeclared(key))
+ {
+ extensions.add(key);
+ }
+ }
+ return extensions;
+ }
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org