Author: norman
Date: Sun May 29 18:42:23 2011
New Revision: 1128932
URL: http://svn.apache.org/viewvc?rev=1128932&view=rev
Log:
Add support for the ESEARCH extension. See IMAP-308 and rfc4731
Added:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchOperation.java
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchResultOption.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/SearchCommandParser.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/SearchRequest.java
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SearchProcessorTest.java
Added:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchOperation.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchOperation.java?rev=1128932&view=auto
==============================================================================
---
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchOperation.java
(added)
+++
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchOperation.java
Sun May 29 18:42:23 2011
@@ -0,0 +1,43 @@
+
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.james.imap.api.message.request;
+
+import java.util.List;
+
+public final class SearchOperation {
+
+ private final SearchKey key;
+ private final List<SearchResultOption> options;
+
+ public SearchOperation(SearchKey key, List<SearchResultOption> options) {
+ this.key = key;
+ this.options = options;
+ }
+
+ public SearchKey getSearchKey() {
+ return key;
+ }
+ public List<SearchResultOption> getResultOptions() {
+ return options;
+ }
+
+
+
+}
Added:
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchResultOption.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchResultOption.java?rev=1128932&view=auto
==============================================================================
---
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchResultOption.java
(added)
+++
james/imap/trunk/api/src/main/java/org/apache/james/imap/api/message/request/SearchResultOption.java
Sun May 29 18:42:23 2011
@@ -0,0 +1,45 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.james.imap.api.message.request;
+
+/**
+ * Represent ESEARCH result options. See RFC4731
+ *
+ */
+public enum SearchResultOption {
+ /**
+ * Return all matched message uids formatted as sequence-set
+ */
+ ALL,
+
+ /**
+ * Return the minimum uid matched
+ */
+ MIN,
+
+ /**
+ * Return the maximum uid matched
+ */
+ MAX,
+
+ /**
+ * Return the count of matched messages
+ */
+ COUNT
+}
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/SearchCommandParser.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/SearchCommandParser.java?rev=1128932&r1=1128931&r2=1128932&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/SearchCommandParser.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/decode/parser/SearchCommandParser.java
Sun May 29 18:42:23 2011
@@ -22,6 +22,7 @@ import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
@@ -35,6 +36,8 @@ import org.apache.james.imap.api.display
import org.apache.james.imap.api.message.IdRange;
import org.apache.james.imap.api.message.request.DayMonthYear;
import org.apache.james.imap.api.message.request.SearchKey;
+import org.apache.james.imap.api.message.request.SearchOperation;
+import org.apache.james.imap.api.message.request.SearchResultOption;
import org.apache.james.imap.api.message.response.StatusResponse;
import org.apache.james.imap.api.message.response.StatusResponseFactory;
import org.apache.james.imap.api.message.response.StatusResponse.ResponseCode;
@@ -109,6 +112,8 @@ public class SearchCommandParser extends
case 'Q':
throw new
DecodingException(HumanReadableText.ILLEGAL_ARGUMENTS, "Unknown search key");
case 'R':
+ nextIsE(request);
+ nextIsC(request);
return recent(request);
case 'S':
return s(request, charset);
@@ -144,10 +149,14 @@ public class SearchCommandParser extends
private int consumeAndCap(ImapRequestLineReader request) throws
DecodingException {
final char next = request.consume();
+ return cap(next);
+ }
+
+ private int cap(char next) {
final int cap = next > 'Z' ? next ^ 32 : next;
return cap;
}
-
+
private SearchKey cc(ImapRequestLineReader request, final Charset charset)
throws DecodingException {
final SearchKey result;
nextIsSpace(request);
@@ -545,8 +554,8 @@ public class SearchCommandParser extends
private SearchKey recent(ImapRequestLineReader request) throws
DecodingException {
final SearchKey result;
- nextIsE(request);
- nextIsC(request);
+ //nextIsE(request);
+ //nextIsC(request);
nextIsE(request);
nextIsN(request);
nextIsT(request);
@@ -887,6 +896,54 @@ public class SearchCommandParser extends
}
}
+ private List<SearchResultOption> parseOptions(ImapRequestLineReader
reader) throws DecodingException {
+ List<SearchResultOption> options = new ArrayList<SearchResultOption>();
+ nextIs(reader, '(', '(');
+ reader.nextWordChar();
+
+ int cap = consumeAndCap(reader);
+
+ while (cap != ')') {
+ switch (cap) {
+ case 'A':
+ nextIsL(reader);
+ nextIsL(reader);
+ options.add(SearchResultOption.ALL);
+
+ case 'C':
+ nextIsO(reader);
+ nextIsU(reader);
+ nextIsN(reader);
+ nextIsT(reader);
+ options.add(SearchResultOption.COUNT);
+ break;
+ case 'M':
+ final int c = consumeAndCap(reader);
+ switch (c) {
+ case 'A':
+ nextIsX(reader);
+ options.add(SearchResultOption.MAX);
+ break;
+ case 'I':
+ nextIsM(reader);
+ options.add(SearchResultOption.MIN);
+ break;
+ default:
+ throw new
DecodingException(HumanReadableText.ILLEGAL_ARGUMENTS, "Unknown search key");
+ }
+ default:
+ throw new
DecodingException(HumanReadableText.ILLEGAL_ARGUMENTS, "Unknown search key");
+ }
+ reader.nextWordChar();
+ cap = consumeAndCap(reader);
+ }
+ // if the options are empty then we parsed RETURN () which is a
shortcut for ALL.
+ // See http://www.faqs.org/rfcs/rfc4731.html 3.1
+ if (options.isEmpty()) {
+ options.add(SearchResultOption.ALL);
+ }
+ return options;
+ }
/*
* (non-Javadoc)
*
@@ -898,10 +955,45 @@ public class SearchCommandParser extends
*/
protected ImapMessage decode(ImapCommand command, ImapRequestLineReader
request, String tag, boolean useUids, ImapSession session) throws
DecodingException {
try {
+ SearchKey recent = null;
+ List<SearchResultOption> options = null;
+ int c = cap(request.nextWordChar());
+ if (c == 'R') {
+ // if we found a R its either RECENT or RETURN so consume it
+ request.consume();
+
+ nextIsE(request);
+ c = consumeAndCap(request);
+
+ switch (c) {
+ case 'C':
+ recent = recent(request);
+ break;
+ case 'T':
+ nextIsU(request);
+ nextIsR(request);
+ nextIsN(request);
+ options = parseOptions(request);
+ default:
+ throw new
DecodingException(HumanReadableText.ILLEGAL_ARGUMENTS, "Unknown search key");
+ }
+ }
+
// Parse the search term from the request
final SearchKey key = decode(request);
-
- final ImapMessage result = new SearchRequest(command, key,
useUids, tag);
+
+ final SearchKey finalKey;
+ if (recent != null) {
+ finalKey = SearchKey.buildAnd(Arrays.asList(recent, key));
+ } else {
+ finalKey = key;
+ }
+
+ if (options == null) {
+ options = new ArrayList<SearchResultOption>();
+ }
+
+ final ImapMessage result = new SearchRequest(command, new
SearchOperation(finalKey, options), useUids, tag);
return result;
} catch (IllegalCharsetNameException e) {
session.getLog().debug("Unable to decode request", e);
@@ -911,4 +1003,5 @@ public class SearchCommandParser extends
return unsupportedCharset(tag, command);
}
}
+
}
Added:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java?rev=1128932&view=auto
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java
(added)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ESearchResponseEncoder.java
Sun May 29 18:42:23 2011
@@ -0,0 +1,81 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+package org.apache.james.imap.encode;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.james.imap.api.ImapMessage;
+import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.request.SearchResultOption;
+import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.encode.base.AbstractChainedImapEncoder;
+import org.apache.james.imap.message.response.ESearchResponse;
+
+/**
+ * Encoders IMAP4rev1 <code>ESEARCH</code> responses.
+ */
+public class ESearchResponseEncoder extends AbstractChainedImapEncoder {
+
+ public ESearchResponseEncoder(ImapEncoder next) {
+ super(next);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.apache.james.imap.encode.base.AbstractChainedImapEncoder#doEncode(org.apache.james.imap.api.ImapMessage,
org.apache.james.imap.encode.ImapResponseComposer,
org.apache.james.imap.api.process.ImapSession)
+ */
+ protected void doEncode(ImapMessage acceptableMessage,
ImapResponseComposer composer, ImapSession session) throws IOException {
+ ESearchResponse response = (ESearchResponse) acceptableMessage;
+ String tag = response.getTag();
+ long min = response.getMinUid();
+ long max = response.getMaxUid();
+ long count = response.getCount();
+ IdRange[] all = response.getAll();
+ boolean useUid = response.getUseUid();
+ List<SearchResultOption> options = response.getSearchResultOptions();
+
+
composer.untagged().message("ESEARCH").openParen().message("TAG").quote(tag).closeParen();
+ if (useUid) {
+ composer.message("UID");
+ }
+ if (min > -1 && options.contains(SearchResultOption.MIN)) {
+ composer.message(SearchResultOption.MIN.name()).message(min);
+ }
+ if (max > -1 && options.contains(SearchResultOption.MAX)) {
+ composer.message(SearchResultOption.MAX.name()).message(max);
+ }
+ if (options.contains(SearchResultOption.COUNT)) {
+ composer.message(SearchResultOption.COUNT.name()).message(count);
+ }
+ if (all != null && all.length > 0 &&
options.contains(SearchResultOption.ALL)) {
+ composer.message(SearchResultOption.ALL.name());
+ composer.sequenceSet(all);
+ }
+ composer.end();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.apache.james.imap.encode.base.AbstractChainedImapEncoder#isAcceptable(org.apache.james.imap.api.ImapMessage)
+ */
+ protected boolean isAcceptable(ImapMessage message) {
+ return (message instanceof ESearchResponse);
+ }
+}
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java?rev=1128932&r1=1128931&r2=1128932&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/ImapResponseComposer.java
Sun May 29 18:42:23 2011
@@ -26,6 +26,7 @@ import java.util.List;
import javax.mail.Flags;
import org.apache.james.imap.api.ImapCommand;
+import org.apache.james.imap.api.message.IdRange;
import org.apache.james.imap.message.response.Literal;
public interface ImapResponseComposer {
@@ -237,6 +238,8 @@ public interface ImapResponseComposer {
public ImapResponseComposer message(final long number) throws IOException;
+ public ImapResponseComposer sequenceSet(final IdRange[] ranges) throws
IOException;
+
/**
* Write a CRLF and flush the composer which will write the content of it
to the socket
*
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java?rev=1128932&r1=1128931&r2=1128932&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/base/ImapResponseComposerImpl.java
Sun May 29 18:42:23 2011
@@ -31,6 +31,7 @@ import javax.mail.Flags;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.james.imap.api.ImapCommand;
import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.api.message.IdRange;
import org.apache.james.imap.encode.ImapResponseComposer;
import org.apache.james.imap.encode.ImapResponseWriter;
import org.apache.james.imap.message.response.Literal;
@@ -829,4 +830,20 @@ public class ImapResponseComposerImpl im
}
}
+ /*
+ * (non-Javadoc)
+ * @see
org.apache.james.imap.encode.ImapResponseComposer#sequenceSet(org.apache.james.imap.api.message.IdRange[])
+ */
+ public ImapResponseComposer sequenceSet(IdRange[] ranges) throws
IOException {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0 ; i< ranges.length; i++) {
+ IdRange range = ranges[i];
+ sb.append(range.getFormattedString());
+ if (i + 1 < ranges.length) {
+ sb.append(",");
+ }
+ }
+ return message(sb.toString());
+ }
+
}
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java?rev=1128932&r1=1128931&r2=1128932&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
Sun May 29 18:42:23 2011
@@ -23,6 +23,7 @@ import org.apache.james.imap.api.display
import org.apache.james.imap.encode.AuthenticateResponseEncoder;
import org.apache.james.imap.encode.CapabilityResponseEncoder;
import org.apache.james.imap.encode.ContinuationResponseEncoder;
+import org.apache.james.imap.encode.ESearchResponseEncoder;
import org.apache.james.imap.encode.ExistsResponseEncoder;
import org.apache.james.imap.encode.ExpungeResponseEncoder;
import org.apache.james.imap.encode.FetchResponseEncoder;
@@ -71,8 +72,8 @@ public class DefaultImapEncoderFactory i
final CapabilityResponseEncoder capabilityResponseEncoder = new
CapabilityResponseEncoder(flagsResponseEncoder);
final ContinuationResponseEncoder continuationResponseEncoder = new
ContinuationResponseEncoder(capabilityResponseEncoder, localizer);
final AuthenticateResponseEncoder authResponseEncoder = new
AuthenticateResponseEncoder(continuationResponseEncoder);
-
- return authResponseEncoder;
+ final ESearchResponseEncoder esearchResponseEncoder = new
ESearchResponseEncoder(authResponseEncoder);
+ return esearchResponseEncoder;
}
private final Localizer localizer;
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/SearchRequest.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/SearchRequest.java?rev=1128932&r1=1128931&r2=1128932&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/SearchRequest.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/request/SearchRequest.java
Sun May 29 18:42:23 2011
@@ -19,22 +19,22 @@
package org.apache.james.imap.message.request;
import org.apache.james.imap.api.ImapCommand;
-import org.apache.james.imap.api.message.request.SearchKey;
+import org.apache.james.imap.api.message.request.SearchOperation;
public class SearchRequest extends AbstractImapRequest {
- private final SearchKey searchKey;
+ private final SearchOperation operation;
private final boolean useUids;
- public SearchRequest(final ImapCommand command, final SearchKey SearchKey,
final boolean useUids, final String tag) {
+ public SearchRequest(final ImapCommand command, final SearchOperation
operation, final boolean useUids, final String tag) {
super(tag, command);
- this.searchKey = SearchKey;
+ this.operation = operation;
this.useUids = useUids;
}
- public final SearchKey getSearchKey() {
- return searchKey;
+ public final SearchOperation getSearchOperation() {
+ return operation;
}
public final boolean isUseUids() {
Added:
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java?rev=1128932&view=auto
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java
(added)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/message/response/ESearchResponse.java
Sun May 29 18:42:23 2011
@@ -0,0 +1,77 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.imap.message.response;
+
+import java.util.List;
+
+import org.apache.james.imap.api.message.IdRange;
+import org.apache.james.imap.api.message.request.SearchResultOption;
+import org.apache.james.imap.api.message.response.ImapResponseMessage;
+
+public class ESearchResponse implements ImapResponseMessage{
+
+ private final long minUid;
+ private final long maxUid;
+ private final long count;
+ private final IdRange[] all;
+ private final String tag;
+ private boolean useUid;
+ private List<SearchResultOption> options;
+
+ public ESearchResponse(final long minUid, final long maxUid, final long
count, final IdRange[] all, String tag, final boolean useUid, final
List<SearchResultOption> options) {
+ super();
+ this.options = options;
+ this.minUid = minUid;
+ this.maxUid = maxUid;
+ this.count = count;
+ this.all = all;
+ this.tag = tag;
+ this.useUid = useUid;
+ }
+
+ public final long getCount() {
+ return count;
+ }
+
+ public final long getMinUid() {
+ return minUid;
+ }
+
+ public final long getMaxUid() {
+ return maxUid;
+ }
+
+ public IdRange[] getAll() {
+ return all;
+ }
+
+ public String getTag() {
+ return tag;
+ }
+
+ public boolean getUseUid() {
+ return useUid;
+ }
+
+ public List<SearchResultOption> getSearchResultOptions() {
+ return options;
+ }
+
+}
Modified:
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/SearchProcessor.java?rev=1128932&r1=1128931&r2=1128932&view=diff
==============================================================================
---
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
(original)
+++
james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/SearchProcessor.java
Sun May 29 18:42:23 2011
@@ -36,11 +36,15 @@ import org.apache.james.imap.api.display
import org.apache.james.imap.api.message.IdRange;
import org.apache.james.imap.api.message.request.DayMonthYear;
import org.apache.james.imap.api.message.request.SearchKey;
+import org.apache.james.imap.api.message.request.SearchOperation;
+import org.apache.james.imap.api.message.request.SearchResultOption;
+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.SelectedMailbox;
import org.apache.james.imap.message.request.SearchRequest;
+import org.apache.james.imap.message.response.ESearchResponse;
import org.apache.james.imap.message.response.SearchResponse;
import org.apache.james.mailbox.MailboxException;
import org.apache.james.mailbox.MailboxManager;
@@ -70,7 +74,8 @@ public class SearchProcessor extends Abs
*/
protected void doProcess(SearchRequest request, ImapSession session,
String tag, ImapCommand command, Responder responder) {
try {
- final SearchKey searchKey = request.getSearchKey();
+ final SearchOperation operation = request.getSearchOperation();
+ final SearchKey searchKey = operation.getSearchKey();
final boolean useUids = request.isUseUids();
final MessageManager mailbox = getSelectedMailbox(session);
@@ -79,8 +84,36 @@ public class SearchProcessor extends Abs
final Collection<Long> results = findIds(useUids, session,
mailbox, query);
final long[] ids = toArray(results);
- final SearchResponse response = new SearchResponse(ids);
+ List<SearchResultOption> resultOptions =
operation.getResultOptions();
+ final ImapResponseMessage response;
+ if (resultOptions == null || resultOptions.isEmpty()) {
+ response = new SearchResponse(ids);
+ } else {
+ long min = -1;
+ long max = -1;
+ long count = ids.length;
+ IdRange[] idRanges;
+
+ if (ids.length > 0) {
+ min = ids[0];
+ max = ids[ids.length -1];
+ }
+ List<Long> idList = new ArrayList<Long>(ids.length);
+ for ( int i = 0; i < ids.length; i++) {
+ idList.add(ids[i]);
+ }
+ List<MessageRange> ranges = MessageRange.toRanges(idList);
+ idRanges = new IdRange[ranges.size()];
+ for (int i = 0 ; i <ranges.size(); i++) {
+ MessageRange range = ranges.get(i);
+ idRanges[i] = new IdRange(range.getUidFrom(),
range.getUidTo());
+ }
+
+ response = new ESearchResponse(min, max, count, idRanges, tag,
useUids, resultOptions);
+
+ }
responder.respond(response);
+
boolean omitExpunged = (!useUids);
unsolicitedResponses(session, responder, omitExpunged, useUids);
okComplete(command, tag, responder);
@@ -283,6 +316,6 @@ public class SearchProcessor extends Abs
* @see
org.apache.james.imap.processor.CapabilityImplementingProcessor#getImplementedCapabilities(org.apache.james.imap.api.process.ImapSession)
*/
public List<String> getImplementedCapabilities(ImapSession session) {
- return Arrays.asList("WITHIN");
+ return Arrays.asList("WITHIN", "SEARCHRES");
}
}
Modified:
james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SearchProcessorTest.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SearchProcessorTest.java?rev=1128932&r1=1128931&r2=1128932&view=diff
==============================================================================
---
james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SearchProcessorTest.java
(original)
+++
james/imap/trunk/processor/src/test/java/org/apache/james/imap/processor/SearchProcessorTest.java
Sun May 29 18:42:23 2011
@@ -37,6 +37,8 @@ import org.apache.james.imap.api.display
import org.apache.james.imap.api.message.IdRange;
import org.apache.james.imap.api.message.request.DayMonthYear;
import org.apache.james.imap.api.message.request.SearchKey;
+import org.apache.james.imap.api.message.request.SearchOperation;
+import org.apache.james.imap.api.message.request.SearchResultOption;
import org.apache.james.imap.api.message.response.StatusResponse;
import org.apache.james.imap.api.message.response.StatusResponseFactory;
import org.apache.james.imap.api.process.ImapProcessor;
@@ -494,7 +496,7 @@ public class SearchProcessorTest {
allowing(selectedMailbox).hasNewApplicableFlags();
will(returnValue(false));
}});
- SearchRequest message = new SearchRequest(command, key, false, TAG);
+ SearchRequest message = new SearchRequest(command, new
SearchOperation(key, new ArrayList<SearchResultOption>()), false, TAG);
processor.doProcess(message, session, TAG, command, responder);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]