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 }