Author: norman
Date: Fri Aug 19 11:25:43 2011
New Revision: 1159594

URL: http://svn.apache.org/viewvc?rev=1159594&view=rev
Log:
Make sure SEARCH <sequence-set> will ignore invalid ranges and so be conform 
with the rfc. See IMAP-292

Modified:
    
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

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=1159594&r1=1159593&r2=1159594&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
 Fri Aug 19 11:25:43 2011
@@ -374,19 +374,78 @@ public class SearchProcessor extends Abs
         return new Date(res);
     }
 
+    /**
+     * Create a {@link Criterion} for the given sequence-sets. This include 
special handling which is needed for SEARCH to not return a BAD response on a 
invalid message-set. 
+     * See IMAP-292 for more details.
+     * 
+     * 
+     * @param sequenceNumbers
+     * @param session
+     * @param msn
+     * @return crit
+     * @throws MessageRangeException
+     */
     private Criterion sequence(IdRange[] sequenceNumbers, final ImapSession 
session, boolean msn) throws MessageRangeException {
         final int length = sequenceNumbers.length;
         final List<SearchQuery.NumericRange> ranges = new 
ArrayList<SearchQuery.NumericRange>();
-        for (int i = 0; i < length; i++) {
-            final IdRange range = sequenceNumbers[i];
-
-            // correctly calculate the ranges. See IMAP-292
-            final SelectedMailbox selected = session.getSelected();
-            MessageRange mRange = messageRange(selected, range, !msn);
-            if (mRange != null) {
-                ranges.add(new SearchQuery.NumericRange(mRange.getUidFrom(), 
mRange.getUidTo()));
+        final SelectedMailbox selected = session.getSelected();
+        boolean useUids = !msn;
+    
+        // First of check if we have any messages in the mailbox
+        // if not we don't need to go through all of this
+        if (selected.existsCount() > 0) {
+               for (int i = 0; i < length; i++) {
+                final IdRange range = sequenceNumbers[i];
+                
+                long lowVal = range.getLowVal();
+                long highVal = range.getHighVal();
+                if (useUids) {
+                       // Take care of "*" and "*:*" values by return the last 
message in
+                       // the mailbox. See IMAP-289
+                       if (lowVal == Long.MAX_VALUE && highVal == 
Long.MAX_VALUE) {
+                               ranges.add(new 
SearchQuery.NumericRange(selected.getLastUid()));
+                       } else if (highVal == Long.MAX_VALUE && 
selected.getLastUid() < lowVal) {
+                               // Sequence uid ranges which use 
*:<uid-higher-then-last-uid>
+                               // MUST return at least the highest uid in the 
mailbox
+                               // See IMAP-291
+                        ranges.add(new 
SearchQuery.NumericRange(selected.getLastUid()));
+                       } else {
+                        ranges.add(new SearchQuery.NumericRange(lowVal, 
highVal));
+                       }
+                } else {
+                       // Take care of "*" and "*:*" values by return the last 
message in
+                    // the mailbox. See IMAP-289
+                    if (lowVal == Long.MAX_VALUE && highVal == Long.MAX_VALUE) 
{
+                        highVal = selected.getLastUid();
+                        
+                        ranges.add(new SearchQuery.NumericRange(highVal));     
                   
+                    } else  {
+                                               if (lowVal != Long.MIN_VALUE) {
+                                                       lowVal = 
selected.uid((int) lowVal);
+                                               } else {
+                                                       lowVal = 
selected.getFirstUid();
+                                               }
+                                               
+                                               // The lowVal should never be 
SelectedMailbox.NO_SUCH_MESSAGE but we check for it just to be safe
+                                               if (lowVal != 
SelectedMailbox.NO_SUCH_MESSAGE) {
+                                                       if (highVal != 
Long.MAX_VALUE) {
+                                                               highVal = 
selected.uid((int) highVal);
+                                                               if (highVal == 
SelectedMailbox.NO_SUCH_MESSAGE) {
+                                                                       // we 
requested a message with a MSN higher then
+                                                                       // the 
current msg count. So just use the
+                                                                       // 
highest uid as max
+                                                                       highVal 
= selected.getLastUid();
+                                                               }
+                                                       } else {
+                                                               highVal = 
selected.getLastUid();
+                                                       }
+                                                       ranges.add(new 
SearchQuery.NumericRange(lowVal, highVal));
+                                               } 
+                                       }
+                }
             }
         }
+        
         Criterion crit = SearchQuery.uid(ranges.toArray(new 
SearchQuery.NumericRange[0]));
         return crit;
     }

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=1159594&r1=1159593&r2=1159594&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
 Fri Aug 19 11:25:43 2011
@@ -157,6 +157,7 @@ public class SearchProcessorTest {
         final SearchQuery.NumericRange[] ranges = { new 
SearchQuery.NumericRange(
                 42, 100L) };
         mockery.checking(new Expectations() {{
+               allowing(selectedMailbox).existsCount();will(returnValue(100L));
             oneOf(selectedMailbox).uid(with(equal(1)));will(returnValue(42L));
             allowing(selectedMailbox).getFirstUid(); will(returnValue(1L));
             allowing(selectedMailbox).getLastUid(); will(returnValue(100L));
@@ -173,6 +174,7 @@ public class SearchProcessorTest {
         final SearchQuery.NumericRange[] ranges = { new 
SearchQuery.NumericRange(
                 42, 1729) };
         mockery.checking(new Expectations() {{
+               allowing(selectedMailbox).existsCount();will(returnValue(2L));
             oneOf(selectedMailbox).uid(with(equal(1)));will(returnValue(42L));
             
oneOf(selectedMailbox).uid(with(equal(5)));will(returnValue(1729L));
             allowing(selectedMailbox).getFirstUid(); will(returnValue(1L));
@@ -189,6 +191,7 @@ public class SearchProcessorTest {
         final SearchQuery.NumericRange[] ranges = { new 
SearchQuery.NumericRange(
                 42) };
         mockery.checking(new Expectations() {{
+               allowing(selectedMailbox).existsCount();will(returnValue(1L));
             
exactly(2).of(selectedMailbox).uid(with(equal(1)));will(returnValue(42L));
         }});
         allowUnsolicitedResponses();



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to