001    /*
002     * Copyright 2010 the original author or authors.
003     * 
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package com.hs.mail.mailet;
017    
018    import java.util.ArrayList;
019    import java.util.Iterator;
020    import java.util.List;
021    import java.util.Set;
022    
023    import javax.mail.MessagingException;
024    import javax.mail.internet.AddressException;
025    
026    import org.apache.commons.collections.CollectionUtils;
027    import org.apache.commons.lang.StringUtils;
028    import org.apache.log4j.Logger;
029    
030    import com.hs.mail.container.config.Config;
031    import com.hs.mail.imap.user.Alias;
032    import com.hs.mail.imap.user.User;
033    import com.hs.mail.smtp.message.Recipient;
034    import com.hs.mail.smtp.message.SmtpMessage;
035    
036    /**
037     * 
038     * @author Won Chul Doh
039     * @since Jun 24, 2010
040     * 
041     */
042    public class AliasingForwarding extends AbstractMailet {
043            
044            static Logger logger = Logger.getLogger(AliasingForwarding.class);
045    
046            public boolean accept(Set<Recipient> recipients, SmtpMessage message) {
047                    return CollectionUtils.isNotEmpty(recipients);
048            }
049    
050            public void service(Set<Recipient> recipients, SmtpMessage message)
051                            throws MessagingException {
052                    List<Recipient> newRecipients = new ArrayList<Recipient>();
053                    List<Recipient> errors = new ArrayList<Recipient>();
054                    for (Iterator<Recipient> it = recipients.iterator(); it.hasNext();) {
055                            Recipient rcpt = it.next();
056                            User user = getUserManager().getUserByAddress(rcpt.getMailbox());
057                            if (user != null) {
058                                    if (StringUtils.isNotEmpty(user.getForwardTo())) {
059                                            // Forwarding takes precedence over local aliases
060                                            try {
061                                                    // TODO optionally remove the original recipient
062                                                    it.remove();
063                                                    Recipient forwardTo = new Recipient(user.getForwardTo(), false);
064                                                    if (Config.isLocal(forwardTo.getHost())) {
065                                                            long id = getUserManager().getUserID(forwardTo.getMailbox());
066                                                            if (id != 0) {
067                                                                    forwardTo.setID(id);
068                                                                    newRecipients.add(forwardTo);
069                                                            } else {
070                                                                    throw new AddressException(
071                                                                                    "Forwarding address not found.");
072                                                            }
073                                                    } else {
074                                                            message.setNode(SmtpMessage.ALL);
075                                                            message.addRecipient(forwardTo);
076                                                    }
077                                            } catch (Exception e) {
078                                                    // Forwarding address is invalid or not found.
079                                                    StringBuffer errorBuffer =
080                                                            new StringBuffer(128)
081                                                                    .append("Failed to forwarding ")
082                                                                    .append(rcpt.getMailbox())
083                                                                    .append(" to ")
084                                                                    .append(user.getForwardTo());
085                                                    logger.error(errorBuffer.toString());
086                                                    errors.add(rcpt);
087                                            }
088                                    } else {
089                                            rcpt.setID(user.getID());
090                                    }
091                            } else {
092                                    // Try to find aliases
093                                    List<Alias> expanded = getUserManager().expandAlias(rcpt.getMailbox());
094                                    it.remove();
095                                    if (CollectionUtils.isNotEmpty(expanded)) {
096                                            for (Alias alias : expanded) {
097                                                    newRecipients.add(new Recipient((Long) alias
098                                                                    .getDeliverTo(), (String) alias.getUserID(),
099                                                                    false));
100                                            }
101                                    } else {
102                                            StringBuffer errorBuffer = 
103                                                    new StringBuffer(64)
104                                                            .append("Permanent exception delivering mail (")
105                                                            .append(message.getName())
106                                            .append("): ")
107                                            .append("Account for ")
108                                            .append(rcpt.getMailbox())
109                                            .append(" not found");
110                                            logger.error(errorBuffer.toString());
111                                            errors.add(rcpt);
112                                    }
113                            }
114                    }
115    
116                    if (newRecipients.size() > 0) {
117                            recipients.addAll(newRecipients);
118                    }
119            }
120    
121    }