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 }