Index: api/src/main/java/org/apache/james/imap/api/ImapConstants.java =================================================================== --- api/src/main/java/org/apache/james/imap/api/ImapConstants.java (revision 1062419) +++ api/src/main/java/org/apache/james/imap/api/ImapConstants.java (working copy) @@ -109,7 +109,12 @@ public static final String SUPPORTS_IDLE = "IDLE"; + public static final String SUPPORTS_XLIST = "XLIST"; + + public static final char NAMESPACE_PREFIX_CHAR = '#'; + public static final String NAMESPACE_PREFIX = String.valueOf(NAMESPACE_PREFIX_CHAR); + public static final String INBOX_NAME = "INBOX"; public static final String MIME_TYPE_TEXT = "TEXT"; @@ -191,6 +196,8 @@ public static final String LOGIN_COMMAND_NAME = "LOGIN"; public static final String LIST_COMMAND_NAME = "LIST"; + + public static final String XLIST_COMMAND_NAME = "XLIST"; public static final String FETCH_COMMAND_NAME = "FETCH"; @@ -215,6 +222,8 @@ public static final String APPEND_COMMAND_NAME = "APPEND"; public static final String LIST_RESPONSE_NAME = "LIST"; + + public static final String XLIST_RESPONSE_NAME = "XLIST"; public static final String LSUB_RESPONSE_NAME = "LSUB"; Index: api/src/main/java/org/apache/james/imap/api/process/MailboxType.java =================================================================== --- api/src/main/java/org/apache/james/imap/api/process/MailboxType.java (revision 0) +++ api/src/main/java/org/apache/james/imap/api/process/MailboxType.java (revision 0) @@ -0,0 +1,28 @@ +package org.apache.james.imap.api.process; + +/** + * represents well-known mailbox types along with their string representations + * used by XLIST command + * + * @author ihsahn + */ +public enum MailboxType { + + INBOX("\\Inbox"), + DRAFTS("\\Drafts"), + TRASH("\\Trash"), + SPAM("\\Spam"), + SENT("\\Sent"), + STARRED("\\Starred"), + ALLMAIL("\\AllMail"), + OTHER(null); + private String attributeName; + + MailboxType(String attributeName) { + this.attributeName = attributeName; + } + + public String getAttributeName() { + return attributeName; + } +} Index: api/src/main/java/org/apache/james/imap/api/process/MailboxTyper.java =================================================================== --- api/src/main/java/org/apache/james/imap/api/process/MailboxTyper.java (revision 0) +++ api/src/main/java/org/apache/james/imap/api/process/MailboxTyper.java (revision 0) @@ -0,0 +1,19 @@ +package org.apache.james.imap.api.process; + +import org.apache.james.mailbox.MailboxPath; + +/** + * + * @author ihsahn + */ +public interface MailboxTyper { + + /** + * returns MailboxType based on mailbox path + * @param session current ImapSession + * @param path path of mailbox, which type is being quered + * @return MailboxType value for passed mailbox, if there's no special + * function for particular mailbox, return OTHER. + */ + MailboxType getMailboxType(ImapSession session, MailboxPath path); +} Index: message/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java =================================================================== --- message/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java (revision 1062419) +++ message/src/main/java/org/apache/james/imap/decode/parser/ImapParserFactory.java (working copy) @@ -80,6 +80,8 @@ UnsubscribeCommandParser.class); _imapCommands.put(ImapConstants.LIST_COMMAND_NAME, ListCommandParser.class); + _imapCommands.put(ImapConstants.XLIST_COMMAND_NAME, + XListCommandParser.class); _imapCommands.put(ImapConstants.LSUB_COMMAND_NAME, LsubCommandParser.class); _imapCommands.put(ImapConstants.STATUS_COMMAND_NAME, Index: message/src/main/java/org/apache/james/imap/decode/parser/XListCommandParser.java =================================================================== --- message/src/main/java/org/apache/james/imap/decode/parser/XListCommandParser.java (revision 0) +++ message/src/main/java/org/apache/james/imap/decode/parser/XListCommandParser.java (revision 0) @@ -0,0 +1,27 @@ +package org.apache.james.imap.decode.parser; + +import org.apache.james.imap.api.ImapCommand; +import org.apache.james.imap.api.ImapConstants; +import org.apache.james.imap.api.ImapMessage; +import org.apache.james.imap.message.request.XListRequest; + +/** + * Parse XLIST commands + * + * @author ihsahn + */ +public class XListCommandParser extends ListCommandParser { + + public XListCommandParser() { + super(ImapCommand.authenticatedStateCommand(ImapConstants.XLIST_COMMAND_NAME)); + } + + @Override + protected ImapMessage createMessage(ImapCommand command, + final String referenceName, final String mailboxPattern, + final String tag) { + final ImapMessage result = new XListRequest(command, + referenceName, mailboxPattern, tag); + return result; + } +} Index: message/src/main/java/org/apache/james/imap/encode/ListingEncodingUtils.java =================================================================== --- message/src/main/java/org/apache/james/imap/encode/ListingEncodingUtils.java (revision 1062419) +++ message/src/main/java/org/apache/james/imap/encode/ListingEncodingUtils.java (working copy) @@ -24,6 +24,7 @@ import java.util.List; import org.apache.james.imap.api.ImapConstants; +import org.apache.james.imap.api.process.MailboxType; import org.apache.james.imap.message.response.AbstractListingResponse; /** @@ -63,6 +64,9 @@ if (response.hasNoChildren()) { attributes.add(ImapConstants.NAME_ATTRIBUTE_HAS_NO_CHILDREN); } + if (!MailboxType.OTHER.equals(response.getType())) { + attributes.add(response.getType().getAttributeName()); + } } else { attributes = null; } Index: message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java =================================================================== --- message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java (revision 1062419) +++ message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java (working copy) @@ -35,6 +35,7 @@ import org.apache.james.imap.encode.MailboxStatusResponseEncoder; import org.apache.james.imap.encode.SearchResponseEncoder; import org.apache.james.imap.encode.StatusResponseEncoder; +import org.apache.james.imap.encode.XListResponseEncoder; import org.apache.james.imap.encode.base.EndImapEncoder; /** @@ -70,8 +71,10 @@ searchResponseEncoder); final ListResponseEncoder listResponseEncoder = new ListResponseEncoder( lsubResponseEncoder); + final XListResponseEncoder xListResponseEncoder = new XListResponseEncoder( + listResponseEncoder); final FlagsResponseEncoder flagsResponseEncoder = new FlagsResponseEncoder( - listResponseEncoder); + xListResponseEncoder); final CapabilityResponseEncoder capabilityResponseEncoder = new CapabilityResponseEncoder( flagsResponseEncoder); final ContinuationResponseEncoder continuationResponseEncoder = new ContinuationResponseEncoder( Index: message/src/main/java/org/apache/james/imap/encode/XListResponseEncoder.java =================================================================== --- message/src/main/java/org/apache/james/imap/encode/XListResponseEncoder.java (revision 0) +++ message/src/main/java/org/apache/james/imap/encode/XListResponseEncoder.java (revision 0) @@ -0,0 +1,34 @@ +package org.apache.james.imap.encode; + +import java.io.IOException; + +import org.apache.james.imap.encode.base.AbstractChainedImapEncoder; +import org.apache.james.imap.message.response.AbstractListingResponse; +import org.apache.james.imap.message.response.XListResponse; + +import org.apache.james.imap.api.ImapConstants; +import org.apache.james.imap.api.ImapMessage; +import org.apache.james.imap.api.process.ImapSession; + +/** + * + * @author ihsahn + */ +public class XListResponseEncoder extends AbstractChainedImapEncoder { + + public XListResponseEncoder(ImapEncoder next) { + super(next); + } + + protected void doEncode(final ImapMessage acceptableMessage, + final ImapResponseComposer composer, ImapSession session) throws IOException { + final AbstractListingResponse response = (AbstractListingResponse) acceptableMessage; + ListingEncodingUtils.encodeListingResponse( + ImapConstants.XLIST_RESPONSE_NAME, composer, response); + } + + + protected boolean isAcceptable(ImapMessage message) { + return (message instanceof XListResponse); + } +} Index: message/src/main/java/org/apache/james/imap/message/request/XListRequest.java =================================================================== --- message/src/main/java/org/apache/james/imap/message/request/XListRequest.java (revision 0) +++ message/src/main/java/org/apache/james/imap/message/request/XListRequest.java (revision 0) @@ -0,0 +1,28 @@ +package org.apache.james.imap.message.request; + +import org.apache.james.imap.api.ImapCommand; + +/** + * XLIST command request + * @author ihsahn + */ +public class XListRequest extends AbstractImapRequest { + private final String baseReferenceName; + + private final String mailboxPattern; + + public XListRequest(final ImapCommand command, final String referenceName, + final String mailboxPattern, final String tag) { + super(tag, command); + this.baseReferenceName = referenceName; + this.mailboxPattern = mailboxPattern; + } + + public final String getBaseReferenceName() { + return baseReferenceName; + } + + public final String getMailboxPattern() { + return mailboxPattern; + } +} Index: message/src/main/java/org/apache/james/imap/message/response/AbstractListingResponse.java =================================================================== --- message/src/main/java/org/apache/james/imap/message/response/AbstractListingResponse.java (revision 1062419) +++ message/src/main/java/org/apache/james/imap/message/response/AbstractListingResponse.java (working copy) @@ -19,6 +19,7 @@ package org.apache.james.imap.message.response; +import org.apache.james.imap.api.process.MailboxType; /** * LIST and LSUB return identical data. @@ -40,12 +41,14 @@ private final char hierarchyDelimiter; private final String name; + + private MailboxType type; public AbstractListingResponse(final boolean noInferiors, final boolean noSelect, final boolean marked, final boolean unmarked, boolean hasChildren, boolean hasNoChildren, final String name, - final char hierarchyDelimiter) { + final char hierarchyDelimiter,final MailboxType type) { super(); this.noInferiors = noInferiors; this.noSelect = noSelect; @@ -55,6 +58,7 @@ this.noChildren = hasNoChildren; this.name = name; this.hierarchyDelimiter = hierarchyDelimiter; + this.type=type; } /** @@ -127,7 +131,16 @@ public boolean hasChildren() { return children; } + + /** + * returns type of the mailbox + * @return mailbox type + */ + public MailboxType getType() { + return type; + } + /** * Are any name attributes set? * @@ -135,7 +148,7 @@ * {@link #isMarked()} or {@link #isUnmarked(){ */ public final boolean isNameAttributed() { - return noInferiors || noSelect || marked || unmarked || children || noChildren; + return noInferiors || noSelect || marked || unmarked || children || noChildren || (!MailboxType.OTHER.equals(type)); } @Override @@ -144,6 +157,7 @@ int result = 1; result = PRIME * result + (children ? 1231 : 1237); result = PRIME * result + hierarchyDelimiter; + result = PRIME * result + type.ordinal(); result = PRIME * result + (marked ? 1231 : 1237); result = PRIME * result + ((name == null) ? 0 : name.hashCode()); result = PRIME * result + (noChildren ? 1231 : 1237); @@ -181,6 +195,8 @@ return false; if (unmarked != other.unmarked) return false; + if (!type.equals(other.type)) + return false; return true; } @@ -197,6 +213,7 @@ + "marked = " + this.marked + TAB + "unmarked = " + this.unmarked + TAB + "hierarchyDelimiter = " + this.hierarchyDelimiter + TAB + "name = " + this.name + TAB + + "type = " + this.type + TAB + " )"; return retValue; Index: message/src/main/java/org/apache/james/imap/message/response/ListResponse.java =================================================================== --- message/src/main/java/org/apache/james/imap/message/response/ListResponse.java (revision 1062419) +++ message/src/main/java/org/apache/james/imap/message/response/ListResponse.java (working copy) @@ -19,6 +19,7 @@ package org.apache.james.imap.message.response; import org.apache.james.imap.api.message.response.ImapResponseMessage; +import org.apache.james.imap.api.process.MailboxType; /** * Values an IMAP4rev1 LIST response. @@ -29,6 +30,6 @@ public ListResponse(final boolean noInferiors, final boolean noSelect, final boolean marked, final boolean unmarked, boolean hasChildren, boolean hasNoChildren, final String name, final char delimiter) { - super(noInferiors, noSelect, marked, unmarked, hasChildren, hasNoChildren, name, delimiter); + super(noInferiors, noSelect, marked, unmarked, hasChildren, hasNoChildren, name, delimiter,MailboxType.OTHER); } } Index: message/src/main/java/org/apache/james/imap/message/response/LSubResponse.java =================================================================== --- message/src/main/java/org/apache/james/imap/message/response/LSubResponse.java (revision 1062419) +++ message/src/main/java/org/apache/james/imap/message/response/LSubResponse.java (working copy) @@ -19,6 +19,7 @@ package org.apache.james.imap.message.response; import org.apache.james.imap.api.message.response.ImapResponseMessage; +import org.apache.james.imap.api.process.MailboxType; /** * Values an IMAP4rev1 LIST response. @@ -26,6 +27,6 @@ public final class LSubResponse extends AbstractListingResponse implements ImapResponseMessage { public LSubResponse(final String name, final boolean noSelect, final char delimiter) { - super(false, noSelect, false, false, false, false, name, delimiter); + super(false, noSelect, false, false, false, false, name, delimiter,MailboxType.OTHER); } } Index: message/src/main/java/org/apache/james/imap/message/response/XListResponse.java =================================================================== --- message/src/main/java/org/apache/james/imap/message/response/XListResponse.java (revision 0) +++ message/src/main/java/org/apache/james/imap/message/response/XListResponse.java (revision 0) @@ -0,0 +1,19 @@ +package org.apache.james.imap.message.response; + +import org.apache.james.imap.api.message.response.ImapResponseMessage; +import org.apache.james.imap.api.process.MailboxType; + +/** + * XLIST command response + * + * @author ihsahn + */ +public class XListResponse extends AbstractListingResponse implements + ImapResponseMessage { + + public XListResponse(final boolean noInferiors, final boolean noSelect, + final boolean marked, final boolean unmarked, + boolean hasChildren, boolean hasNoChildren, final String name, final char delimiter,final MailboxType type) { + super(noInferiors, noSelect, marked, unmarked, hasChildren, hasNoChildren, name, delimiter,type); + } +} Index: processor/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java =================================================================== --- processor/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java (revision 1062419) +++ processor/src/main/java/org/apache/james/imap/processor/DefaultProcessorChain.java (working copy) @@ -22,6 +22,7 @@ import org.apache.james.imap.api.message.response.StatusResponseFactory; import org.apache.james.imap.api.process.ImapProcessor; +import org.apache.james.imap.api.process.MailboxTyper; import org.apache.james.imap.processor.fetch.FetchProcessor; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.SubscriptionManager; @@ -35,8 +36,8 @@ final ImapProcessor chainEndProcessor, final MailboxManager mailboxManager, final SubscriptionManager subscriptionManager, - final StatusResponseFactory statusResponseFactory) { - return createDefaultChain(chainEndProcessor, mailboxManager, subscriptionManager, statusResponseFactory, 100); + final StatusResponseFactory statusResponseFactory,MailboxTyper mailboxTyper) { + return createDefaultChain(chainEndProcessor, mailboxManager, subscriptionManager, statusResponseFactory, mailboxTyper,100); } @@ -44,7 +45,7 @@ final ImapProcessor chainEndProcessor, final MailboxManager mailboxManager, final SubscriptionManager subscriptionManager, - final StatusResponseFactory statusResponseFactory, int batchSize) { + final StatusResponseFactory statusResponseFactory, MailboxTyper mailboxTyper,int batchSize) { final SystemMessageProcessor systemProcessor = new SystemMessageProcessor(chainEndProcessor, mailboxManager); final LogoutProcessor logoutProcessor = new LogoutProcessor( systemProcessor, mailboxManager, statusResponseFactory); @@ -92,13 +93,16 @@ mailboxManager, subscriptionManager, statusResponseFactory); final ListProcessor listProcessor = new ListProcessor(lsubProcessor, mailboxManager, statusResponseFactory); + final XListProcessor xlistProcessor = new XListProcessor(listProcessor, + mailboxManager, statusResponseFactory,mailboxTyper); final SearchProcessor searchProcessor = new SearchProcessor( - listProcessor, mailboxManager, statusResponseFactory); + xlistProcessor, mailboxManager, statusResponseFactory); final SelectProcessor selectProcessor = new SelectProcessor( searchProcessor, mailboxManager, statusResponseFactory); final NamespaceProcessor namespaceProcessor = new NamespaceProcessor( selectProcessor, mailboxManager, statusResponseFactory); + capabilityProcessor.addProcessor(xlistProcessor); final ImapProcessor fetchProcessor = new FetchProcessor(namespaceProcessor, mailboxManager, statusResponseFactory, batchSize); Index: processor/src/main/java/org/apache/james/imap/processor/ListProcessor.java =================================================================== --- processor/src/main/java/org/apache/james/imap/processor/ListProcessor.java (revision 1062419) +++ processor/src/main/java/org/apache/james/imap/processor/ListProcessor.java (working copy) @@ -31,6 +31,8 @@ import org.apache.james.imap.api.message.response.StatusResponseFactory; import org.apache.james.imap.api.process.ImapProcessor; import org.apache.james.imap.api.process.ImapSession; +import org.apache.james.imap.api.process.MailboxType; +import org.apache.james.imap.api.process.MailboxTyper; import org.apache.james.imap.message.request.ListRequest; import org.apache.james.imap.message.response.ListResponse; import org.apache.james.mailbox.MailboxConstants; @@ -61,12 +63,12 @@ final String baseReferenceName = request.getBaseReferenceName(); final String mailboxPatternString = request.getMailboxPattern(); doProcess(baseReferenceName, mailboxPatternString, session, tag, - command, responder); + command, responder,null); } protected ImapResponseMessage createResponse(boolean noInferior, boolean noSelect, boolean marked, boolean unmarked, - boolean hasChildren, boolean hasNoChildren, String mailboxName, char delimiter) { + boolean hasChildren, boolean hasNoChildren, String mailboxName, char delimiter,MailboxType type) { return new ListResponse(noInferior, noSelect, marked, unmarked, hasChildren, hasNoChildren, mailboxName, delimiter); } @@ -93,7 +95,7 @@ */ protected final void doProcess(final String referenceName, final String mailboxName, final ImapSession session, - final String tag, ImapCommand command, final Responder responder) { + final String tag, ImapCommand command, final Responder responder,final MailboxTyper mailboxTyper) { try { // Should the namespace section be returned or not? final boolean isRelative; @@ -128,7 +130,7 @@ MailboxPath rootPath = new MailboxPath(referenceRoot, "", ""); results = new ArrayList(1); results.add(SimpleMailboxMetaData.createNoSelect(rootPath, mailboxSession.getPathDelimiter())); - } + } else { // If the mailboxPattern is fully qualified, ignore the reference name. String finalReferencename = referenceName; @@ -151,7 +153,7 @@ } for (final MailboxMetaData metaData: results) { - processResult(responder, isRelative, metaData); + processResult(responder, isRelative, metaData,getMailboxType(session,mailboxTyper,metaData.getPath())); } okComplete(command, tag, responder); @@ -160,7 +162,7 @@ } } - void processResult(final Responder responder, final boolean relative, final MailboxMetaData listResult) { + void processResult(final Responder responder, final boolean relative, final MailboxMetaData listResult,final MailboxType mailboxType) { final char delimiter = listResult.getHierarchyDelimiter(); final String mailboxName = mailboxName(relative, listResult.getPath(), delimiter); @@ -183,7 +185,22 @@ break; } responder.respond(createResponse(noInferior, noSelect, marked, - unmarked, hasChildren, hasNoChildren, mailboxName, delimiter)); + unmarked, hasChildren, hasNoChildren, mailboxName, delimiter,mailboxType)); } + /** + * retrieve mailboxType for specified mailboxPath using provided MailboxTyper + * @param session current imap session + * @param mailboxTyper provided MailboxTyper used to retrieve mailbox type + * @param path mailbox's path + * @return MailboxType value + */ + private MailboxType getMailboxType(ImapSession session, MailboxTyper mailboxTyper, MailboxPath path) { + MailboxType result = MailboxType.OTHER; + if (mailboxTyper != null) { + result = mailboxTyper.getMailboxType(session, path); + } + return result; + } + } Index: processor/src/main/java/org/apache/james/imap/processor/main/DefaultImapProcessorFactory.java =================================================================== --- processor/src/main/java/org/apache/james/imap/processor/main/DefaultImapProcessorFactory.java (revision 1062419) +++ processor/src/main/java/org/apache/james/imap/processor/main/DefaultImapProcessorFactory.java (working copy) @@ -22,6 +22,7 @@ import org.apache.james.imap.api.message.response.StatusResponseFactory; import org.apache.james.imap.api.process.ImapProcessor; import org.apache.james.imap.api.process.ImapProcessorFactory; +import org.apache.james.imap.api.process.MailboxTyper; import org.apache.james.imap.message.response.UnpooledStatusResponseFactory; import org.apache.james.imap.processor.DefaultProcessorChain; import org.apache.james.imap.processor.base.ImapResponseMessageProcessor; @@ -34,13 +35,19 @@ */ public class DefaultImapProcessorFactory implements ImapProcessorFactory { - public static final ImapProcessor createDefaultProcessor(final MailboxManager mailboxManager, final SubscriptionManager subscriptionManager) { + public static final ImapProcessor createDefaultProcessor(final MailboxManager mailboxManager, + final SubscriptionManager subscriptionManager) { + return createDefaultProcessor(mailboxManager, subscriptionManager, null); + } + + public static final ImapProcessor createDefaultProcessor(final MailboxManager mailboxManager, + final SubscriptionManager subscriptionManager,final MailboxTyper mailboxTyper) { final StatusResponseFactory statusResponseFactory = new UnpooledStatusResponseFactory(); final UnknownRequestProcessor unknownRequestImapProcessor = new UnknownRequestProcessor( statusResponseFactory); final ImapProcessor imap4rev1Chain = DefaultProcessorChain .createDefaultChain(unknownRequestImapProcessor, - mailboxManager, subscriptionManager, statusResponseFactory); + mailboxManager, subscriptionManager, statusResponseFactory,mailboxTyper); final ImapProcessor result = new ImapResponseMessageProcessor( imap4rev1Chain); return result; @@ -66,11 +73,22 @@ this.subscriptionManager = subscriptionManager; } + private MailboxTyper mailboxTyper; + + public MailboxTyper getMailboxTyper() { + return mailboxTyper; + } + + public void setMailboxTyper(MailboxTyper mailboxTyper) { + this.mailboxTyper = mailboxTyper; + } + + /* * (non-Javadoc) * @see org.apache.james.imap.api.process.ImapProcessorFactory#buildImapProcessor() */ public ImapProcessor buildImapProcessor() { - return createDefaultProcessor(mailboxManager, subscriptionManager); + return createDefaultProcessor(mailboxManager, subscriptionManager,mailboxTyper); } } Index: processor/src/main/java/org/apache/james/imap/processor/XListProcessor.java =================================================================== --- processor/src/main/java/org/apache/james/imap/processor/XListProcessor.java (revision 0) +++ processor/src/main/java/org/apache/james/imap/processor/XListProcessor.java (revision 0) @@ -0,0 +1,71 @@ +package org.apache.james.imap.processor; + +import java.util.List; +import static org.apache.james.imap.api.ImapConstants.SUPPORTS_XLIST; +import java.util.Arrays; +import java.util.Collections; +import org.apache.james.imap.api.ImapCommand; +import org.apache.james.imap.api.ImapMessage; +import org.apache.james.imap.api.message.request.ImapRequest; +import org.apache.james.imap.api.message.response.ImapResponseMessage; + +import org.apache.james.imap.api.message.response.StatusResponseFactory; +import org.apache.james.imap.api.process.ImapProcessor; +import org.apache.james.imap.api.process.ImapSession; +import org.apache.james.imap.api.process.MailboxType; +import org.apache.james.imap.api.process.MailboxTyper; +import org.apache.james.imap.message.request.XListRequest; +import org.apache.james.imap.message.response.XListResponse; +import org.apache.james.mailbox.MailboxManager; + +/** + * Processes XLIST command + * + * @author ihsahn + */ +public class XListProcessor extends ListProcessor implements CapabilityImplementingProcessor { + + private MailboxTyper mailboxTyper; + + //some interface + public XListProcessor(final ImapProcessor next, + final MailboxManager mailboxManager, + final StatusResponseFactory factory, + final MailboxTyper mailboxTyper) { + super(next, mailboxManager, factory); + this.mailboxTyper=mailboxTyper; + } + + public List getImplementedCapabilities(ImapSession session) { + //if there's no mailboxTyper, do not annnoyce XLIST capability + if (mailboxTyper==null) + { + return Collections.emptyList(); + } + + return Arrays.asList(SUPPORTS_XLIST); + } + + @Override + protected boolean isAcceptable(ImapMessage message) { + return (message instanceof XListRequest) ; + } + + @Override + protected void doProcess(ImapRequest message, ImapSession session, + String tag, ImapCommand command, Responder responder) { + final XListRequest request = (XListRequest) message; + final String baseReferenceName = request.getBaseReferenceName(); + final String mailboxPatternString = request.getMailboxPattern(); + doProcess(baseReferenceName, mailboxPatternString, session, tag, + command, responder,mailboxTyper); + } + + @Override + protected ImapResponseMessage createResponse(boolean noInferior, + boolean noSelect, boolean marked, boolean unmarked, + boolean hasChildren, boolean hasNoChildren, String mailboxName, char delimiter,MailboxType type) { + return new XListResponse(noInferior, noSelect, marked, unmarked, + hasChildren, hasNoChildren, mailboxName, delimiter,type); + } +} Index: processor/src/test/java/org/apache/james/imap/processor/ListProcessorTest.java =================================================================== --- processor/src/test/java/org/apache/james/imap/processor/ListProcessorTest.java (revision 1062419) +++ processor/src/test/java/org/apache/james/imap/processor/ListProcessorTest.java (working copy) @@ -23,6 +23,7 @@ import org.apache.james.imap.api.message.response.StatusResponseFactory; import org.apache.james.imap.api.process.ImapProcessor; import org.apache.james.imap.api.process.ImapSession; +import org.apache.james.imap.api.process.MailboxType; import org.apache.james.imap.message.response.ListResponse; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxMetaData; @@ -98,7 +99,7 @@ mockery.checking(new Expectations() {{ oneOf(responder).respond(with(equal(createResponse(false, false, false, false, true, false, '.', "INBOX")))); }}); - processor.processResult(responder, false, result); + processor.processResult(responder, false, result,MailboxType.OTHER); } @Test @@ -107,7 +108,7 @@ mockery.checking(new Expectations() {{ oneOf(responder).respond(with(equal(createResponse(false, false, false, false, false, true, '.', "INBOX")))); }}); - processor.processResult(responder, false, result); + processor.processResult(responder, false, result,MailboxType.OTHER); } @Test @@ -116,7 +117,7 @@ mockery.checking(new Expectations() {{ oneOf(responder).respond(with(equal(createResponse(true, false, false, false, false, false, '.', "INBOX")))); }}); - processor.processResult(responder, false, result); + processor.processResult(responder, false, result,MailboxType.OTHER); } @Test @@ -125,7 +126,7 @@ mockery.checking(new Expectations() {{ oneOf(responder).respond(with(equal(createResponse(false, true, false, false, false, false, '.', "INBOX")))); }}); - processor.processResult(responder, false, result); + processor.processResult(responder, false, result,MailboxType.OTHER); } @Test @@ -134,7 +135,7 @@ mockery.checking(new Expectations() {{ oneOf(responder).respond(with(equal(createResponse(false, false, false, true, false, false, '.', "INBOX")))); }}); - processor.processResult(responder, false, result); + processor.processResult(responder, false, result,MailboxType.OTHER); } @Test @@ -143,6 +144,6 @@ mockery.checking(new Expectations() {{ oneOf(responder).respond(with(equal(createResponse(false, false, true, false, false, false, '.', "INBOX")))); }}); - processor.processResult(responder, false, result); + processor.processResult(responder, false, result,MailboxType.OTHER); } }