001 /*
002 * Copyright 2010 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package com.hs.mail.imap.processor;
017
018 import org.apache.log4j.Logger;
019 import org.jboss.netty.channel.Channel;
020 import org.jboss.netty.channel.ChannelFuture;
021 import org.jboss.netty.channel.ChannelFutureListener;
022
023 import com.hs.mail.container.config.ComponentManager;
024 import com.hs.mail.imap.ImapSession;
025 import com.hs.mail.imap.event.EventTracker;
026 import com.hs.mail.imap.mailbox.MailboxManager;
027 import com.hs.mail.imap.mailbox.SelectedMailbox;
028 import com.hs.mail.imap.message.request.ImapRequest;
029 import com.hs.mail.imap.message.responder.DefaultImapResponder;
030 import com.hs.mail.imap.message.responder.Responder;
031 import com.hs.mail.imap.message.responder.UnsolicitedResponder;
032 import com.hs.mail.imap.message.response.HumanReadableText;
033 import com.hs.mail.imap.message.response.UnsolicitedResponse;
034 import com.hs.mail.imap.message.response.UnsolicitedResponseBuilder;
035 import com.hs.mail.imap.user.UserManager;
036
037 /**
038 *
039 * @author Won Chul Doh
040 * @since Jan 31, 2010
041 *
042 */
043 public abstract class AbstractImapProcessor implements ImapProcessor {
044
045 static Logger logger = Logger.getLogger(AbstractImapProcessor.class);
046
047 protected AbstractImapProcessor() {
048 super();
049 }
050
051 public void process(ImapSession session, ImapRequest request,
052 Channel channel) {
053 if (!request.validForState(session.getState())) {
054 channel.write(request.getTag() + " NO " + request.getCommand()
055 + " " + HumanReadableText.INVALID_COMMAND + "\r\n");
056 } else {
057 Responder responder = createResponder(channel, request);
058 if (isSelectedMailboxDeleted(session)) {
059 writeSignOff(session, responder);
060 } else {
061 try {
062 doProcess(session, request, responder);
063 } catch (Exception ex) {
064 logger.error(ex.getMessage(), ex);
065 responder.taggedNo(request, ex.getMessage());
066 }
067 }
068 }
069 }
070
071 abstract protected void doProcess(ImapSession session, ImapRequest request,
072 Responder responder) throws Exception;
073
074 protected MailboxManager getMailboxManager() {
075 return (MailboxManager) ComponentManager
076 .getBeanOfType(MailboxManager.class);
077 }
078
079 protected UserManager getUserManager() {
080 return (UserManager) ComponentManager.getBeanOfType(UserManager.class);
081 }
082
083 protected Responder createResponder(Channel channel, ImapRequest request) {
084 return new DefaultImapResponder(channel, request);
085 }
086
087 protected void unsolicitedResponse(ImapSession session, Responder responder) {
088 SelectedMailbox selected = session.getSelectedMailbox();
089 if (selected != null) {
090 EventTracker tracker = selected.getEventTracker();
091 if (tracker != null) {
092 UnsolicitedResponse response = new UnsolicitedResponseBuilder()
093 .build(selected, tracker);
094 if (response != null) {
095 new UnsolicitedResponder(responder).respond(response);
096 }
097 selected.resetEvents();
098 }
099 }
100 }
101
102 private boolean isSelectedMailboxDeleted(ImapSession session) {
103 SelectedMailbox selected = session.getSelectedMailbox();
104 return (selected != null) ? selected.isDeletedMailbox() : false;
105 }
106
107 private void writeSignOff(ImapSession session, Responder responder) {
108 getMailboxManager().removeEventListener(session.getSelectedMailbox());
109 // Is this necessary?
110 session.logout();
111 // RFC2180 3.3 The server MAY allow the DELETE/RENAME of a
112 // multi-accessed mailbox, but disconnect all other clients who
113 // have the mailbox accessed by sending a untagged BYE response.
114 ChannelFuture future = responder
115 .bye(HumanReadableText.MAILBOX_DELETED_SIGN_OFF);
116 future.addListener(ChannelFutureListener.CLOSE);
117 }
118
119 }