james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Robert Burrell Donkin <robertburrelldon...@gmail.com>
Subject Re: [jira] Created: (IMAP-71) Design: Consolidate Sessions
Date Wed, 18 Mar 2009 13:53:36 GMT
On Wed, Mar 18, 2009 at 12:19 PM, Martin.Bergljung
<Martin.Bergljung@opsera.com> 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: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message