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 rd...@apache.org on 2008/12/23 23:33:48 UTC
svn commit: r729150 -
/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/
Author: rdonkin
Date: Tue Dec 23 14:33:48 2008
New Revision: 729150
URL: http://svn.apache.org/viewvc?rev=729150&view=rev
Log:
Revise dispatch in favour of a system that uses interfaces (rather than reflection). Introduced ActionContext to group minor parameters together.
Added:
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionContext.java
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionUtils.java
- copied, changed from r729074, james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/Actions.java
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/FileIntoAction.java
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/KeepAction.java
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/MailAction.java
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RedirectAction.java
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RejectAction.java
Removed:
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/Actions.java
Modified:
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionDispatcher.java
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailAdapter.java
james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailboxMailet.java
Added: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionContext.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionContext.java?rev=729150&view=auto
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionContext.java (added)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionContext.java Tue Dec 23 14:33:48 2008
@@ -0,0 +1,65 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.jsieve.mailet;
+
+import java.util.Collection;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.logging.Log;
+import org.apache.mailet.MailAddress;
+
+/**
+ * Provides context for action execution.
+ */
+public interface ActionContext {
+
+ /**
+ * Gets the log.
+ * @return not null
+ */
+ public Log getLog();
+
+ /**
+ * Experimental mail delivery.
+ * POST verb indicate that mail should be attached to the collection
+ * indicated by the given URI.
+ *
+ * @param uri indicates the destination to which the mail to added. ATM
+ * the value should be mailbox://<user>@localhost/<mailbox-path>
+ * @param mail not null
+ */
+ public void post(String uri, MimeMessage mail) throws MessagingException;
+
+ /**
+ * Posts the given mail.
+ * @param sender possibly null
+ * @param recipients not null
+ * @param mail not null
+ * @throws MessagingException when mail cannot be posted
+ */
+ public void post(MailAddress sender, Collection recipients, MimeMessage mail) throws MessagingException;
+
+ /**
+ * Gets name (including version) of this server.
+ * @return not nul
+ */
+ public String getServerInfo();
+}
Modified: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionDispatcher.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionDispatcher.java?rev=729150&r1=729149&r2=729150&view=diff
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionDispatcher.java (original)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionDispatcher.java Tue Dec 23 14:33:48 2008
@@ -19,8 +19,6 @@
package org.apache.jsieve.mailet;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
@@ -32,19 +30,18 @@
import org.apache.jsieve.mail.ActionRedirect;
import org.apache.jsieve.mail.ActionReject;
import org.apache.mailet.Mail;
-import org.apache.mailet.MailetContext;
/**
- * Singleton Class <code>ActionDispatcher</code> dynamically dispatches
- * an Action depending on the type of Action received at runtime.
+ * Dynamically dispatches an Action depending on the type of Action received at runtime.
*/
public class ActionDispatcher
{
/**
* A Map keyed by the type of Action. The values are the methods to invoke to
* handle the Action.
+ * <Action, MailAction>
*/
- private Map fieldMethodMap;
+ private Map/*<Action, MailAction>*/ fieldMailActionMap;
/**
* Constructor for ActionDispatcher.
@@ -55,104 +52,50 @@
super();
setMethodMap(defaultMethodMap());
}
-
+
/**
* Method execute executes the passed Action by invoking the method mapped by the
* receiver with a parameter of the EXACT type of Action.
- * @param anAction
- * @param aMail
- * @param aMailetContext
- * @throws NoSuchMethodException
- * @throws IllegalAccessException
- * @throws InvocationTargetException
+ * @param anAction not null
+ * @param aMail not null
+ * @param context not null
* @throws MessagingException
*/
- public void execute(
- Action anAction,
- Mail aMail,
- MailetContext aMailetContext)
- throws
- NoSuchMethodException,
- IllegalAccessException,
- InvocationTargetException,
- MessagingException
+ public void execute(final Action anAction, final Mail aMail, final ActionContext context) throws MessagingException
{
- Method actionMethod = (Method) getMethodMap().get(anAction.getClass());
- if (null == actionMethod)
- throw new NoSuchMethodException(
- "Method accepting parameters ("
- + anAction.getClass().getName()
- + ", "
- + aMail.getClass().getName()
- + ", "
- + aMailetContext.getClass().getName()
- + ") not mapped.");
- actionMethod.invoke(
- null,
- new Object[] { anAction, aMail, aMailetContext });
+ MailAction mailAction = (MailAction) getMethodMap().get(anAction.getClass());
+ mailAction.execute(anAction, aMail, context);
}
-
+
/**
* Returns the methodMap.
* @return Map
*/
public Map getMethodMap()
{
- return fieldMethodMap;
+ return fieldMailActionMap;
}
-
+
/**
* Returns a new methodMap.
* @return Map
*/
- private Map defaultMethodMap() throws MessagingException
+ private Map defaultMethodMap()
{
- try {
- Map methodNameMap = new HashMap();
- methodNameMap.put(
- ActionFileInto.class,
- Actions.class.getMethod(
- "execute",
- new Class[] {
- ActionFileInto.class,
- Mail.class,
- MailetContext.class }));
- methodNameMap.put(
- ActionKeep.class,
- Actions.class.getMethod(
- "execute",
- new Class[] {
- ActionKeep.class,
- Mail.class,
- MailetContext.class }));
- methodNameMap.put(
- ActionRedirect.class,
- Actions.class.getMethod(
- "execute",
- new Class[] {
- ActionRedirect.class,
- Mail.class,
- MailetContext.class }));
- methodNameMap.put(
- ActionReject.class,
- Actions.class.getMethod(
- "execute",
- new Class[] {
- ActionReject.class,
- Mail.class,
- MailetContext.class }));
- return methodNameMap;
- } catch (NoSuchMethodException e) {
- throw new MessagingException("Require method missing from action.", e);
- }
+ Map/*<Action, MailAction>*/ actionMap = new HashMap/*<Action, MailAction>*/(4);
+ actionMap.put(ActionFileInto.class, new FileIntoAction());
+ actionMap.put(ActionKeep.class, new KeepAction());
+ actionMap.put(ActionRedirect.class, new RedirectAction());
+ actionMap.put(ActionReject.class, new RejectAction());
+ return actionMap;
}
/**
- * Sets the methodMap.
- * @param methodMap The methodMap to set
+ * Sets the mail action mail.
+ * @param mailActionMap <Action, MailAction> not null
*/
- protected void setMethodMap(Map methodMap)
+ protected void setMethodMap(Map/*<Action, MailAction>*/ mailActionMap)
{
- fieldMethodMap = methodMap;
+ fieldMailActionMap = mailActionMap;
}
}
Copied: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionUtils.java (from r729074, james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/Actions.java)
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionUtils.java?p2=james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionUtils.java&p1=james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/Actions.java&r1=729074&r2=729150&rev=729150&view=diff
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/Actions.java (original)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/ActionUtils.java Tue Dec 23 14:33:48 2008
@@ -19,267 +19,18 @@
package org.apache.jsieve.mailet;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import javax.mail.Address;
import javax.mail.MessagingException;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-import org.apache.mailet.base.mail.mdn.ActionModeAutomatic;
-import org.apache.mailet.base.mail.mdn.Disposition;
-import org.apache.mailet.base.mail.mdn.DispositionModifier;
-import org.apache.mailet.base.mail.mdn.MDNFactory;
-import org.apache.mailet.base.mail.mdn.ModifierError;
-import org.apache.mailet.base.mail.mdn.SendingModeAutomatic;
-import org.apache.mailet.base.mail.mdn.TypeDeleted;
-import org.apache.jsieve.mail.ActionFileInto;
-import org.apache.jsieve.mail.ActionKeep;
-import org.apache.jsieve.mail.ActionRedirect;
-import org.apache.jsieve.mail.ActionReject;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
-import org.apache.mailet.MailetContext;
/**
- * Singleton Class <code>Actions</code> implements <code>execute()</code>
- * methods for each of the supported Actions.
+ * Utility methods helpful for actions.
*/
-public class Actions
+public class ActionUtils
{
- private static final String INBOX = "INBOX";
- private static final char HIERARCHY_DELIMITER = '.';
- static private String fieldAttributePrefix;
-
- /**
- * Constructor for Actions.
- */
- private Actions()
- {
- super();
- }
-
- /**
- * <p>
- * Executes the passed ActionFileInto.
- * </p>
- *
- * <p>
- * This implementation accepts any destination with the root of <code>INBOX</code>.
- * </p>
- *
- * <p>
- * As the current POP3 server does not support sub-folders, the mail is
- * stored in the INBOX for the recipient of the mail and the full intended
- * destination added as a prefix to the message's subject.
- * </p>
- *
- * <p>
- * When IMAP support is added to James, it will be possible to support
- * sub-folders of <code>INBOX</code> fully.
- * </p>
- *
- * @param anAction
- * @param aMail
- * @param aMailetContext
- * @param poster TODO
- * @throws MessagingException
- */
- static public void execute(ActionFileInto anAction, Mail aMail,
- MailetContext aMailetContext, Poster poster) throws MessagingException
- {
- String destinationMailbox = anAction.getDestination();
- MailAddress recipient;
- boolean delivered = false;
- try
- {
- recipient = getSoleRecipient(aMail);
- MimeMessage localMessage = createMimeMessage(aMail, recipient);
-
- if (!(destinationMailbox.length() > 0
- && destinationMailbox.charAt(0) == HIERARCHY_DELIMITER)) {
- destinationMailbox = HIERARCHY_DELIMITER + destinationMailbox;
- }
-
- final String url = "mailbox://" + recipient.getUser() + "@localhost/" +
- destinationMailbox.replace(HIERARCHY_DELIMITER, '/');
- //TODO: copying this message so many times seems a waste
- poster.post(url, localMessage);
- delivered = true;
- }
- catch (MessagingException ex)
- {
- aMailetContext.log("Error while storing mail into. "+destinationMailbox, ex);
- throw ex;
- }
- finally
- {
- // Ensure the mail is always ghosted
- aMail.setState(Mail.GHOST);
- }
- if (delivered)
- {
- aMailetContext.log("Filed Message ID: "
- + aMail.getMessage().getMessageID()
- + " into destination: \""
- + destinationMailbox + "\"");
- }
- }
-
- private static MimeMessage createMimeMessage(Mail aMail, MailAddress recipient) throws MessagingException {
- // Adapted from LocalDelivery Mailet
- // Add qmail's de facto standard Delivered-To header
- MimeMessage localMessage = new MimeMessage(aMail.getMessage())
- {
- protected void updateHeaders() throws MessagingException
- {
- if (getMessageID() == null)
- super.updateHeaders();
- else
- modified = false;
- }
- };
- localMessage.addHeader("Delivered-To", recipient.toString());
-
- localMessage.saveChanges();
- return localMessage;
- }
-
- /**
- * <p>
- * Executes the passed ActionKeep.
- * </p>
- *
- * <p>
- * In this implementation, "keep" is equivalent to "fileinto" with a
- * destination of "INBOX".
- * </p>
- *
- * @param anAction
- * @param aMail
- * @param aMailetContext
- * @throws MessagingException
- */
- public static void execute(ActionKeep anAction, Mail aMail,
- MailetContext aMailetContext, Poster poster) throws MessagingException
- {
- final ActionFileInto action = new ActionFileInto(INBOX);
- execute(action, aMail, aMailetContext, poster);
- }
-
- /**
- * Method execute executes the passed ActionRedirect.
- *
- * @param anAction
- * @param aMail
- * @param aMailetContext
- * @throws MessagingException
- */
- public static void execute(ActionRedirect anAction, Mail aMail,
- MailetContext aMailetContext) throws MessagingException
- {
- detectAndHandleLocalLooping(aMail, aMailetContext, "redirect");
- Collection recipients = new ArrayList(1);
- recipients.add(new InternetAddress(anAction.getAddress()));
- aMailetContext.sendMail(aMail.getSender(), recipients, aMail
- .getMessage());
- aMail.setState(Mail.GHOST);
- aMailetContext.log("Redirected Message ID: "
- + aMail.getMessage().getMessageID() + " to \""
- + anAction.getAddress() + "\"");
- }
-
- /**
- * <p>
- * Method execute executes the passed ActionReject. It sends an RFC 2098
- * compliant reject MDN back to the sender.
- * </p>
- * <p>
- * NOTE: The Mimecontent type should be 'report', but as we do not yet have
- * a DataHandler for this yet, its currently 'text'!
- *
- * @param anAction
- * @param aMail
- * @param aMailetContext
- * @throws MessagingException
- */
- public static void execute(ActionReject anAction, Mail aMail,
- MailetContext aMailetContext) throws MessagingException
- {
- detectAndHandleLocalLooping(aMail, aMailetContext, "reject");
-
- // Create the MDN part
- StringBuffer humanText = new StringBuffer(128);
- humanText
- .append("This message was refused by the recipient's mail filtering program.");
- humanText.append("\r\n");
- humanText.append("The reason given was:");
- humanText.append("\r\n");
- humanText.append("\r\n");
- humanText.append(anAction.getMessage());
-
- String reporting_UA_name = null;
- try
- {
- reporting_UA_name = InetAddress.getLocalHost()
- .getCanonicalHostName();
- }
- catch (UnknownHostException ex)
- {
- reporting_UA_name = "localhost";
- }
-
- String reporting_UA_product = aMailetContext.getServerInfo();
-
- String[] originalRecipients = aMail.getMessage().getHeader(
- "Original-Recipient");
- String original_recipient = null;
- if (null != originalRecipients && originalRecipients.length > 0)
- {
- original_recipient = originalRecipients[0];
- }
-
- MailAddress soleRecipient = getSoleRecipient(aMail);
- String final_recipient = soleRecipient.toString();
-
- String original_message_id = aMail.getMessage().getMessageID();
-
- DispositionModifier modifiers[] = {new ModifierError()};
- Disposition disposition = new Disposition(new ActionModeAutomatic(),
- new SendingModeAutomatic(), new TypeDeleted(), modifiers);
-
- MimeMultipart multiPart = MDNFactory.create(humanText.toString(),
- reporting_UA_name, reporting_UA_product, original_recipient,
- final_recipient, original_message_id, disposition);
-
- // Send the message
- MimeMessage reply = (MimeMessage) aMail.getMessage().reply(false);
- reply.setFrom(soleRecipient.toInternetAddress());
- reply.setContent(multiPart);
- reply.saveChanges();
- Address[] recipientAddresses = reply.getAllRecipients();
- if (null != recipientAddresses)
- {
- Collection recipients = new ArrayList(recipientAddresses.length);
- for (int i = 0; i < recipientAddresses.length; i++)
- {
- recipients.add(new MailAddress(
- (InternetAddress) recipientAddresses[i]));
- }
- aMailetContext.sendMail(null, recipients, reply);
- }
- else
- {
- aMailetContext
- .log("Unable to send reject MDN. Could not determine the recipient.");
- }
- // Ghost the original mail
- aMail.setState(Mail.GHOST);
- }
+
+ private final static String ATTRIBUTE_PREFIX = ActionUtils.class.getPackage().getName() + ".";
/**
* Answers the sole intended recipient for aMail.
@@ -288,13 +39,12 @@
* @return String
* @throws MessagingException
*/
- protected static MailAddress getSoleRecipient(Mail aMail)
- throws MessagingException
+ public static MailAddress getSoleRecipient(Mail aMail) throws MessagingException
{
- if (aMail.getRecipients() == null) {
- throw new MessagingException("Invalid number of recipients - 0"
- + ". Exactly 1 recipient is expected.");
- } else if (1 != aMail.getRecipients().size())
+ if (aMail.getRecipients() == null) {
+ throw new MessagingException("Invalid number of recipients - 0"
+ + ". Exactly 1 recipient is expected.");
+ } else if (1 != aMail.getRecipients().size())
throw new MessagingException("Invalid number of recipients - "
+ new Integer(aMail.getRecipients().size()).toString()
+ ". Exactly 1 recipient is expected.");
@@ -302,84 +52,29 @@
}
/**
- * Returns a lazy initialised attributePrefix.
- *
- * @return String
- */
- protected static String getAttributePrefix()
- {
- String value = null;
- if (null == (value = getAttributePrefixBasic()))
- {
- updateAttributePrefix();
- return getAttributePrefix();
- }
- return value;
- }
-
- /**
- * Returns the attributePrefix.
- *
- * @return String
- */
- private static String getAttributePrefixBasic()
- {
- return fieldAttributePrefix;
- }
-
- /**
- * Returns the computed attributePrefix.
- *
- * @return String
- */
- protected static String computeAttributePrefix()
- {
- return Actions.class.getPackage().getName() + ".";
- }
-
- /**
- * Sets the attributePrefix.
- *
- * @param attributePrefix The attributePrefix to set
- */
- protected static void setAttributePrefix(String attributePrefix)
- {
- fieldAttributePrefix = attributePrefix;
- }
-
- /**
- * Updates the attributePrefix.
- */
- protected static void updateAttributePrefix()
- {
- setAttributePrefix(computeAttributePrefix());
- }
-
- /**
* Detect and handle locally looping mail. External loop detection is left
* to the MTA.
*
* @param aMail
- * @param aMailetContext
+ * @param context not null
* @param anAttributeSuffix
* @throws MessagingException
*/
- protected static void detectAndHandleLocalLooping(Mail aMail,
- MailetContext aMailetContext, String anAttributeSuffix)
+ public static void detectAndHandleLocalLooping(Mail aMail, ActionContext context, String anAttributeSuffix)
throws MessagingException
{
MailAddress thisRecipient = getSoleRecipient(aMail);
MailAddress lastRecipient = (MailAddress) aMail
- .getAttribute(getAttributePrefix() + anAttributeSuffix);
+ .getAttribute(ATTRIBUTE_PREFIX + anAttributeSuffix);
if (null != lastRecipient && lastRecipient.equals(thisRecipient))
{
MessagingException ex = new MessagingException(
"This message is looping! Message ID: "
+ aMail.getMessage().getMessageID());
- aMailetContext.log(ex.getMessage(), ex);
+ context.getLog().warn(ex.getMessage(), ex);
throw ex;
}
- aMail.setAttribute(getAttributePrefix() + anAttributeSuffix,
+ aMail.setAttribute(ATTRIBUTE_PREFIX + anAttributeSuffix,
thisRecipient);
}
}
Added: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/FileIntoAction.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/FileIntoAction.java?rev=729150&view=auto
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/FileIntoAction.java (added)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/FileIntoAction.java Tue Dec 23 14:33:48 2008
@@ -0,0 +1,130 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.jsieve.mailet;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.logging.Log;
+import org.apache.jsieve.mail.Action;
+import org.apache.jsieve.mail.ActionFileInto;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+
+public class FileIntoAction implements MailAction {
+
+ private static final char HIERARCHY_DELIMITER = '.';
+
+ public void execute(Action action, Mail mail, ActionContext context) throws MessagingException {
+ if (action instanceof ActionFileInto) {
+ final ActionFileInto fileIntoAction = (ActionFileInto) action;
+ execute(fileIntoAction, mail, context);
+ }
+ }
+
+ /**
+ * <p>
+ * Executes the passed ActionFileInto.
+ * </p>
+ *
+ * <p>
+ * This implementation accepts any destination with the root of <code>INBOX</code>.
+ * </p>
+ *
+ * <p>
+ * As the current POP3 server does not support sub-folders, the mail is
+ * stored in the INBOX for the recipient of the mail and the full intended
+ * destination added as a prefix to the message's subject.
+ * </p>
+ *
+ * <p>
+ * When IMAP support is added to James, it will be possible to support
+ * sub-folders of <code>INBOX</code> fully.
+ * </p>
+ *
+ * @param anAction
+ * @param aMail
+ * @param context not null
+ * @throws MessagingException
+ */
+ public void execute(ActionFileInto anAction, Mail aMail, final ActionContext context) throws MessagingException
+ {
+ String destinationMailbox = anAction.getDestination();
+ MailAddress recipient;
+ boolean delivered = false;
+ try
+ {
+ recipient = ActionUtils.getSoleRecipient(aMail);
+ MimeMessage localMessage = createMimeMessage(aMail, recipient);
+
+ if (!(destinationMailbox.length() > 0
+ && destinationMailbox.charAt(0) == HIERARCHY_DELIMITER)) {
+ destinationMailbox = HIERARCHY_DELIMITER + destinationMailbox;
+ }
+
+ final String url = "mailbox://" + recipient.getUser() + "@localhost/" +
+ destinationMailbox.replace(HIERARCHY_DELIMITER, '/');
+ //TODO: copying this message so many times seems a waste
+ context.post(url, localMessage);
+ delivered = true;
+ }
+ catch (MessagingException ex)
+ {
+ final Log log = context.getLog();
+ if (log.isDebugEnabled()) {
+ log.debug("Error while storing mail into. "+destinationMailbox, ex);
+ }
+ throw ex;
+ }
+ finally
+ {
+ // Ensure the mail is always ghosted
+ aMail.setState(Mail.GHOST);
+ }
+ if (delivered)
+ {
+ final Log log = context.getLog();
+ if (log.isDebugEnabled()) {
+ log.debug("Filed Message ID: "
+ + aMail.getMessage().getMessageID()
+ + " into destination: \""
+ + destinationMailbox + "\"");
+ }
+ }
+ }
+
+ private static MimeMessage createMimeMessage(Mail aMail, MailAddress recipient) throws MessagingException {
+ // Adapted from LocalDelivery Mailet
+ // Add qmail's de facto standard Delivered-To header
+ MimeMessage localMessage = new MimeMessage(aMail.getMessage())
+ {
+ protected void updateHeaders() throws MessagingException
+ {
+ if (getMessageID() == null)
+ super.updateHeaders();
+ else
+ modified = false;
+ }
+ };
+ localMessage.addHeader("Delivered-To", recipient.toString());
+
+ localMessage.saveChanges();
+ return localMessage;
+ }
+}
Added: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/KeepAction.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/KeepAction.java?rev=729150&view=auto
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/KeepAction.java (added)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/KeepAction.java Tue Dec 23 14:33:48 2008
@@ -0,0 +1,60 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.jsieve.mailet;
+
+import javax.mail.MessagingException;
+
+import org.apache.jsieve.mail.Action;
+import org.apache.jsieve.mail.ActionFileInto;
+import org.apache.jsieve.mail.ActionKeep;
+import org.apache.mailet.Mail;
+
+public class KeepAction extends FileIntoAction implements MailAction {
+
+ private static final String INBOX = "INBOX";
+
+ public void execute(Action action, Mail mail, ActionContext context)
+ throws MessagingException {
+ if (action instanceof ActionKeep) {
+ final ActionKeep actionKeep = (ActionKeep) action;
+ execute(actionKeep, mail, context);
+ }
+ }
+
+ /**
+ * <p>
+ * Executes the passed ActionKeep.
+ * </p>
+ *
+ * <p>
+ * In this implementation, "keep" is equivalent to "fileinto" with a
+ * destination of "INBOX".
+ * </p>
+ *
+ * @param anAction not null
+ * @param aMail not null
+ * @param context not null
+ * @throws MessagingException
+ */
+ public void execute(ActionKeep anAction, Mail aMail, ActionContext context) throws MessagingException
+ {
+ final ActionFileInto action = new ActionFileInto(INBOX);
+ execute(action, aMail, context);
+ }
+}
Added: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/MailAction.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/MailAction.java?rev=729150&view=auto
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/MailAction.java (added)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/MailAction.java Tue Dec 23 14:33:48 2008
@@ -0,0 +1,39 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.jsieve.mailet;
+
+import javax.mail.MessagingException;
+
+import org.apache.jsieve.mail.Action;
+import org.apache.mailet.Mail;
+
+/**
+ * Executes a Sieve action.
+ */
+public interface MailAction {
+
+ /**
+ * Executes the given action.
+ * @param action not null
+ * @param mail not null
+ * @param context not null
+ * @throws MessagingException when action cannot be executed
+ */
+ public void execute(final Action action, final Mail mail, final ActionContext context) throws MessagingException;
+}
Added: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RedirectAction.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RedirectAction.java?rev=729150&view=auto
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RedirectAction.java (added)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RedirectAction.java Tue Dec 23 14:33:48 2008
@@ -0,0 +1,67 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.jsieve.mailet;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+
+import org.apache.commons.logging.Log;
+import org.apache.jsieve.mail.Action;
+import org.apache.jsieve.mail.ActionRedirect;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+
+public class RedirectAction implements MailAction {
+
+ public void execute(Action action, Mail mail, ActionContext context)
+ throws MessagingException {
+ if (action instanceof ActionRedirect) {
+ final ActionRedirect actionRedirect = (ActionRedirect) action;
+ execute(actionRedirect, mail, context);
+ }
+
+ }
+
+ /**
+ * Method execute executes the passed ActionRedirect.
+ *
+ * @param anAction not nul
+ * @param aMail not null
+ * @param context not null
+ * @throws MessagingException
+ */
+ public void execute(ActionRedirect anAction, Mail aMail, ActionContext context) throws MessagingException
+ {
+ ActionUtils.detectAndHandleLocalLooping(aMail, context, "redirect");
+ Collection recipients = new ArrayList(1);
+ recipients.add(new InternetAddress(anAction.getAddress()));
+ MailAddress sender = aMail.getSender();
+ context.post(sender, recipients, aMail.getMessage());
+ aMail.setState(Mail.GHOST);
+ Log log = context.getLog();
+ if (log.isDebugEnabled()) {
+ log.debug("Redirected Message ID: "
+ + aMail.getMessage().getMessageID() + " to \""
+ + anAction.getAddress() + "\"");
+ }
+ }
+}
Added: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RejectAction.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RejectAction.java?rev=729150&view=auto
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RejectAction.java (added)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/RejectAction.java Tue Dec 23 14:33:48 2008
@@ -0,0 +1,141 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.jsieve.mailet;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.mail.Address;
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.jsieve.mail.Action;
+import org.apache.jsieve.mail.ActionReject;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+import org.apache.mailet.base.mail.mdn.ActionModeAutomatic;
+import org.apache.mailet.base.mail.mdn.Disposition;
+import org.apache.mailet.base.mail.mdn.DispositionModifier;
+import org.apache.mailet.base.mail.mdn.MDNFactory;
+import org.apache.mailet.base.mail.mdn.ModifierError;
+import org.apache.mailet.base.mail.mdn.SendingModeAutomatic;
+import org.apache.mailet.base.mail.mdn.TypeDeleted;
+
+public class RejectAction implements MailAction {
+
+ public void execute(Action action, Mail mail, ActionContext context)
+ throws MessagingException {
+ if (action instanceof ActionReject) {
+ final ActionReject actionReject = (ActionReject) action;
+ execute(actionReject, mail, context);
+ }
+
+ }
+
+ /**
+ * <p>
+ * Method execute executes the passed ActionReject. It sends an RFC 2098
+ * compliant reject MDN back to the sender.
+ * </p>
+ * <p>
+ * NOTE: The Mimecontent type should be 'report', but as we do not yet have
+ * a DataHandler for this yet, its currently 'text'!
+ *
+ * @param anAction not null
+ * @param aMail not null
+ * @param context not null
+ * @throws MessagingException
+ */
+ public void execute(ActionReject anAction, Mail aMail, ActionContext context) throws MessagingException
+ {
+ ActionUtils.detectAndHandleLocalLooping(aMail, context, "reject");
+
+ // Create the MDN part
+ StringBuffer humanText = new StringBuffer(128);
+ humanText
+ .append("This message was refused by the recipient's mail filtering program.");
+ humanText.append("\r\n");
+ humanText.append("The reason given was:");
+ humanText.append("\r\n");
+ humanText.append("\r\n");
+ humanText.append(anAction.getMessage());
+
+ String reporting_UA_name = null;
+ try
+ {
+ reporting_UA_name = InetAddress.getLocalHost()
+ .getCanonicalHostName();
+ }
+ catch (UnknownHostException ex)
+ {
+ reporting_UA_name = "localhost";
+ }
+
+ String reporting_UA_product = context.getServerInfo();
+
+ String[] originalRecipients = aMail.getMessage().getHeader(
+ "Original-Recipient");
+ String original_recipient = null;
+ if (null != originalRecipients && originalRecipients.length > 0)
+ {
+ original_recipient = originalRecipients[0];
+ }
+
+ MailAddress soleRecipient = ActionUtils.getSoleRecipient(aMail);
+ String final_recipient = soleRecipient.toString();
+
+ String original_message_id = aMail.getMessage().getMessageID();
+
+ DispositionModifier modifiers[] = {new ModifierError()};
+ Disposition disposition = new Disposition(new ActionModeAutomatic(),
+ new SendingModeAutomatic(), new TypeDeleted(), modifiers);
+
+ MimeMultipart multiPart = MDNFactory.create(humanText.toString(),
+ reporting_UA_name, reporting_UA_product, original_recipient,
+ final_recipient, original_message_id, disposition);
+
+ // Send the message
+ MimeMessage reply = (MimeMessage) aMail.getMessage().reply(false);
+ reply.setFrom(soleRecipient.toInternetAddress());
+ reply.setContent(multiPart);
+ reply.saveChanges();
+ Address[] recipientAddresses = reply.getAllRecipients();
+ if (null != recipientAddresses)
+ {
+ Collection recipients = new ArrayList(recipientAddresses.length);
+ for (int i = 0; i < recipientAddresses.length; i++)
+ {
+ recipients.add(new MailAddress(
+ (InternetAddress) recipientAddresses[i]));
+ }
+ context.post(null, recipients, reply);
+ }
+ else
+ {
+ context.getLog().info("Unable to send reject MDN. Could not determine the recipient.");
+ }
+ // Ghost the original mail
+ aMail.setState(Mail.GHOST);
+ }
+
+}
Modified: james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailAdapter.java
URL: http://svn.apache.org/viewvc/james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailAdapter.java?rev=729150&r1=729149&r2=729150&view=diff
==============================================================================
--- james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailAdapter.java (original)
+++ james/jsieve/trunk/mailet/src/main/java/org/apache/jsieve/mailet/SieveMailAdapter.java Tue Dec 23 14:33:48 2008
@@ -19,9 +19,9 @@
package org.apache.jsieve.mailet;
import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
@@ -30,10 +30,13 @@
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
+
import javax.mail.Header;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.james.mime4j.field.address.AddressList;
import org.apache.james.mime4j.field.address.Mailbox;
import org.apache.james.mime4j.field.address.MailboxList;
@@ -54,8 +57,12 @@
* for use in a Mailet environment.
* </p>
*/
-public class SieveMailAdapter implements MailAdapter, EnvelopeAccessors
+public class SieveMailAdapter implements MailAdapter, EnvelopeAccessors, ActionContext
{
+ private static final Log LOG = LogFactory.getLog(SieveMailAdapter.class);
+
+ private Log log = LOG;
+
/**
* The Mail being adapted.
*/
@@ -71,18 +78,27 @@
private final ActionDispatcher dispatcher;
+ private final Poster poster;
+
/**
* Constructor for SieveMailAdapter.
*
* @param aMail
* @param aMailetContext
*/
- public SieveMailAdapter(final Mail aMail, final MailetContext aMailetContext, final ActionDispatcher dispatcher)
+ public SieveMailAdapter(final Mail aMail, final MailetContext aMailetContext, final ActionDispatcher dispatcher, final Poster poster)
{
+ this.poster = poster;
this.dispatcher = dispatcher;
setMail(aMail);
setMailetContext(aMailetContext);
}
+
+
+ public void setLog(Log log) {
+ this.log = log;
+ }
+
/**
* Returns the message.
*
@@ -146,19 +162,7 @@
getMailetContext().log("Executing action: " + action.toString());
try
{
- dispatcher.execute(action, getMail(), getMailetContext());
- }
- catch (NoSuchMethodException e)
- {
- throw new SieveException(e);
- }
- catch (IllegalAccessException e)
- {
- throw new SieveException(e);
- }
- catch (InvocationTargetException e)
- {
- throw new SieveException(e);
+ dispatcher.execute(action, getMail(), this);
}
catch (MessagingException e)
{
@@ -439,4 +443,19 @@
return localPart;
}
}
+
+ public Log getLog() {
+ return log;
+ }
+
+ public String getServerInfo() {
+ return getMailetContext().getServerInfo();
+ }
+ public void post(String uri, MimeMessage mail) throws MessagingException {
+ poster.post(uri, mail);
+ }
+
+ public void post(MailAddress sender, Collection recipients, MimeMessage mail) throws MessagingException {
+ getMailetContext().sendMail(sender, recipients, mail);
+ }
}
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=729150&r1=729149&r2=729150&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 Tue Dec 23 14:33:48 2008
@@ -30,10 +30,10 @@
import javax.mail.internet.InternetHeaders;
import javax.mail.internet.MimeMessage;
+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.mail.MailAdapter;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
import org.apache.mailet.MailetConfig;
@@ -80,6 +80,8 @@
private ActionDispatcher actionDispatcher;
+ private Log log;
+
/**
* For SDI
*/
@@ -199,7 +201,8 @@
} else {
logLevel = CommonsLoggingAdapter.WARN;
}
- configurationManager.setLog(new CommonsLoggingAdapter(this, logLevel));
+ log = new CommonsLoggingAdapter(this, logLevel);
+ configurationManager.setLog(log);
factory = configurationManager.build();
} catch (SieveConfigurationException e) {
throw new MessagingException("Failed to load standard Sieve configuration.", e);
@@ -333,8 +336,9 @@
{
final InputStream ins = locator.get(relativeUri);
- MailAdapter aMailAdapter = new SieveMailAdapter(aMail,
- getMailetContext(), actionDispatcher);
+ SieveMailAdapter aMailAdapter = new SieveMailAdapter(aMail,
+ getMailetContext(), actionDispatcher, poster);
+ aMailAdapter.setLog(log);
// This logging operation is potentially costly
if (verbose) {
log("Evaluating " + aMailAdapter.toString() + "against \""
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org