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 2011/11/18 11:00:52 UTC
svn commit: r1203562 [2/2] - in /james/protocols/trunk/pop3: .settings/
src/main/java/org/apache/james/protocols/pop3/
src/main/java/org/apache/james/protocols/pop3/core/
src/main/java/org/apache/james/protocols/pop3/pop3server/
src/main/java/org/apach...
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/QuitCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/QuitCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/QuitCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/QuitCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,99 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.Resource;
+import javax.mail.Flags;
+
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageRange;
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.pop3server.POP3Response;
+import org.apache.james.pop3server.POP3Session;
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.CommandHandler;
+
+/**
+ * Handles QUIT command
+ */
+public class QuitCmdHandler implements CommandHandler<POP3Session> {
+ private final static String COMMAND_NAME = "QUIT";
+ protected MailboxManager mailboxManager;
+
+ @Resource(name = "mailboxmanager")
+ public void setMailboxManager(MailboxManager manager) {
+ this.mailboxManager = manager;
+ }
+
+ /**
+ * Handler method called upon receipt of a QUIT command. This method handles
+ * cleanup of the POP3Handler state.
+ */
+ @SuppressWarnings("unchecked")
+ public Response onCommand(POP3Session session, Request request) {
+ POP3Response response = null;
+ if (session.getHandlerState() == POP3Session.AUTHENTICATION_READY || session.getHandlerState() == POP3Session.AUTHENTICATION_USERSET) {
+ response = new POP3Response(POP3Response.OK_RESPONSE, "Apache James POP3 Server signing off.");
+ response.setEndSession(true);
+ return response;
+ }
+ MailboxSession mailboxSession = (MailboxSession) session.getState().get(POP3Session.MAILBOX_SESSION);
+
+ List<Long> toBeRemoved = (List<Long>) session.getState().get(POP3Session.DELETED_UID_LIST);
+ try {
+ MessageManager mailbox = session.getUserMailbox();
+
+ for (int i = 0; i < toBeRemoved.size(); i++) {
+ MessageRange range = MessageRange.one(toBeRemoved.get(i));
+ mailbox.setFlags(new Flags(Flags.Flag.DELETED), true, false, range, mailboxSession);
+ mailbox.expunge(range, mailboxSession);
+ }
+ response = new POP3Response(POP3Response.OK_RESPONSE, "Apache James POP3 Server signing off.");
+ } catch (Exception ex) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE, "Some deleted messages were not removed");
+ session.getLogger().error("Some deleted messages were not removed", ex);
+ }
+ response.setEndSession(true);
+ try {
+ mailboxManager.logout(mailboxSession, false);
+ } catch (MailboxException e) {
+ // nothing todo on logout
+ }
+
+ return response;
+ }
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/RetrCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/RetrCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/RetrCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/RetrCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,134 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.apache.james.mailbox.Content;
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageRange;
+import org.apache.james.mailbox.MessageResult;
+import org.apache.james.mailbox.MessageResult.FetchGroup;
+import org.apache.james.pop3server.POP3Response;
+import org.apache.james.pop3server.POP3Session;
+import org.apache.james.pop3server.POP3StreamResponse;
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.CommandHandler;
+
+/**
+ * Handles RETR command
+ */
+public class RetrCmdHandler implements CommandHandler<POP3Session> {
+
+ private final static String COMMAND_NAME = "RETR";
+ private final static FetchGroup GROUP = new FetchGroup() {
+
+ @Override
+ public int content() {
+ return FULL_CONTENT;
+ }
+
+ @Override
+ public Set<PartContentDescriptor> getPartContentDescriptors() {
+ return null;
+ }
+
+ };
+ /**
+ * Handler method called upon receipt of a RETR command. This command
+ * retrieves a particular mail message from the mailbox.
+ */
+ @SuppressWarnings("unchecked")
+ public Response onCommand(POP3Session session, Request request) {
+ POP3Response response = null;
+ String parameters = request.getArgument();
+ if (session.getHandlerState() == POP3Session.TRANSACTION) {
+ int num = 0;
+ try {
+ num = Integer.parseInt(parameters.trim());
+ } catch (Exception e) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE, "Usage: RETR [mail number]");
+ return response;
+ }
+ try {
+ List<MessageMetaData> uidList = (List<MessageMetaData>) session.getState().get(POP3Session.UID_LIST);
+ List<Long> deletedUidList = (List<Long>) session.getState().get(POP3Session.DELETED_UID_LIST);
+
+ MailboxSession mailboxSession = (MailboxSession) session.getState().get(POP3Session.MAILBOX_SESSION);
+ Long uid = uidList.get(num - 1).getUid();
+ if (deletedUidList.contains(uid) == false) {
+ Iterator<MessageResult> results = session.getUserMailbox().getMessages(MessageRange.one(uid), GROUP, mailboxSession);
+
+ if (results.hasNext()) {
+ MessageResult result = results.next();
+
+ Content content = result.getFullContent();
+ InputStream in = new CRLFTerminatedInputStream(new ExtraDotInputStream(content.getInputStream()));
+ response = new POP3StreamResponse(POP3Response.OK_RESPONSE, "Message follows", in);
+ return response;
+
+
+
+ } else {
+ StringBuilder responseBuffer = new StringBuilder(64).append("Message (").append(num).append(") does not exist.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, responseBuffer.toString());
+ }
+ } else {
+
+ StringBuilder responseBuffer = new StringBuilder(64).append("Message (").append(num).append(") already deleted.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, responseBuffer.toString());
+ }
+ } catch (IOException ioe) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE, "Error while retrieving message.");
+ } catch (MailboxException me) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE, "Error while retrieving message.");
+ } catch (IndexOutOfBoundsException iob) {
+ StringBuilder responseBuffer = new StringBuilder(64).append("Message (").append(num).append(") does not exist.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, responseBuffer.toString());
+ } catch (NoSuchElementException e) {
+ StringBuilder responseBuffer = new StringBuilder(64).append("Message (").append(num).append(") does not exist.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, responseBuffer.toString());
+ }
+ } else {
+ response = new POP3Response(POP3Response.ERR_RESPONSE);
+ }
+ return response;
+ }
+
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/RsetCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/RsetCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/RsetCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/RsetCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,110 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageRange;
+import org.apache.james.mailbox.MessageResult;
+import org.apache.james.mailbox.MessageResult.FetchGroup;
+import org.apache.james.pop3server.POP3Response;
+import org.apache.james.pop3server.POP3Session;
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.CommandHandler;
+
+/**
+ * Handles RSET command
+ */
+public class RsetCmdHandler implements CommandHandler<POP3Session> {
+ private final static String COMMAND_NAME = "RSET";
+
+ private final static FetchGroup GROUP = new FetchGroup() {
+
+ @Override
+ public int content() {
+ return MINIMAL;
+ }
+
+ @Override
+ public Set<PartContentDescriptor> getPartContentDescriptors() {
+ return null;
+ }
+
+ };
+
+ /**
+ * Handler method called upon receipt of a RSET command. Calls stat() to
+ * reset the mailbox.
+ */
+ public Response onCommand(POP3Session session, Request request) {
+ POP3Response response = null;
+ if (session.getHandlerState() == POP3Session.TRANSACTION) {
+ stat(session);
+ response = new POP3Response(POP3Response.OK_RESPONSE);
+ } else {
+ response = new POP3Response(POP3Response.ERR_RESPONSE);
+ }
+ return response;
+ }
+
+ /**
+ * Implements a "stat". If the handler is currently in a transaction state,
+ * this amounts to a rollback of the mailbox contents to the beginning of
+ * the transaction. This method is also called when first entering the
+ * transaction state to initialize the handler copies of the user inbox.
+ */
+ protected void stat(POP3Session session) {
+ try {
+ MailboxSession mailboxSession = (MailboxSession) session.getState().get(POP3Session.MAILBOX_SESSION);
+
+ List<MessageMetaData> uids = new ArrayList<MessageMetaData>();
+ Iterator<MessageResult> it = session.getUserMailbox().getMessages(MessageRange.all(), GROUP, mailboxSession);
+ while (it.hasNext()) {
+ MessageResult result = it.next();
+ uids.add(new MessageMetaData(result.getUid(), result.getSize()));
+
+ }
+ session.getState().put(POP3Session.UID_LIST, uids);
+ session.getState().put(POP3Session.DELETED_UID_LIST, new ArrayList<Long>());
+ } catch (MailboxException e) {
+ // In the event of an exception being thrown there may or may not be
+ // anything in userMailbox
+ session.getLogger().error("Unable to STAT mail box ", e);
+ }
+
+ }
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/StatCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/StatCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/StatCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/StatCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,80 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.james.pop3server.POP3Response;
+import org.apache.james.pop3server.POP3Session;
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.CommandHandler;
+
+/**
+ * Handles STAT command
+ */
+public class StatCmdHandler implements CommandHandler<POP3Session> {
+ private final static String COMMAND_NAME = "STAT";
+
+ /**
+ * Handler method called upon receipt of a STAT command. Returns the number
+ * of messages in the mailbox and its aggregate size.
+ */
+ @SuppressWarnings("unchecked")
+ public Response onCommand(POP3Session session, Request request) {
+ POP3Response response = null;
+ if (session.getHandlerState() == POP3Session.TRANSACTION) {
+
+ List<MessageMetaData> uidList = (List<MessageMetaData>) session.getState().get(POP3Session.UID_LIST);
+ List<Long> deletedUidList = (List<Long>) session.getState().get(POP3Session.DELETED_UID_LIST);
+ long size = 0;
+ int count = 0;
+ if (uidList.isEmpty() == false) {
+ List<MessageMetaData> validResults = new ArrayList<MessageMetaData>();
+ for (int i = 0; i < uidList.size(); i++) {
+ MessageMetaData data = uidList.get(i);
+ if (deletedUidList.contains(data.getUid()) == false) {
+ size += data.getSize();
+ count++;
+ validResults.add(data);
+ }
+ }
+ }
+ StringBuilder responseBuffer = new StringBuilder(32).append(count).append(" ").append(size);
+ response = new POP3Response(POP3Response.OK_RESPONSE, responseBuffer.toString());
+
+ } else {
+ response = new POP3Response(POP3Response.ERR_RESPONSE);
+ }
+ return response;
+ }
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/StlsCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/StlsCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/StlsCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/StlsCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,77 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.CommandHandler;
+import org.apache.james.protocols.pop3.POP3Response;
+import org.apache.james.protocols.pop3.POP3Session;
+import org.apache.james.protocols.pop3.StartTlsPop3Response;
+
+/**
+ * Handler which offer STARTTLS implementation for POP3. STARTTLS is started
+ * with the STSL command
+ */
+public class StlsCmdHandler implements CommandHandler<POP3Session>, CapaCapability {
+ public final static String COMMAND_NAME = "STLS";
+
+ /**
+ * @see CommandHandler#onCommand(org.apache.james.protocols.api.ProtocolSession, Request)
+ */
+ public Response onCommand(POP3Session session, Request request) {
+ POP3Response response;
+ // check if starttls is supported, the state is the right one and it was
+ // not started before
+ if (session.isStartTLSSupported() && session.getHandlerState() == POP3Session.AUTHENTICATION_READY && session.isTLSStarted() == false) {
+ response = new StartTlsPop3Response(POP3Response.OK_RESPONSE, "Begin TLS negotiation");
+ return response;
+
+ } else {
+ response = new POP3Response(POP3Response.ERR_RESPONSE);
+ return response;
+ }
+ }
+
+ /**
+ * @see org.apache.james.pop3server.core.CapaCapability#getImplementedCapabilities(org.apache.james.pop3server.POP3Session)
+ */
+ public List<String> getImplementedCapabilities(POP3Session session) {
+ List<String> caps = new ArrayList<String>();
+ if (session.isStartTLSSupported() && session.getHandlerState() == POP3Session.AUTHENTICATION_READY) {
+ caps.add(COMMAND_NAME);
+ return caps;
+ }
+ return caps;
+ }
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/TopCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/TopCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/TopCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/TopCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,246 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageRange;
+import org.apache.james.mailbox.MessageResult;
+import org.apache.james.mailbox.MessageResult.FetchGroup;
+import org.apache.james.pop3server.POP3Response;
+import org.apache.james.pop3server.POP3Session;
+import org.apache.james.pop3server.POP3StreamResponse;
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+
+/**
+ * Handles TOP command
+ */
+public class TopCmdHandler extends RetrCmdHandler implements CapaCapability {
+ private final static String COMMAND_NAME = "TOP";
+ private final static FetchGroup GROUP = new FetchGroup() {
+
+ @Override
+ public int content() {
+ return BODY_CONTENT | HEADERS;
+ }
+
+ @Override
+ public Set<PartContentDescriptor> getPartContentDescriptors() {
+ return null;
+ }
+
+ };
+
+ /**
+ * Handler method called upon receipt of a TOP command. This command
+ * retrieves the top N lines of a specified message in the mailbox.
+ *
+ * The expected command format is TOP [mail message number] [number of lines
+ * to return]
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Response onCommand(POP3Session session, Request request) {
+ POP3Response response = null;
+ String parameters = request.getArgument();
+ if (parameters == null) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE, "Usage: TOP [mail number] [Line number]");
+ return response;
+ }
+
+ String argument = "";
+ String argument1 = "";
+ int pos = parameters.indexOf(" ");
+ if (pos > 0) {
+ argument = parameters.substring(0, pos);
+ argument1 = parameters.substring(pos + 1);
+ }
+
+ if (session.getHandlerState() == POP3Session.TRANSACTION) {
+ int num = 0;
+ int lines = -1;
+ try {
+ num = Integer.parseInt(argument);
+ lines = Integer.parseInt(argument1);
+ } catch (NumberFormatException nfe) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE, "Usage: TOP [mail number] [Line number]");
+ return response;
+ }
+ try {
+ List<MessageMetaData> uidList = (List<MessageMetaData>) session.getState().get(POP3Session.UID_LIST);
+ List<Long> deletedUidList = (List<Long>) session.getState().get(POP3Session.DELETED_UID_LIST);
+
+ MailboxSession mailboxSession = (MailboxSession) session.getState().get(POP3Session.MAILBOX_SESSION);
+ Long uid = uidList.get(num - 1).getUid();
+ if (deletedUidList.contains(uid) == false) {
+
+ Iterator<MessageResult> results = session.getUserMailbox().getMessages(MessageRange.one(uid), GROUP, mailboxSession);
+
+ if (results.hasNext()) {
+ MessageResult result = results.next();
+
+ InputStream headersIn = result.getHeaders().getInputStream();
+ InputStream bodyIn = new CountingBodyInputStream(new ExtraDotInputStream(new CRLFTerminatedInputStream(result.getBody().getInputStream())), lines);
+
+ // write body
+ InputStream in = new SequenceInputStream(Collections.enumeration(Arrays.asList(headersIn, new ByteArrayInputStream("\r\n".getBytes()), bodyIn)));
+
+ response = new POP3StreamResponse(POP3Response.OK_RESPONSE, "Message follows", in);
+ return response;
+
+ } else {
+ StringBuilder exceptionBuffer = new StringBuilder(64).append("Message (").append(num).append(") does not exist.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, exceptionBuffer.toString());
+ }
+
+ } else {
+ StringBuilder responseBuffer = new StringBuilder(64).append("Message (").append(num).append(") already deleted.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, responseBuffer.toString());
+ }
+ } catch (IOException ioe) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE, "Error while retrieving message.");
+ } catch (MailboxException me) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE, "Error while retrieving message.");
+ } catch (IndexOutOfBoundsException iob) {
+ StringBuilder exceptionBuffer = new StringBuilder(64).append("Message (").append(num).append(") does not exist.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, exceptionBuffer.toString());
+ } catch (NoSuchElementException iob) {
+ StringBuilder exceptionBuffer = new StringBuilder(64).append("Message (").append(num).append(") does not exist.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, exceptionBuffer.toString());
+ }
+ } else {
+ response = new POP3Response(POP3Response.ERR_RESPONSE);
+ }
+ return response;
+
+ }
+
+ /**
+ * @see org.apache.james.pop3server.core.CapaCapability#getImplementedCapabilities(org.apache.james.pop3server.POP3Session)
+ */
+ public List<String> getImplementedCapabilities(POP3Session session) {
+ List<String> caps = new ArrayList<String>();
+ if (session.getHandlerState() == POP3Session.TRANSACTION) {
+ caps.add(COMMAND_NAME);
+ return caps;
+ }
+ return caps;
+ }
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+
+ /**
+ * This {@link InputStream} implementation can be used to limit the body
+ * lines which will be read from the wrapped {@link InputStream}
+ */
+ private final class CountingBodyInputStream extends FilterInputStream {
+
+ private int count = 0;
+ private int limit = -1;
+ private int lastChar;
+
+ /**
+ *
+ * @param in
+ * InputStream to read from
+ * @param limit
+ * the lines to read. -1 is used for no limits
+ */
+ public CountingBodyInputStream(InputStream in, int limit) {
+ super(in);
+ this.limit = limit;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (limit != -1) {
+ if (count <= limit) {
+ int a = in.read();
+
+ if (lastChar == '\r' && a == '\n') {
+ count++;
+ }
+ lastChar = a;
+
+ return a;
+ } else {
+ return -1;
+ }
+ } else {
+ return in.read();
+ }
+
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (limit == -1) {
+ return in.read(b, off, len);
+ } else {
+ int i;
+ for (i = 0; i < len; i++) {
+ int a = read();
+ if (i == 0 && a == -1) {
+ return -1;
+ } else {
+ if (a == -1) {
+ break;
+ } else {
+ b[off++] = (byte) a;
+ }
+ }
+ }
+ return i;
+ }
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ if (limit == -1) {
+ return in.read(b);
+ } else {
+ return read(b, 0, b.length);
+ }
+ }
+
+ }
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UidlCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UidlCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UidlCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UidlCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,122 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager.MetaData;
+import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
+import org.apache.james.pop3server.POP3Response;
+import org.apache.james.pop3server.POP3Session;
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.CommandHandler;
+
+/**
+ * Handles UIDL command
+ */
+public class UidlCmdHandler implements CommandHandler<POP3Session>, CapaCapability {
+ private final static String COMMAND_NAME = "UIDL";
+
+ /**
+ * Handler method called upon receipt of a UIDL command. Returns a listing
+ * of message ids to the client.
+ */
+ @SuppressWarnings("unchecked")
+ public Response onCommand(POP3Session session, Request request) {
+ POP3Response response = null;
+ String parameters = request.getArgument();
+ if (session.getHandlerState() == POP3Session.TRANSACTION) {
+ List<MessageMetaData> uidList = (List<MessageMetaData>) session.getState().get(POP3Session.UID_LIST);
+ List<Long> deletedUidList = (List<Long>) session.getState().get(POP3Session.DELETED_UID_LIST);
+ MailboxSession mailboxSession = (MailboxSession) session.getState().get(POP3Session.MAILBOX_SESSION);
+ try {
+ MetaData mData = session.getUserMailbox().getMetaData(false, mailboxSession, FetchGroup.NO_COUNT);
+ long validity = mData.getUidValidity();
+ if (parameters == null) {
+ response = new POP3Response(POP3Response.OK_RESPONSE, "unique-id listing follows");
+ for (int i = 0; i < uidList.size(); i++) {
+ Long uid = uidList.get(i).getUid();
+ if (deletedUidList.contains(uid) == false) {
+ // construct unique UIDL. See JAMES-1264
+ StringBuilder responseBuffer = new StringBuilder(64).append(i + 1).append(" ").append(validity).append("-").append(uid);
+ response.appendLine(responseBuffer.toString());
+ }
+ }
+
+ response.appendLine(".");
+ } else {
+ int num = 0;
+ try {
+ num = Integer.parseInt(parameters);
+ Long uid = uidList.get(num - 1).getUid();
+ if (deletedUidList.contains(uid) == false) {
+ // construct unique UIDL. See JAMES-1264
+ StringBuilder responseBuffer = new StringBuilder(64).append(num).append(" ").append(validity).append("-").append(uid);
+ response = new POP3Response(POP3Response.OK_RESPONSE, responseBuffer.toString());
+
+ } else {
+ StringBuilder responseBuffer = new StringBuilder(64).append("Message (").append(num).append(") already deleted.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, responseBuffer.toString());
+ }
+ } catch (IndexOutOfBoundsException npe) {
+ StringBuilder responseBuffer = new StringBuilder(64).append("Message (").append(num).append(") does not exist.");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, responseBuffer.toString());
+ } catch (NumberFormatException nfe) {
+ StringBuilder responseBuffer = new StringBuilder(64).append(parameters).append(" is not a valid number");
+ response = new POP3Response(POP3Response.ERR_RESPONSE, responseBuffer.toString());
+ }
+ }
+ } catch (MailboxException e) {
+ response = new POP3Response(POP3Response.ERR_RESPONSE);
+ return response;
+ }
+
+ } else {
+ response = new POP3Response(POP3Response.ERR_RESPONSE);
+ }
+ return response;
+ }
+
+ /**
+ * @see org.apache.james.pop3server.core.CapaCapability#getImplementedCapabilities(org.apache.james.pop3server.POP3Session)
+ */
+ public List<String> getImplementedCapabilities(POP3Session session) {
+ List<String> caps = new ArrayList<String>();
+ if (session.getHandlerState() == POP3Session.TRANSACTION) {
+ caps.add(COMMAND_NAME);
+ return caps;
+ }
+ return caps;
+ }
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UnknownCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UnknownCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UnknownCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UnknownCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,58 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.CommandHandler;
+import org.apache.james.protocols.pop3.POP3Response;
+import org.apache.james.protocols.pop3.POP3Session;
+
+/**
+ * Default command handler for handling unknown commands
+ */
+public class UnknownCmdHandler implements CommandHandler<POP3Session> {
+ /**
+ * The name of the command handled by the command handler
+ */
+ public static final String COMMAND_NAME = "UNKNOWN";
+
+ /**
+ * Handler method called upon receipt of an unrecognized command. Returns an
+ * error response and logs the command.
+ */
+ public Response onCommand(POP3Session session, Request request) {
+ return new POP3Response(POP3Response.ERR_RESPONSE);
+ }
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UserCmdHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UserCmdHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UserCmdHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/UserCmdHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,73 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.james.pop3server.POP3Response;
+import org.apache.james.pop3server.POP3Session;
+import org.apache.james.protocols.api.Request;
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.CommandHandler;
+
+/**
+ * Handles NOOP command
+ */
+public class UserCmdHandler implements CommandHandler<POP3Session>, CapaCapability {
+
+ private final static String COMMAND_NAME = "USER";
+
+ /**
+ * Handler method called upon receipt of a USER command. Reads in the user
+ * id.
+ */
+ public Response onCommand(POP3Session session, Request request) {
+ POP3Response response = null;
+ String parameters = request.getArgument();
+ if (session.getHandlerState() == POP3Session.AUTHENTICATION_READY && parameters != null) {
+ session.setUser(parameters);
+ session.setHandlerState(POP3Session.AUTHENTICATION_USERSET);
+ response = new POP3Response(POP3Response.OK_RESPONSE);
+ } else {
+ response = new POP3Response(POP3Response.ERR_RESPONSE);
+ }
+ return response;
+ }
+
+ /**
+ * @see org.apache.james.pop3server.core.CapaCapability#getImplementedCapabilities(org.apache.james.pop3server.POP3Session)
+ */
+ public List<String> getImplementedCapabilities(POP3Session session) {
+ List<String> caps = new ArrayList<String>();
+ caps.add(COMMAND_NAME);
+ return caps;
+ }
+
+ /**
+ * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
+ */
+ public Collection<String> getImplCommands() {
+ List<String> commands = new ArrayList<String>();
+ commands.add(COMMAND_NAME);
+ return commands;
+ }
+}
Added: james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/WelcomeMessageHandler.java
URL: http://svn.apache.org/viewvc/james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/WelcomeMessageHandler.java?rev=1203562&view=auto
==============================================================================
--- james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/WelcomeMessageHandler.java (added)
+++ james/protocols/trunk/pop3/src/main/java/org/apache/james/protocols/pop3/core/WelcomeMessageHandler.java Fri Nov 18 10:00:50 2011
@@ -0,0 +1,46 @@
+/****************************************************************
+ * 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.protocols.pop3.core;
+
+
+import org.apache.james.protocols.api.Response;
+import org.apache.james.protocols.api.handler.ConnectHandler;
+import org.apache.james.protocols.pop3.POP3Response;
+import org.apache.james.protocols.pop3.POP3Session;
+
+public class WelcomeMessageHandler implements ConnectHandler<POP3Session> {
+ /** POP3 Server identification string used in POP3 headers */
+ private static final String softwaretype = "JAMES POP3 Server ";// +
+ // Constants.SOFTWARE_VERSION;
+
+ /**
+ * @see org.apache.james.protocols.api.handler.ConnectHandler
+ * #onConnect(org.apache.james.pop3server.POP3Session)
+ */
+ public Response onConnect(POP3Session session) {
+ StringBuilder responseBuffer = new StringBuilder();
+ // Initially greet the connector
+ // Format is: Sat, 24 Jan 1998 13:16:09 -0500
+ responseBuffer.append(session.getConfigurationData().getHelloName()).append(" POP3 server (").append(softwaretype).append(") ready ");
+ POP3Response response = new POP3Response(POP3Response.OK_RESPONSE, responseBuffer.toString());
+ return response;
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org