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/17 19:19:57 UTC
svn commit: r900176 - in /james/server/trunk: imapserver-function/
imapserver-function/src/main/java/org/apache/james/imapserver/mina/
spring-deployment/src/main/config/james/
Author: norman
Date: Sun Jan 17 18:19:56 2010
New Revision: 900176
URL: http://svn.apache.org/viewvc?rev=900176&view=rev
Log:
Add Async ImapServer which use MINA (JAMES-952)
Added:
james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/
james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/AsyncImapServer.java
james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/ImapIoHandler.java
Modified:
james/server/trunk/imapserver-function/pom.xml
james/server/trunk/spring-deployment/src/main/config/james/spring-beans.xml
Modified: james/server/trunk/imapserver-function/pom.xml
URL: http://svn.apache.org/viewvc/james/server/trunk/imapserver-function/pom.xml?rev=900176&r1=900175&r2=900176&view=diff
==============================================================================
--- james/server/trunk/imapserver-function/pom.xml (original)
+++ james/server/trunk/imapserver-function/pom.xml Sun Jan 17 18:19:56 2010
@@ -69,6 +69,12 @@
<artifactId>geronimo-annotation_1.0_spec</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>james-server-mina-socket-library</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>james-server-socket-shared-library</artifactId>
@@ -125,6 +131,11 @@
</dependency>
<dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
Added: james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/AsyncImapServer.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/AsyncImapServer.java?rev=900176&view=auto
==============================================================================
--- james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/AsyncImapServer.java (added)
+++ james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/AsyncImapServer.java Sun Jan 17 18:19:56 2010
@@ -0,0 +1,205 @@
+/****************************************************************
+ * 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.imapserver.mina;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+
+import javax.annotation.Resource;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.process.ImapProcessor;
+import org.apache.james.imap.decode.ImapDecoder;
+import org.apache.james.imap.encode.ImapEncoder;
+import org.apache.james.imap.mailbox.Mailbox;
+import org.apache.james.imap.mailbox.MailboxManager;
+import org.apache.james.imap.mailbox.MailboxSession;
+import org.apache.james.imap.main.ImapRequestHandler;
+import org.apache.james.socket.mina.AbstractAsyncServer;
+import org.apache.jsieve.mailet.Poster;
+import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
+import org.apache.mina.core.service.IoHandler;
+
+/**
+ * Async ImapServer which use MINA for socket handling
+ *
+ */
+public class AsyncImapServer extends AbstractAsyncServer implements ImapConstants, Poster{
+
+ private static final String softwaretype = "JAMES "+VERSION+" Server "; //+ Constants.SOFTWARE_VERSION;
+
+ private String hello;
+ private ImapProcessor processor;
+ private ImapEncoder encoder;
+
+ private ImapDecoder decoder;
+
+ private MailboxManager mailboxManager;
+
+ @Resource(name="imapDecoder")
+ public void setImapDecoder(ImapDecoder decoder) {
+ this.decoder = decoder;
+ }
+
+ @Resource(name="imapEncoder")
+ public void setImapEncoder(ImapEncoder encoder) {
+ this.encoder = encoder;
+ }
+
+ @Resource(name="imapProcessor")
+ public void setImapProcessor(ImapProcessor processor) {
+ this.processor = processor;
+ }
+
+ @Resource(name="mailboxmanager")
+ public void setMailboxManager(MailboxManager mailboxManager) {
+ this.mailboxManager = mailboxManager;
+ }
+
+ @Override
+ public void doConfigure( final HierarchicalConfiguration configuration ) throws ConfigurationException {
+ super.doConfigure(configuration);
+ hello = softwaretype + " Server " + getHelloName() + " is ready.";
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.james.socket.mina.AbstractAsyncServer#getDefaultPort()
+ */
+ public int getDefaultPort() {
+ return 143;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.james.socket.mina.AbstractAsyncServer#getServiceType()
+ */
+ public String getServiceType() {
+ return "IMAP Service";
+ }
+
+ @Override
+ protected IoHandler createIoHandler() {
+ final ImapRequestHandler handler = new ImapRequestHandler(decoder, processor, encoder);
+ return new ImapIoHandler(hello, handler, getLogger());
+ }
+
+ @Override
+ protected DefaultIoFilterChainBuilder createIoFilterChainBuilder() {
+
+ // just return an empty filterchain because we need no special protocol filter etc
+ return new DefaultIoFilterChainBuilder();
+ }
+
+ /**
+ * @see org.apache.jsieve.mailet.Poster#post(java.lang.String, javax.mail.internet.MimeMessage)
+ */
+ public void post(String url, MimeMessage mail)throws MessagingException {
+ final int endOfScheme = url.indexOf(':');
+ if (endOfScheme < 0) {
+ throw new MessagingException("Malformed URI");
+ } else {
+ final String scheme = url.substring(0, endOfScheme);
+ if ("mailbox".equals(scheme)) {
+ final int startOfUser = endOfScheme + 3;
+ final int endOfUser = url.indexOf('@', startOfUser);
+ if (endOfUser < 0) {
+ // TODO: when user missing, append to a default location
+ throw new MessagingException("Shared mailbox is not supported");
+ } else {
+ String user = url.substring(startOfUser, endOfUser);
+ final int startOfHost = endOfUser + 1;
+ final int endOfHost = url.indexOf('/', startOfHost);
+ final String host = url.substring(startOfHost, endOfHost);
+ //if (!"localhost".equals(host)) {
+ if (getMailServer().isLocalServer(host) == false) {
+ //TODO: possible support for clustering?
+ throw new MessagingException("Only local mailboxes are supported");
+ } else {
+ final String urlPath;
+ final int length = url.length();
+ if (endOfHost + 1 == length) {
+ urlPath = "INBOX";
+ } else {
+ urlPath = url.substring(endOfHost, length);
+ }
+
+ // check if we should use the full emailaddress as username
+ if (getMailServer().supportVirtualHosting()) {
+ user = user + "@" + host;
+ }
+
+ final MailboxSession session = mailboxManager.createSystemSession(user, getLogger());
+ // This allows Sieve scripts to use a standard delimiter regardless of mailbox implementation
+ final String mailbox = urlPath.replace('/', session.getPersonalSpace().getDeliminator());
+ postToMailbox(user, mail, mailbox, session, mailboxManager);
+ }
+ }
+ } else {
+ // TODO: add support for more protocols
+ // TODO: for example mailto: for forwarding over SMTP
+ // TODO: for example xmpp: for forwarding over Jabber
+ throw new MessagingException("Unsupported protocol");
+ }
+ }
+ }
+
+ public void postToMailbox(String username, MimeMessage mail, String destination, final MailboxSession session, final MailboxManager mailboxManager) throws MessagingException {
+ if (destination == null || "".equals(destination)) {
+ destination = "INBOX";
+ }
+ final String name = mailboxManager.resolve(username, destination);
+ try
+ {
+ if ("INBOX".equalsIgnoreCase(destination) && !(mailboxManager.mailboxExists(name, session))) {
+ mailboxManager.createMailbox(name, session);
+ }
+ final Mailbox mailbox = mailboxManager.getMailbox(name, session);
+
+ if (mailbox == null) {
+ final String error = "Mailbox for user " + username
+ + " was not found on this server.";
+ throw new MessagingException(error);
+ }
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ mail.writeTo(baos);
+ mailbox.appendMessage(baos.toByteArray() , new Date(), session, true, null);
+ }
+ catch (IOException e)
+ {
+ throw new MessagingException("Failed to write mail message", e);
+ }
+ finally
+ {
+ session.close();
+ mailboxManager.logout(session, true);
+ }
+ }
+
+
+}
Added: james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/ImapIoHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/ImapIoHandler.java?rev=900176&view=auto
==============================================================================
--- james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/ImapIoHandler.java (added)
+++ james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/mina/ImapIoHandler.java Sun Jan 17 18:19:56 2010
@@ -0,0 +1,104 @@
+/****************************************************************
+ * 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.imapserver.mina;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.encode.ImapResponseComposer;
+import org.apache.james.imap.encode.base.ImapResponseComposerImpl;
+import org.apache.james.imap.main.ImapRequestHandler;
+import org.apache.james.imap.main.ImapSessionImpl;
+import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.handler.stream.StreamIoHandler;
+
+/**
+ * IoHandler which process Imap commands
+ *
+ */
+public class ImapIoHandler extends StreamIoHandler{
+
+ private Log logger;
+
+ private String hello;
+
+ private ImapRequestHandler handler;
+
+ private final static String IMAP_SESSION = "IMAP_SESSION";
+ public ImapIoHandler(String hello, ImapRequestHandler handler, Log logger) {
+ this.logger = logger;
+ this.hello = hello;
+ this.handler = handler;
+
+ }
+
+ @Override
+ public void exceptionCaught(IoSession session, Throwable cause) {
+ cause.printStackTrace();
+ super.exceptionCaught(session, cause);
+ }
+
+ @Override
+ public void sessionCreated(IoSession session) throws Exception {
+
+ // create the imap session and store it in the IoSession for later usage
+ final ImapSessionImpl imapsession = new ImapSessionImpl();
+ imapsession.setLog(logger);
+
+ session.setAttribute(IMAP_SESSION, imapsession);
+
+ super.sessionCreated(session);
+ }
+
+
+ @Override
+ public void sessionOpened(IoSession session) {
+ // write hello to client
+ session.write(IoBuffer.wrap((ImapConstants.UNTAGGED + " OK " + hello +" " + new String(ImapConstants.BYTES_LINE_END)).getBytes()));
+
+ super.sessionOpened(session);
+ }
+
+ @Override
+ protected void processStreamIo(final IoSession session, final InputStream in, final OutputStream out) {
+
+ // it would prolly make sense to use a thread pool...
+ new Thread(new Runnable() {
+
+
+ public void run() {
+ final ImapSessionImpl imapSession = (ImapSessionImpl) session.getAttribute(IMAP_SESSION);
+
+ // handle requests in a loop
+ while(handler.handleRequest( in, out, imapSession ));
+ if (imapSession != null) imapSession.logout();
+ session.close(false);
+ }
+
+ }).start();
+
+ }
+
+}
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=900176&r1=900175&r2=900176&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 Sun Jan 17 18:19:56 2010
@@ -305,6 +305,12 @@
<!--
<bean id="domainlist" class="org.apache.james.vut.XMLVirtualUserTable"/>
-->
+ <!--
+ <bean id="imapserver" name="org.apache.jsieve.mailet.Poster" class="org.apache.james.imapserver.mina.AsyncImapServer">
+ <property name="imapDecoder" ref="imapDecoder"/>
+ <property name="imapEncoder" ref="imapEncoder"/>
+ </bean>
+ -->
<!-- IMAP server Beans -->
<bean id="imapserver.protocolhandlerfactory" name="org.apache.jsieve.mailet.Poster" class="org.apache.james.imapserver.ImapServerProtocolHandlerFactory">
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org