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-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org