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 no...@apache.org on 2010/01/23 13:27:45 UTC
svn commit: r902395 - in /james/server/trunk:
spoolmanager-function/src/main/java/org/apache/james/
spoolmanager-function/src/main/java/org/apache/james/transport/
spring-deployment/src/main/config/james/
Author: norman
Date: Sat Jan 23 12:27:44 2010
New Revision: 902395
URL: http://svn.apache.org/viewvc?rev=902395&view=rev
Log:
Seperate the implementation of MailetContext and MailServer (JAMES-958)
Added:
james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/JamesMailetContext.java
Modified:
james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/James.java
james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java
james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml
Modified: james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/James.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/James.java?rev=902395&r1=902394&r2=902395&view=diff
==============================================================================
--- james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/James.java (original)
+++ james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/James.java Sat Jan 23 12:27:44 2010
@@ -21,18 +21,32 @@
package org.apache.james;
-import org.apache.avalon.cornerstone.services.store.Store;
-import org.apache.avalon.framework.container.ContainerUtil;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.mail.Address;
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.ParseException;
+
+import org.apache.avalon.cornerstone.services.store.Store;
import org.apache.commons.collections.map.ReferenceMap;
import org.apache.commons.configuration.CombinedConfiguration;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.DefaultConfigurationBuilder;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.logging.Log;
-
import org.apache.james.api.dnsservice.DNSService;
-import org.apache.james.api.dnsservice.TemporaryResolutionException;
import org.apache.james.api.domainlist.DomainList;
import org.apache.james.api.domainlist.ManageableDomainList;
import org.apache.james.api.user.UsersRepository;
@@ -45,40 +59,9 @@
import org.apache.james.services.MailRepository;
import org.apache.james.services.MailServer;
import org.apache.james.services.SpoolRepository;
-import org.apache.james.transport.MailetConfigImpl;
-import org.apache.james.transport.mailets.LocalDelivery;
-import org.apache.mailet.HostAddress;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
import org.apache.mailet.Mailet;
-import org.apache.mailet.MailetContext;
-import org.apache.mailet.base.RFC2822Headers;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.Resource;
-import javax.mail.Address;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.ParseException;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.SequenceInputStream;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Vector;
/**
* Core class for JAMES. Provides three primary services:
@@ -93,7 +76,7 @@
*/
@SuppressWarnings("unchecked")
public class James
- implements MailServer, MailetContext, LogEnabled, Configurable {
+ implements MailServer, LogEnabled, Configurable {
/**
* The software name and version
@@ -144,10 +127,6 @@
private static int count = 0;
private static final Object countLock = new Object();
- /**
- * The address of the postmaster for this server
- */
- private MailAddress postmaster;
/**
* A map used to store mailboxes and reduce the cost of lookup of individual
@@ -160,7 +139,7 @@
* A hash table of server attributes
* These are the MailetContext attributes
*/
- private Hashtable<String,Object> attributes = new Hashtable<String,Object>();
+ //private Hashtable<String,Object> attributes = new Hashtable<String,Object>();
/**
* Currently used by storeMail to avoid code duplication (we moved store logic to that mailet).
@@ -182,7 +161,6 @@
private DNSService dns;
- private Log mailetLog;
/**
@@ -213,15 +191,6 @@
this.conf = (HierarchicalConfiguration)config;
}
-
- /**
- * This only needed till MailetContext get factored out of this class
- *
- * @param mailetLog
- */
- public void setMailetLog(Log mailetLog) {
- this.mailetLog = mailetLog;
- }
@PostConstruct
public void init() throws Exception {
@@ -260,7 +229,7 @@
}
}
- initializeServernamesAndPostmaster();
+ initializeServernames();
// We don't need this. UsersRepository.ROLE is already in the compMgr we received
// We've just looked up it from the cmpManager
@@ -295,7 +264,7 @@
// Should we use the defaultdomain here ?
helloName = conf.getString("helloName",defaultDomain);
}
- attributes.put(Constants.HELLO_NAME, helloName);
+ //attributes.put(Constants.HELLO_NAME, helloName);
}
//Temporary get out to allow complex mailet config files to stop blocking sergei sozonoff's work on bouce processing
@@ -304,18 +273,17 @@
// defaults to the old behaviour
if (confDir == null) confDir = "file://conf/";
java.io.File configDir = fileSystem.getFile(confDir);
- attributes.put("confDir", configDir.getCanonicalPath());
+ //attributes.put("confDir", configDir.getCanonicalPath());
+ /*
try {
- attributes.put(Constants.HOSTADDRESS, dns.getLocalHost().getHostAddress());
- attributes.put(Constants.HOSTNAME, dns.getLocalHost().getHostName());
+ //attributes.put(Constants.HOSTADDRESS, dns.getLocalHost().getHostAddress());
+ //attributes.put(Constants.HOSTNAME, dns.getLocalHost().getHostName());
} catch (java.net.UnknownHostException _) {
- attributes.put(Constants.HOSTADDRESS, "127.0.0.1");
- attributes.put(Constants.HOSTNAME, "localhost");
+ //attributes.put(Constants.HOSTADDRESS, "127.0.0.1");
+ //attributes.put(Constants.HOSTNAME, "localhost");
}
-
- initializeLocalDeliveryMailet();
-
+ */
System.out.println(SOFTWARE_NAME_VERSION);
logger.info("JAMES ...init end");
}
@@ -363,7 +331,7 @@
}
}
- private void initializeServernamesAndPostmaster() throws ConfigurationException, ParseException {
+ private void initializeServernames() throws ConfigurationException, ParseException {
String defaultDomain = getDefaultDomain();
if (domains.containsDomain(defaultDomain) == false) {
if (domains instanceof ManageableDomainList) {
@@ -378,51 +346,10 @@
if (serverNames == null || serverNames.size() == 0) throw new ConfigurationException("No domainnames configured");
- // used by RemoteDelivery for HELO
- attributes.put(Constants.DEFAULT_DOMAIN, defaultDomain);
-
- // Get postmaster
- String postMasterAddress = conf.getString("postmaster","postmaster").toLowerCase(Locale.US);
- // if there is no @domain part, then add the first one from the
- // list of supported domains that isn't localhost. If that
- // doesn't work, use the hostname, even if it is localhost.
- if (postMasterAddress.indexOf('@') < 0) {
- String domainName = null; // the domain to use
- // loop through candidate domains until we find one or exhaust the list
- Iterator<String> i = serverNames.iterator();
- while (i.hasNext()) {
- String serverName = i.next().toLowerCase(Locale.US);
- if (!("localhost".equals(serverName))) {
- domainName = serverName; // ok, not localhost, so use it
- continue;
- }
- }
- // if we found a suitable domain, use it. Otherwise fallback to the host name.
- postMasterAddress = postMasterAddress + "@" + (domainName != null ? domainName : defaultDomain);
- }
- this.postmaster = new MailAddress( postMasterAddress );
-
- if (!isLocalServer(postmaster.getDomain())) {
- StringBuffer warnBuffer
- = new StringBuffer(320)
- .append("The specified postmaster address ( ")
- .append(postmaster)
- .append(" ) is not a local address. This is not necessarily a problem, but it does mean that emails addressed to the postmaster will be routed to another server. For some configurations this may cause problems.");
- logger.warn(warnBuffer.toString());
- }
+
}
- private void initializeLocalDeliveryMailet() throws MessagingException {
- // We can safely remove this and the localDeliveryField when we
- // remove the storeMail method from James and from the MailetContext
- DefaultConfigurationBuilder conf = new DefaultConfigurationBuilder();
- MailetConfigImpl configImpl = new MailetConfigImpl();
- configImpl.setMailetName("LocalDelivery");
- configImpl.setConfiguration(conf);
- configImpl.setMailetContext(this);
- localDeliveryMailet = new LocalDelivery();
- localDeliveryMailet.init(configImpl);
- }
+
/**
* Set Store to use
@@ -483,23 +410,14 @@
*/
public void sendMail(MailAddress sender, Collection recipients, MimeMessage message)
throws MessagingException {
- sendMail(sender, recipients, message, Mail.DEFAULT);
- }
-
- /**
- * @see org.apache.mailet.MailetContext#sendMail(MailAddress, Collection, MimeMessage, String)
- */
- public void sendMail(MailAddress sender, Collection recipients, MimeMessage message, String state)
- throws MessagingException {
- MailImpl mail = new MailImpl(getId(), sender, recipients, message);
try {
- mail.setState(state);
- sendMail(mail);
- } finally {
- ContainerUtil.dispose(mail);
+ sendMail(sender, recipients, message.getInputStream());
+ } catch (IOException e) {
+ throw new MessagingException("Unable to send message",e);
}
}
+
/**
* @see org.apache.james.services.MailServer#sendMail(MailAddress, Collection, InputStream)
*/
@@ -656,193 +574,6 @@
System.out.println("Please refer to the Readme file to know how to run James.");
}
- //Methods for MailetContext
-
- /**
- * @see org.apache.mailet.MailetContext#getMailServers(String)
- */
- public Collection<String> getMailServers(String host) {
- try {
- return dns.findMXRecords(host);
- } catch (TemporaryResolutionException e) {
- //TODO: We only do this to not break backward compatiblity. Should fixed later
- return Collections.unmodifiableCollection(new ArrayList<String>(0));
- }
- }
-
- /**
- * @see org.apache.mailet.MailetContext#getAttribute(java.lang.String)
- */
- public Object getAttribute(String key) {
- return attributes.get(key);
- }
-
- /**
- * @see org.apache.mailet.MailetContext#setAttribute(java.lang.String, java.lang.Object)
- */
- public void setAttribute(String key, Object object) {
- attributes.put(key, object);
- }
-
- /**
- * @see org.apache.mailet.MailetContext#removeAttribute(java.lang.String)
- */
- public void removeAttribute(String key) {
- attributes.remove(key);
- }
-
- /**
- * @see org.apache.mailet.MailetContext#getAttributeNames()
- */
- public Iterator<String> getAttributeNames() {
- Vector<String> names = new Vector<String>();
- for (Enumeration e = attributes.keys(); e.hasMoreElements(); ) {
- names.add(e.nextElement().toString());
- }
- return names.iterator();
- }
-
- /**
- * This generates a response to the Return-Path address, or the address of
- * the message's sender if the Return-Path is not available. Note that
- * this is different than a mail-client's reply, which would use the
- * Reply-To or From header. This will send the bounce with the server's
- * postmaster as the sender.
- *
- * @see org.apache.mailet.MailetContext#bounce(Mail, String)
- */
- public void bounce(Mail mail, String message) throws MessagingException {
- bounce(mail, message, getPostmaster());
- }
-
- /**
- * This generates a response to the Return-Path address, or the
- * address of the message's sender if the Return-Path is not
- * available. Note that this is different than a mail-client's
- * reply, which would use the Reply-To or From header.
- *
- * Bounced messages are attached in their entirety (headers and
- * content) and the resulting MIME part type is "message/rfc822".
- *
- * The attachment to the subject of the original message (or "No
- * Subject" if there is no subject in the original message)
- *
- * There are outstanding issues with this implementation revolving
- * around handling of the return-path header.
- *
- * MIME layout of the bounce message:
- *
- * multipart (mixed)/
- * contentPartRoot (body) = mpContent (alternative)/
- * part (body) = message
- * part (body) = original
- *
- * @see org.apache.mailet.MailetContext#bounce(Mail, String, MailAddress)
- */
-
- public void bounce(Mail mail, String message, MailAddress bouncer) throws MessagingException {
- if (mail.getSender() == null) {
- if (logger.isInfoEnabled())
- logger.info("Mail to be bounced contains a null (<>) reverse path. No bounce will be sent.");
- return;
- } else {
- // Bounce message goes to the reverse path, not to the Reply-To address
- if (logger.isInfoEnabled())
- logger.info("Processing a bounce request for a message with a reverse path of " + mail.getSender().toString());
- }
-
- MailImpl reply = rawBounce(mail,message);
- //Change the sender...
- reply.getMessage().setFrom(bouncer.toInternetAddress());
- reply.getMessage().saveChanges();
- //Send it off ... with null reverse-path
- reply.setSender(null);
- sendMail(reply);
- ContainerUtil.dispose(reply);
- }
-
- /**
- * Generates a bounce mail that is a bounce of the original message.
- *
- * @param bounceText the text to be prepended to the message to describe the bounce condition
- *
- * @return the bounce mail
- *
- * @throws MessagingException if the bounce mail could not be created
- */
- private MailImpl rawBounce(Mail mail, String bounceText) throws MessagingException {
- //This sends a message to the james component that is a bounce of the sent message
- MimeMessage original = mail.getMessage();
- MimeMessage reply = (MimeMessage) original.reply(false);
- reply.setSubject("Re: " + original.getSubject());
- reply.setSentDate(new Date());
- Collection<MailAddress> recipients = new HashSet<MailAddress>();
- recipients.add(mail.getSender());
- InternetAddress addr[] = { new InternetAddress(mail.getSender().toString())};
- reply.setRecipients(Message.RecipientType.TO, addr);
- reply.setFrom(new InternetAddress(mail.getRecipients().iterator().next().toString()));
- reply.setText(bounceText);
- reply.setHeader(RFC2822Headers.MESSAGE_ID, "replyTo-" + mail.getName());
- return new MailImpl(
- "replyTo-" + mail.getName(),
- new MailAddress(mail.getRecipients().iterator().next().toString()),
- recipients,
- reply);
- }
-
- /**
- * @see org.apache.mailet.MailetContext#isLocalUser(String)
- */
- public boolean isLocalUser(String name) {
- if (name == null) {
- return false;
- }
- try {
- if (name.indexOf("@") == -1) {
- return isLocalEmail(new MailAddress(name,"localhost"));
- } else {
- return isLocalEmail(new MailAddress(name));
- }
- } catch (ParseException e) {
- log("Error checking isLocalUser for user "+name);
- return false;
- }
- }
-
- /**
- * @see org.apache.mailet.MailetContext#isLocalEmail(org.apache.mailet.MailAddress)
- */
- public boolean isLocalEmail(MailAddress mailAddress) {
- String userName = mailAddress.toString();
- if (!isLocalServer(mailAddress.getDomain())) {
- return false;
- }
- if (virtualHosting == false) {
- userName = mailAddress.getLocalPart();
- }
- return localusers.contains(userName);
- }
-
- /**
- * @see org.apache.mailet.MailetContext#getPostmaster()
- */
- public MailAddress getPostmaster() {
- return postmaster;
- }
-
- /**
- * @see org.apache.mailet.MailetContext#getMajorVersion()
- */
- public int getMajorVersion() {
- return 2;
- }
-
- /**
- * @see org.apache.mailet.MailetContext#getMinorVersion()
- */
- public int getMinorVersion() {
- return 4;
- }
/**
* @see org.apache.james.services.MailServer#isLocalServer(java.lang.String)
@@ -860,39 +591,6 @@
}
/**
- * @see org.apache.mailet.MailetContext#getServerInfo()
- */
- public String getServerInfo() {
- return "Apache JAMES";
- }
-
- /**
- * Return the logger for the Mailet API
- *
- * @return the logger for the Mailet API
- */
- private Log getMailetLogger() {
- if (mailetLog == null) {
- return logger;
- }
- return mailetLog;
- }
-
- /**
- * @see org.apache.mailet.MailetContext#log(java.lang.String)
- */
- public void log(String message) {
- getMailetLogger().info(message);
- }
-
- /**
- * @see org.apache.mailet.MailetContext#log(java.lang.String, java.lang.Throwable)
- */
- public void log(String message, Throwable t) {
- getMailetLogger().info(message,t);
- }
-
- /**
* Adds a user to this mail server. Currently just adds user to a
* UsersRepository.
*
@@ -910,54 +608,6 @@
}
/**
- * Performs DNS lookups as needed to find servers which should or might
- * support SMTP.
- * Returns an Iterator over HostAddress, a specialized subclass of
- * javax.mail.URLName, which provides location information for
- * servers that are specified as mail handlers for the given
- * hostname. This is done using MX records, and the HostAddress
- * instances are returned sorted by MX priority. If no host is
- * found for domainName, the Iterator returned will be empty and the
- * first call to hasNext() will return false.
- *
- * @see org.apache.james.api.dnsservice.DNSService#getSMTPHostAddresses(String)
- * @since Mailet API v2.2.0a16-unstable
- * @param domainName - the domain for which to find mail servers
- * @return an Iterator over HostAddress instances, sorted by priority
- */
- public Iterator<HostAddress> getSMTPHostAddresses(String domainName) {
- try {
- return dns.getSMTPHostAddresses(domainName);
- } catch (TemporaryResolutionException e) {
- //TODO: We only do this to not break backward compatiblity. Should fixed later
- return Collections.unmodifiableCollection(new ArrayList<HostAddress>(0)).iterator();
- }
- }
-
- /**
- * This method has been moved to LocalDelivery (the only client of the method).
- * Now we can safely remove it from the Mailet API and from this implementation of MailetContext.
- *
- * The local field localDeliveryMailet will be removed when we remove the storeMail method.
- *
- * @deprecated since 2.2.0 look at the LocalDelivery code to find out how to do the local delivery.
- * @see org.apache.mailet.MailetContext#storeMail(org.apache.mailet.MailAddress, org.apache.mailet.MailAddress, javax.mail.internet.MimeMessage)
- */
- public void storeMail(MailAddress sender, MailAddress recipient, MimeMessage msg) throws MessagingException {
- if (recipient == null) {
- throw new IllegalArgumentException("Recipient for mail to be spooled cannot be null.");
- }
- if (msg == null) {
- throw new IllegalArgumentException("Mail message to be spooled cannot be null.");
- }
- Collection<MailAddress> recipients = new HashSet<MailAddress>();
- recipients.add(recipient);
- MailImpl m = new MailImpl(getId(),sender,recipients,msg);
- localDeliveryMailet.service(m);
- ContainerUtil.dispose(m);
- }
-
- /**
* @see org.apache.james.services.MailServer#supportVirtualHosting()
*/
public boolean supportVirtualHosting() {
@@ -987,12 +637,16 @@
if (helloName != null) {
return helloName;
} else {
+ return getDefaultDomain();
+ /*
String hello = (String) getAttribute(Constants.HELLO_NAME);
+
if (hello == null) {
return defaultDomain;
} else {
return hello;
}
+ */
}
}
}
Added: james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/JamesMailetContext.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/JamesMailetContext.java?rev=902395&view=auto
==============================================================================
--- james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/JamesMailetContext.java (added)
+++ james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/JamesMailetContext.java Sat Jan 23 12:27:44 2010
@@ -0,0 +1,487 @@
+/****************************************************************
+ * 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.james;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.ParseException;
+
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.DefaultConfigurationBuilder;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.logging.Log;
+import org.apache.james.api.dnsservice.DNSService;
+import org.apache.james.api.dnsservice.TemporaryResolutionException;
+import org.apache.james.api.domainlist.DomainList;
+import org.apache.james.api.user.UsersRepository;
+import org.apache.james.core.MailImpl;
+import org.apache.james.lifecycle.Configurable;
+import org.apache.james.lifecycle.LogEnabled;
+import org.apache.james.services.MailServer;
+import org.apache.james.transport.MailetConfigImpl;
+import org.apache.james.transport.mailets.LocalDelivery;
+import org.apache.mailet.HostAddress;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+import org.apache.mailet.MailetContext;
+import org.apache.mailet.base.RFC2822Headers;
+
+public class JamesMailetContext implements MailetContext, LogEnabled, Configurable {
+
+ private MailServer mailServer;
+
+ /**
+ * A hash table of server attributes These are the MailetContext attributes
+ */
+ private Hashtable<String, Object> attributes = new Hashtable<String, Object>();
+ private DNSService dns;
+
+ private Log log;
+
+ private UsersRepository localusers;
+
+ private LocalDelivery localDeliveryMailet;
+
+ /**
+ * The address of the postmaster for this server
+ */
+ private MailAddress postmaster;
+
+ private DomainList domains;
+
+ private HierarchicalConfiguration conf;
+
+ @Resource(name = "James")
+ public void setMailServer(MailServer mailServer) {
+ this.mailServer = mailServer;
+ }
+
+ @Resource(name = "dnsserver")
+ public void setDNSService(DNSService dns) {
+ this.dns = dns;
+ }
+
+ @Resource(name = "localusersrepository")
+ public void setUsersRepository(UsersRepository localusers) {
+ this.localusers = localusers;
+ }
+
+ @Resource(name = "domainlist")
+ public void setDomainList(DomainList domains) {
+ this.domains = domains;
+ }
+
+ @PostConstruct
+ public void init() throws Exception {
+
+ // used by RemoteDelivery for HELO
+ attributes.put(Constants.DEFAULT_DOMAIN, mailServer.getDefaultDomain());
+
+ initializeLocalDeliveryMailet();
+
+ initPostmaster();
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#getMailServers(String)
+ */
+ public Collection<String> getMailServers(String host) {
+ try {
+ return dns.findMXRecords(host);
+ } catch (TemporaryResolutionException e) {
+ // TODO: We only do this to not break backward compatiblity. Should
+ // fixed later
+ return Collections.unmodifiableCollection(new ArrayList<String>(0));
+ }
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#getAttribute(java.lang.String)
+ */
+ public Object getAttribute(String key) {
+ return attributes.get(key);
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#setAttribute(java.lang.String,
+ * java.lang.Object)
+ */
+ public void setAttribute(String key, Object object) {
+ attributes.put(key, object);
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#removeAttribute(java.lang.String)
+ */
+ public void removeAttribute(String key) {
+ attributes.remove(key);
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#getAttributeNames()
+ */
+ public Iterator<String> getAttributeNames() {
+ Vector<String> names = new Vector<String>();
+ for (Enumeration e = attributes.keys(); e.hasMoreElements();) {
+ names.add(e.nextElement().toString());
+ }
+ return names.iterator();
+ }
+
+ /**
+ * This generates a response to the Return-Path address, or the address of
+ * the message's sender if the Return-Path is not available. Note that this
+ * is different than a mail-client's reply, which would use the Reply-To or
+ * From header. This will send the bounce with the server's postmaster as
+ * the sender.
+ *
+ * @see org.apache.mailet.MailetContext#bounce(Mail, String)
+ */
+ public void bounce(Mail mail, String message) throws MessagingException {
+ bounce(mail, message, getPostmaster());
+ }
+
+ /**
+ * This generates a response to the Return-Path address, or the address of
+ * the message's sender if the Return-Path is not available. Note that this
+ * is different than a mail-client's reply, which would use the Reply-To or
+ * From header.
+ *
+ * Bounced messages are attached in their entirety (headers and content) and
+ * the resulting MIME part type is "message/rfc822".
+ *
+ * The attachment to the subject of the original message (or "No Subject" if
+ * there is no subject in the original message)
+ *
+ * There are outstanding issues with this implementation revolving around
+ * handling of the return-path header.
+ *
+ * MIME layout of the bounce message:
+ *
+ * multipart (mixed)/ contentPartRoot (body) = mpContent (alternative)/ part
+ * (body) = message part (body) = original
+ *
+ * @see org.apache.mailet.MailetContext#bounce(Mail, String, MailAddress)
+ */
+
+ public void bounce(Mail mail, String message, MailAddress bouncer) throws MessagingException {
+ if (mail.getSender() == null) {
+ if (log.isInfoEnabled())
+ log.info("Mail to be bounced contains a null (<>) reverse path. No bounce will be sent.");
+ return;
+ } else {
+ // Bounce message goes to the reverse path, not to the Reply-To
+ // address
+ if (log.isInfoEnabled())
+ log.info("Processing a bounce request for a message with a reverse path of " + mail.getSender().toString());
+ }
+
+ MailImpl reply = rawBounce(mail, message);
+ // Change the sender...
+ reply.getMessage().setFrom(bouncer.toInternetAddress());
+ reply.getMessage().saveChanges();
+ // Send it off ... with null reverse-path
+ reply.setSender(null);
+ sendMail(reply);
+ ContainerUtil.dispose(reply);
+ }
+
+ /**
+ * Generates a bounce mail that is a bounce of the original message.
+ *
+ * @param bounceText
+ * the text to be prepended to the message to describe the bounce
+ * condition
+ *
+ * @return the bounce mail
+ *
+ * @throws MessagingException
+ * if the bounce mail could not be created
+ */
+ private MailImpl rawBounce(Mail mail, String bounceText) throws MessagingException {
+ // This sends a message to the james component that is a bounce of the
+ // sent message
+ MimeMessage original = mail.getMessage();
+ MimeMessage reply = (MimeMessage) original.reply(false);
+ reply.setSubject("Re: " + original.getSubject());
+ reply.setSentDate(new Date());
+ Collection<MailAddress> recipients = new HashSet<MailAddress>();
+ recipients.add(mail.getSender());
+ InternetAddress addr[] = { new InternetAddress(mail.getSender().toString()) };
+ reply.setRecipients(Message.RecipientType.TO, addr);
+ reply.setFrom(new InternetAddress(mail.getRecipients().iterator().next().toString()));
+ reply.setText(bounceText);
+ reply.setHeader(RFC2822Headers.MESSAGE_ID, "replyTo-" + mail.getName());
+ return new MailImpl("replyTo-" + mail.getName(), new MailAddress(mail.getRecipients().iterator().next().toString()), recipients, reply);
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#isLocalUser(String)
+ */
+ public boolean isLocalUser(String name) {
+ if (name == null) {
+ return false;
+ }
+ try {
+ if (name.indexOf("@") == -1) {
+ return isLocalEmail(new MailAddress(name, "localhost"));
+ } else {
+ return isLocalEmail(new MailAddress(name));
+ }
+ } catch (ParseException e) {
+ log("Error checking isLocalUser for user " + name);
+ return false;
+ }
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#isLocalEmail(org.apache.mailet.MailAddress)
+ */
+ public boolean isLocalEmail(MailAddress mailAddress) {
+ String userName = mailAddress.toString();
+ if (!isLocalServer(mailAddress.getDomain())) {
+ return false;
+ }
+ if (mailServer.supportVirtualHosting() == false) {
+ userName = mailAddress.getLocalPart();
+ }
+ return localusers.contains(userName);
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#getPostmaster()
+ */
+ public MailAddress getPostmaster() {
+ return postmaster;
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#getMajorVersion()
+ */
+ public int getMajorVersion() {
+ return 2;
+ }
+
+ /**
+ * @see org.apache.mailet.MailetContext#getMinorVersion()
+ */
+ public int getMinorVersion() {
+ return 4;
+ }
+
+ /**
+ * Performs DNS lookups as needed to find servers which should or might
+ * support SMTP. Returns an Iterator over HostAddress, a specialized
+ * subclass of javax.mail.URLName, which provides location information for
+ * servers that are specified as mail handlers for the given hostname. This
+ * is done using MX records, and the HostAddress instances are returned
+ * sorted by MX priority. If no host is found for domainName, the Iterator
+ * returned will be empty and the first call to hasNext() will return false.
+ *
+ * @see org.apache.james.api.dnsservice.DNSService#getSMTPHostAddresses(String)
+ * @since Mailet API v2.2.0a16-unstable
+ * @param domainName
+ * - the domain for which to find mail servers
+ * @return an Iterator over HostAddress instances, sorted by priority
+ */
+ public Iterator<HostAddress> getSMTPHostAddresses(String domainName) {
+ try {
+ return dns.getSMTPHostAddresses(domainName);
+ } catch (TemporaryResolutionException e) {
+ // TODO: We only do this to not break backward compatiblity. Should
+ // fixed later
+ return Collections.unmodifiableCollection(new ArrayList<HostAddress>(0)).iterator();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.mailet.MailetContext#getServerInfo()
+ */
+ public String getServerInfo() {
+ return "Apache JAMES";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.mailet.MailetContext#isLocalServer(java.lang.String)
+ */
+ public boolean isLocalServer(String name) {
+ return mailServer.isLocalServer(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.mailet.MailetContext#log(java.lang.String)
+ */
+ public void log(String arg0) {
+ log.info(arg0);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.mailet.MailetContext#log(java.lang.String, java.lang.Throwable)
+ */
+ public void log(String arg0, Throwable arg1) {
+ log.info(arg0, arg1);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.mailet.MailetContext#sendMail(javax.mail.internet.MimeMessage)
+ */
+ public void sendMail(MimeMessage message) throws MessagingException {
+ mailServer.sendMail(message);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.mailet.MailetContext#sendMail(org.apache.mailet.Mail)
+ */
+ public void sendMail(Mail mail) throws MessagingException {
+ mailServer.sendMail(mail);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.mailet.MailetContext#sendMail(org.apache.mailet.MailAddress, java.util.Collection, javax.mail.internet.MimeMessage)
+ */
+ public void sendMail(MailAddress sender, Collection recipients, MimeMessage msg) throws MessagingException {
+ mailServer.sendMail(sender, recipients, msg);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.mailet.MailetContext#sendMail(org.apache.mailet.MailAddress, java.util.Collection, javax.mail.internet.MimeMessage, java.lang.String)
+ */
+ public void sendMail(MailAddress sender, Collection recipients, MimeMessage message, String state) throws MessagingException {
+ MailImpl mail = new MailImpl(mailServer.getId(), sender, recipients, message);
+ try {
+ mail.setState(state);
+ sendMail(mail);
+ } finally {
+ ContainerUtil.dispose(mail);
+ }
+ }
+
+ private void initializeLocalDeliveryMailet() throws MessagingException {
+ // We can safely remove this and the localDeliveryField when we
+ // remove the storeMail method from James and from the MailetContext
+ DefaultConfigurationBuilder conf = new DefaultConfigurationBuilder();
+ MailetConfigImpl configImpl = new MailetConfigImpl();
+ configImpl.setMailetName("LocalDelivery");
+ configImpl.setConfiguration(conf);
+ configImpl.setMailetContext(this);
+ localDeliveryMailet = new LocalDelivery();
+ localDeliveryMailet.init(configImpl);
+ }
+
+ /**
+ * This method has been moved to LocalDelivery (the only client of the
+ * method). Now we can safely remove it from the Mailet API and from this
+ * implementation of MailetContext.
+ *
+ * The local field localDeliveryMailet will be removed when we remove the
+ * storeMail method.
+ *
+ * @deprecated since 2.2.0 look at the LocalDelivery code to find out how to
+ * do the local delivery.
+ * @see org.apache.mailet.MailetContext#storeMail(org.apache.mailet.MailAddress,
+ * org.apache.mailet.MailAddress, javax.mail.internet.MimeMessage)
+ */
+ public void storeMail(MailAddress sender, MailAddress recipient, MimeMessage msg) throws MessagingException {
+ if (recipient == null) {
+ throw new IllegalArgumentException("Recipient for mail to be spooled cannot be null.");
+ }
+ if (msg == null) {
+ throw new IllegalArgumentException("Mail message to be spooled cannot be null.");
+ }
+ Collection<MailAddress> recipients = new HashSet<MailAddress>();
+ recipients.add(recipient);
+ MailImpl m = new MailImpl(mailServer.getId(), sender, recipients, msg);
+ localDeliveryMailet.service(m);
+ ContainerUtil.dispose(m);
+ }
+
+ public void setLog(Log log) {
+ this.log = log;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.james.lifecycle.Configurable#configure(org.apache.commons.
+ * configuration.HierarchicalConfiguration)
+ */
+ public void configure(HierarchicalConfiguration conf) throws ConfigurationException {
+ this.conf = conf;
+ }
+
+ private void initPostmaster() throws Exception {
+ // Get postmaster
+ String postMasterAddress = conf.getString("postmaster", "postmaster").toLowerCase(Locale.US);
+ // if there is no @domain part, then add the first one from the
+ // list of supported domains that isn't localhost. If that
+ // doesn't work, use the hostname, even if it is localhost.
+ if (postMasterAddress.indexOf('@') < 0) {
+ String domainName = null; // the domain to use
+ // loop through candidate domains until we find one or exhaust the
+ // list
+ Iterator<String> i = domains.getDomains().iterator();
+ while (i.hasNext()) {
+ String serverName = i.next().toLowerCase(Locale.US);
+ if (!("localhost".equals(serverName))) {
+ domainName = serverName; // ok, not localhost, so use it
+ continue;
+ }
+ }
+ // if we found a suitable domain, use it. Otherwise fallback to the
+ // host name.
+ postMasterAddress = postMasterAddress + "@" + (domainName != null ? domainName : mailServer.getDefaultDomain());
+ }
+ this.postmaster = new MailAddress(postMasterAddress);
+
+ if (!isLocalServer(postmaster.getDomain())) {
+ StringBuffer warnBuffer = new StringBuffer(320).append("The specified postmaster address ( ").append(postmaster).append(
+ " ) is not a local address. This is not necessarily a problem, but it does mean that emails addressed to the postmaster will be routed to another server. For some configurations this may cause problems.");
+ log.warn(warnBuffer.toString());
+ }
+ }
+}
Modified: james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java
URL: http://svn.apache.org/viewvc/james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java?rev=902395&r1=902394&r2=902395&view=diff
==============================================================================
--- james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java (original)
+++ james/server/trunk/spoolmanager-function/src/main/java/org/apache/james/transport/AbstractLoader.java Sat Jan 23 12:27:44 2010
@@ -81,7 +81,7 @@
*
* @param mailetContext the MailetContext
*/
- @Resource(name="James")
+ @Resource(name="mailet")
public void setMailetContext(MailetContext mailetContext) {
this.mailetContext = mailetContext;
}
Modified: james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml
URL: http://svn.apache.org/viewvc/james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml?rev=902395&r1=902394&r2=902395&view=diff
==============================================================================
--- james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml (original)
+++ james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml Sat Jan 23 12:27:44 2010
@@ -91,7 +91,8 @@
<map>
<entry key="nntpserver.protocolserver" value="nntpserver" />
<entry key="nntpserver.protocolhandlerfactory" value="nntpserver" />
- <entry key="mailboxmanager" value="imapserver" />
+ <entry key="mailboxmanager" value="imapserver" />
+ <entry key="mailet" value="James"/>
</map>
</property>
</bean>
@@ -127,14 +128,9 @@
<property name="order" value="3" />
</bean>
- <bean id="mailetLog" class="org.apache.commons.logging.impl.Log4JLogger">
- <constructor-arg index="0" value="MAILET"/>
- </bean>
-
- <bean id="James" class="org.apache.james.James">
- <!-- just a workaround atm -->
- <property name="mailetLog" ref="mailetLog"/>
- </bean>
+ <bean id="James" class="org.apache.james.James"/>
+
+ <bean id="mailet" class="org.apache.james.JamesMailetContext"/>
<!-- The James Spool Manager block -->
<bean id="spoolmanager" class="org.apache.james.transport.JamesSpoolManager" />
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org