On Wed, Mar 18, 2009 at 12:19 PM, Martin.Bergljung
<[email protected]> wrote:
> Hi,
>
> I did play around with another design as follows:
>
> public interface MailboxManager {
> public static final char HIERARCHY_DELIMITER = '.';
> public static final String USER_NAMESPACE = "#mail";
> public static final String INBOX = "INBOX";
>
> boolean isAuthentic(String username, String passwd);
> public MailboxSession createSession();
>
> String resolve(UserSessionContext context);
> Mailbox getMailbox(UserSessionContext context) throws MailboxException;
> void createMailbox(UserSessionContext context) throws MailboxException;
> void deleteMailbox(UserSessionContext context) throws MailboxException;
> void renameMailbox(UserSessionContext context, String from, String to)
> throws MailboxException;
> boolean mailboxExists(UserSessionContext context) throws MailboxException;
> public void subscribe(UserSessionContext context) throws
> SubscriptionException;
> public void unsubscribe(UserSessionContext context) throws
> SubscriptionException;
> public Collection<String> subscriptions(UserSessionContext context) throws
> SubscriptionException;
>
> void copyMessages(UserSessionContext context, MessageRange set, String
> from) throws MailboxException;
> List<MailboxMetaData> search(UserSessionContext context, MailboxQuery
> expression) throws MailboxException;
> void addListener(UserSessionContext context, MailboxListener listener)
> throws MailboxException;
> }
>
> public interface Mailbox {
> public static final long ANONYMOUS_SESSION = 0;
>
> int getMessageCount(UserSessionContext context) throws MailboxException;
> int getUnseenCount(UserSessionContext context) throws MailboxException;
> Long getFirstUnseen(UserSessionContext context) throws MailboxException;
> long getUidValidity(UserSessionContext context) throws MailboxException;
> long getUidNext(UserSessionContext context) throws MailboxException;
>
> long appendMessage(UserSessionContext context, byte[] message, Date
> internalDate, boolean isRecent) throws MailboxException;
> Iterator<MessageResult> getMessages(UserSessionContext context,
> MessageRange set, MessageResult.FetchGroup fetchGroup) throws
> MailboxException;
> Iterator<Long> expunge(UserSessionContext context, MessageRange set)
> throws MailboxException;
> Map<Long, Flags> setFlags(UserSessionContext context, Flags flags, boolean
> value, boolean replace, MessageRange set) throws MailboxException;
> long[] recent(UserSessionContext context, boolean reset) throws
> MailboxException;
> Iterator<Long> search(UserSessionContext context, SearchQuery searchQuery)
> throws MailboxException;
>
> boolean isWriteable();
> Flags getPermanentFlags();
> }
>
> And then the context object
>
> /**
> * The user session context is passed around to the
> * {...@link org.apache.james.imap.mailbox.MailboxManager}
> * and {...@link org.apache.james.imap.mailbox.Mailbox}
> * methods with information about the current user
> * session, which lasts from an IMAP LOGIN to a LOGOUT.
> * <p/>
> * It contains the username of the currently logged in user
> * and it gives you access to current mailboxPath if that is
> * required by the method that this context is passed to.
> * If you are in a <code>Mailbox</code> method you can access
> * the {...@link org.apache.james.imap.mailbox.MailboxSession}
> * via this context.
> * <p/>
> * It also contains the IMAP Session from which you can for
> * example find out the current state of the IMAP protocol session.
> * <p/>
> * This session context can also be used to store custom session attributes
> * such as an object with extra user properties.
> * Use the <code>setAttribute</code> to store an attribute and
> * <code>getAttribute</code> to retrieve it.
> */
> public class UserSessionContext {
> private ImapSession imapSession;
> private String userName;
> private String mailboxPath;
> private Map<String, Object> attributes;
>
> public UserSessionContext(ImapSession imapSession) {
> this.imapSession = imapSession;
> userName = ImapSessionUtils.getUserName(imapSession);
> attributes = new HashMap<String, Object>();
> }
> public ImapSession getImapSession() {
> return imapSession;
> }
>
> public MailboxSession getMailboxSession() {
> return ImapSessionUtils.getMailboxSession(imapSession);
> }
>
> public String getUserName() {
> return userName;
> }
>
> public String getMailboxPath() {
> return mailboxPath;
> }
>
> public void setMailboxPath(String mailboxPath) {
> this.mailboxPath = mailboxPath;
> }
>
> public Object getAttribute(String attrbuteName) {
> return attributes.get(attrbuteName);
> }
>
> public void setAttribute(String attributeName, Object attributeValue) {
> attributes.put(attributeName, attributeValue);
> }
> }
this approach couples mailbox to IMAP and exposes the IMAPSession to
the mailbox implementation. i think this is an architectural
disadvantage. i'm not sure whether so much complexity is really
needed: 2 sessions and a context seems too many to me. would be more
elegant just to use a single object for all, i think.
> I create this object in LoginProcessor as follows:
>
>
> if (mailboxManager.isAuthentic(userid, passwd)) {
> session.authenticated();
> final MailboxSession mailboxSession =
> mailboxManager.createSession();
> session.setAttribute(
> ImapSessionUtils.MAILBOX_SESSION_ATTRIBUTE_SESSION_KEY,
> mailboxSession);
> ImapSessionUtils.setUserName(session, userid);
>
> UserSessionContext context = new UserSessionContext(session);
>
> session.setAttribute(ImapSessionUtils.USER_SESSION_CONTEXT_ATTRIBUTE_KEY,
> context);
>
> final String inboxName = buildFullName(session,
> MailboxManager.INBOX);
>
> if (mailboxManager.mailboxExists(context)) {
> getLog().debug("INBOX exists. No need to create it.");
>
> buildFullName looks like:
>
> public String buildFullName(final ImapSession session, String mailboxName)
> throws MailboxException {
> UserSessionContext context =
> ImapSessionUtils.getUserSessionContext(session);
> if (!mailboxName.startsWith(NAMESPACE_PREFIX)) {
> context.setMailboxPath(mailboxName);
> mailboxName =
> mailboxManagerProvider.getMailboxManager().resolve(context);
> }
> context.setMailboxPath(mailboxName);
> return mailboxName;
> }
IMO buildFullName is the cause of many of these problems. i'm
unconvinced that building the full name is really something that
belongs in the processors. i think that really name resolution is
something that should be done by the mailbox manager. i suspect that
refactoring the design so that this is done in the mailbox would allow
a simple session to be used.
- robert
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]