You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2008/02/28 21:04:53 UTC

svn commit: r632108 - in /james/server/trunk/imap-codec-library/src: main/java/org/apache/james/imapserver/codec/decode/imap4rev1/ test/java/org/apache/james/imapserver/codec/decode/imap4rev1/

Author: rdonkin
Date: Thu Feb 28 12:04:50 2008
New Revision: 632108

URL: http://svn.apache.org/viewvc?rev=632108&view=rev
Log:
Implemented NOT and OR search keys. Only AND remains.

Added:
    james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java
    james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java
    james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java
Modified:
    james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java
    james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java

Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java?rev=632108&r1=632107&r2=632108&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java Thu Feb 28 12:04:50 2008
@@ -22,6 +22,7 @@
 import org.apache.james.api.imap.ImapMessage;
 import org.apache.james.api.imap.ProtocolException;
 import org.apache.james.api.imap.imap4rev1.Imap4Rev1CommandFactory;
+import org.apache.james.api.imap.message.IdRange;
 import org.apache.james.api.imap.message.request.DayMonthYear;
 import org.apache.james.api.imap.message.request.SearchKey;
 import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
@@ -45,31 +46,36 @@
      * Parses the request argument into a valid search term.
      */
     public SearchKey searchKey( ImapRequestLineReader request ) throws ProtocolException {
-        final int cap = consumeAndCap(request);
-        switch (cap) {
-            case 'A': return a(request);
-            case 'B': return b(request);
-            case 'C': return cc(request);
-            case 'D': return d(request);
-            case 'E': throw new ProtocolException("Unknown search key");
-            case 'F': return f(request);
-            case 'G': throw new ProtocolException("Unknown search key");
-            case 'H': return header(request);
-            case 'I': throw new ProtocolException("Unknown search key");
-            case 'J': throw new ProtocolException("Unknown search key");
-            case 'K': return keyword(request);
-            case 'L': return larger(request);
-            case 'M': throw new ProtocolException("Unknown search key");
-            case 'N': return n(request);
-            case 'O': return o(request);
-            case 'P': throw new ProtocolException("Unknown search key");
-            case 'Q': throw new ProtocolException("Unknown search key");
-            case 'R': return recent(request);
-            case 'S': return s(request);
-            case 'T': return t(request);
-            case 'U': return u(request);
-            default:
-                throw new ProtocolException("Unknown search key");
+        final char next = request.nextChar();
+        if (next >= '0' && next <= '9' || next == '*') {
+            return sequenceSet(request);
+        } else {
+            final int cap = consumeAndCap(request);
+            switch (cap) {
+                case 'A': return a(request);
+                case 'B': return b(request);
+                case 'C': return cc(request);
+                case 'D': return d(request);
+                case 'E': throw new ProtocolException("Unknown search key");
+                case 'F': return f(request);
+                case 'G': throw new ProtocolException("Unknown search key");
+                case 'H': return header(request);
+                case 'I': throw new ProtocolException("Unknown search key");
+                case 'J': throw new ProtocolException("Unknown search key");
+                case 'K': return keyword(request);
+                case 'L': return larger(request);
+                case 'M': throw new ProtocolException("Unknown search key");
+                case 'N': return n(request);
+                case 'O': return o(request);
+                case 'P': throw new ProtocolException("Unknown search key");
+                case 'Q': throw new ProtocolException("Unknown search key");
+                case 'R': return recent(request);
+                case 'S': return s(request);
+                case 'T': return t(request);
+                case 'U': return u(request);
+                default:
+                    throw new ProtocolException("Unknown search key");
+            }
         }
     }
 
@@ -91,6 +97,7 @@
     private SearchKey u(ImapRequestLineReader request) throws ProtocolException {
         final int next = consumeAndCap(request);
         switch (next) {
+            case 'I': return uid(request);
             case 'N': return un(request);
             default:
                 throw new ProtocolException("Unknown search key");
@@ -177,6 +184,7 @@
         switch (next) {
             case 'L': return old(request);
             case 'N': return on(request);
+            case 'R': return or(request);
             default:
                 throw new ProtocolException("Unknown search key");
         }
@@ -186,6 +194,7 @@
         final int next = consumeAndCap(request);
         switch (next) {
             case 'E': return _new(request);
+            case 'O': return not(request);
             default:
                 throw new ProtocolException("Unknown search key");
         }
@@ -363,6 +372,25 @@
         return result;
     }
     
+    private SearchKey or(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsSpace(request);
+        final SearchKey firstKey = searchKey(request);
+        nextIsSpace(request);
+        final SearchKey secondKey = searchKey(request);
+        result = SearchKey.buildOr(firstKey, secondKey);
+        return result;
+    }
+    
+    private SearchKey not(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsT(request);
+        nextIsSpace(request);
+        final SearchKey nextKey = searchKey(request);
+        result = SearchKey.buildNot(nextKey);
+        return result;
+    }
+    
     private SearchKey _new(ImapRequestLineReader request) throws ProtocolException {
         final SearchKey result;
         nextIsW(request);
@@ -510,6 +538,21 @@
         nextIsSpace(request);
         final String value = astring(request);
         result = SearchKey.buildText(value);
+        return result;
+    }
+    
+    private SearchKey uid(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsD(request);
+        nextIsSpace(request);
+        final IdRange[] range = parseIdRange(request);
+        result = SearchKey.buildUidSet(range);
+        return result;
+    }
+    
+    private SearchKey sequenceSet(ImapRequestLineReader request) throws ProtocolException {
+        final IdRange[] range = parseIdRange(request);
+        final SearchKey result = SearchKey.buildSequenceSet(range);
         return result;
     }
     

Added: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java?rev=632108&view=auto
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java (added)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java Thu Feb 28 12:04:50 2008
@@ -0,0 +1,121 @@
+/****************************************************************
+ * 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.imapserver.codec.decode.imap4rev1;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.apache.james.api.imap.ImapCommand;
+import org.apache.james.api.imap.ImapMessage;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1CommandFactory;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.IdRange;
+import org.apache.james.api.imap.message.request.DayMonthYear;
+import org.apache.james.api.imap.message.request.SearchKey;
+import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+public class SearchCommandParserNotTest extends MockObjectTestCase {
+
+    SearchCommandParser parser;
+    Mock mockCommandFactory;
+    Mock mockMessageFactory;
+    Mock mockCommand;
+    Mock mockMessage;
+    ImapCommand command;
+    ImapMessage message;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        parser = new SearchCommandParser();
+        mockCommandFactory = mock(Imap4Rev1CommandFactory.class);
+        mockCommandFactory.expects(once()).method("getSearch");
+        mockMessageFactory = mock(Imap4Rev1MessageFactory.class);
+        mockCommand = mock(ImapCommand.class);
+        command = (ImapCommand) mockCommand.proxy();
+        mockMessage = mock(ImapMessage.class);
+        message = (ImapMessage) mockMessage.proxy();
+        parser.init((Imap4Rev1CommandFactory) mockCommandFactory.proxy());
+        parser.setMessageFactory((Imap4Rev1MessageFactory) mockMessageFactory.proxy());
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testShouldParseNotSequence() throws Exception {
+        IdRange[] range = {new IdRange(Long.MAX_VALUE, 100), new IdRange(110), new IdRange(200, 201),
+                new IdRange(400, Long.MAX_VALUE)};
+        SearchKey notdKey = SearchKey.buildSequenceSet(range);
+        SearchKey key = SearchKey.buildNot(notdKey);
+        checkValid("NOT *:100,110,200:201,400:*\r\n", key);
+    }
+    
+    public void testShouldParseNotUid() throws Exception {
+        IdRange[] range = {new IdRange(Long.MAX_VALUE, 100), new IdRange(110), new IdRange(200, 201),
+                new IdRange(400, Long.MAX_VALUE)};
+        SearchKey notdKey = SearchKey.buildUidSet(range);
+        SearchKey key = SearchKey.buildNot(notdKey);
+        checkValid("NOT UID *:100,110,200:201,400:*\r\n", key);
+    }
+    
+    public void testShouldParseNotHeaderKey() throws Exception {
+        SearchKey notdKey = SearchKey.buildHeader("FROM", "Smith");
+        SearchKey key = SearchKey.buildNot(notdKey);
+        checkValid("NOT HEADER FROM Smith\r\n", key);
+        checkValid("NOT header FROM Smith\r\n", key);
+    }
+    
+    public void testShouldParseNotDateParameterKey() throws Exception {
+        SearchKey notdKey = SearchKey.buildSince(new DayMonthYear(11,1, 2001));
+        SearchKey key = SearchKey.buildNot(notdKey);
+        checkValid("NOT since 11-Jan-2001\r\n", key);
+        checkValid("NOT SINCE 11-Jan-2001\r\n", key);
+    }
+
+    public void testShouldParseNotStringParameterKey() throws Exception {
+        SearchKey notdKey = SearchKey.buildFrom("Smith");
+        SearchKey key = SearchKey.buildNot(notdKey);
+        checkValid("NOT FROM Smith\r\n", key);
+        checkValid("NOT FROM \"Smith\"\r\n", key);
+    }
+    
+    public void testShouldParseNotStringQuotedParameterKey() throws Exception {
+        SearchKey notdKey = SearchKey.buildFrom("Smith And Jones");
+        SearchKey key = SearchKey.buildNot(notdKey);
+        checkValid("NOT FROM \"Smith And Jones\"\r\n", key);
+    }
+    
+    public void testShouldParseNotNoParameterKey() throws Exception {
+        SearchKey notdKey = SearchKey.buildNew();
+        SearchKey key = SearchKey.buildNot(notdKey);
+        checkValid("NOT NEW\r\n", key);
+        checkValid("Not NEW\r\n", key);
+        checkValid("not new\r\n", key);
+    }
+    
+    private void checkValid(String input, final SearchKey key) throws Exception {
+        ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")), 
+                new ByteArrayOutputStream());
+
+        assertEquals(key, parser.searchKey(reader));
+    }
+}

Added: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java?rev=632108&view=auto
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java (added)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java Thu Feb 28 12:04:50 2008
@@ -0,0 +1,192 @@
+/****************************************************************
+ * 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.imapserver.codec.decode.imap4rev1;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.apache.james.api.imap.ImapCommand;
+import org.apache.james.api.imap.ImapMessage;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1CommandFactory;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.IdRange;
+import org.apache.james.api.imap.message.request.DayMonthYear;
+import org.apache.james.api.imap.message.request.SearchKey;
+import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+public class SearchCommandParserOrTest extends MockObjectTestCase {
+    
+    SearchCommandParser parser;
+    Mock mockCommandFactory;
+    Mock mockMessageFactory;
+    Mock mockCommand;
+    Mock mockMessage;
+    ImapCommand command;
+    ImapMessage message;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        parser = new SearchCommandParser();
+        mockCommandFactory = mock(Imap4Rev1CommandFactory.class);
+        mockCommandFactory.expects(once()).method("getSearch");
+        mockMessageFactory = mock(Imap4Rev1MessageFactory.class);
+        mockCommand = mock(ImapCommand.class);
+        command = (ImapCommand) mockCommand.proxy();
+        mockMessage = mock(ImapMessage.class);
+        message = (ImapMessage) mockMessage.proxy();
+        parser.init((Imap4Rev1CommandFactory) mockCommandFactory.proxy());
+        parser.setMessageFactory((Imap4Rev1MessageFactory) mockMessageFactory.proxy());
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+    
+    public Input sequence() {
+        IdRange[] range = {new IdRange(Long.MAX_VALUE, 100), new IdRange(110), new IdRange(200, 201),
+                new IdRange(400, Long.MAX_VALUE)};
+        SearchKey key = SearchKey.buildSequenceSet(range);
+        return new Input("*:100,110,200:201,400:*", key);
+    }
+    
+    public Input uid() {
+        IdRange[] range = {new IdRange(Long.MAX_VALUE, 100), new IdRange(110), new IdRange(200, 201),
+                new IdRange(400, Long.MAX_VALUE)};
+        SearchKey key = SearchKey.buildUidSet(range);
+        return new Input("UID *:100,110,200:201,400:*", key);
+    }
+    
+    public Input header() {
+        SearchKey key = SearchKey.buildHeader("FROM", "Smith");
+        return new Input("HEADER FROM Smith", key);
+    }
+    
+    public Input date() {
+        SearchKey key = SearchKey.buildSince(new DayMonthYear(11,1, 2001));
+        return new Input("since 11-Jan-2001", key);
+    }
+    
+    public Input stringUnquoted() {
+        SearchKey key = SearchKey.buildFrom("Smith");
+        return new Input("FROM Smith", key);
+    }
+    
+    public Input stringQuoted() {
+        SearchKey key = SearchKey.buildFrom("Smith And Jones");
+        return new Input("FROM \"Smith And Jones\"", key);
+    }
+    
+    public Input draft() {
+        SearchKey key = SearchKey.buildDraft();
+        return new Input("DRAFT", key);
+    }
+    
+    public void testDraftPermutations() throws Exception {
+        checkValid(draft(), draft());
+        checkValid(draft(), stringQuoted());
+        checkValid(draft(), stringUnquoted());
+        checkValid(draft(), sequence());
+        checkValid(draft(), header());
+        checkValid(draft(), date());
+        checkValid(draft(), uid());
+    }
+    
+    public void testDatePermutations() throws Exception {
+        checkValid(date(), draft());
+        checkValid(date(), stringQuoted());
+        checkValid(date(), stringUnquoted());
+        checkValid(date(), sequence());
+        checkValid(date(), header());
+        checkValid(date(), date());
+        checkValid(date(), uid());
+    }
+    
+    public void testHeaderPermutations() throws Exception {
+        checkValid(header(), draft());
+        checkValid(header(), stringQuoted());
+        checkValid(header(), stringUnquoted());
+        checkValid(header(), sequence());
+        checkValid(header(), header());
+        checkValid(header(), date());
+        checkValid(header(), uid());
+    }
+    
+    public void testSequencePermutations() throws Exception {
+        checkValid(sequence(), draft());
+        checkValid(sequence(), stringQuoted());
+        checkValid(sequence(), stringUnquoted());
+        checkValid(sequence(), sequence());
+        checkValid(sequence(), header());
+        checkValid(sequence(), date());
+        checkValid(sequence(), uid());
+    }
+    
+    public void testStringQuotedPermutations() throws Exception {
+        checkValid(stringQuoted(), draft());
+        checkValid(stringQuoted(), stringQuoted());
+        checkValid(stringQuoted(), stringUnquoted());
+        checkValid(stringQuoted(), sequence());
+        checkValid(stringQuoted(), header());
+        checkValid(stringQuoted(), date());
+        checkValid(stringQuoted(), uid());
+    }
+    
+    public void testStringUnquotedPermutations() throws Exception {
+        checkValid(stringUnquoted(), draft());
+        checkValid(stringUnquoted(), stringQuoted());
+        checkValid(stringUnquoted(), stringUnquoted());
+        checkValid(stringUnquoted(), sequence());
+        checkValid(stringUnquoted(), header());
+        checkValid(stringUnquoted(), date());
+        checkValid(stringUnquoted(), uid());
+    }
+    
+    public void testUidPermutations() throws Exception {
+        checkValid(uid(), draft());
+        checkValid(uid(), stringQuoted());
+        checkValid(uid(), stringUnquoted());
+        checkValid(uid(), sequence());
+        checkValid(uid(), header());
+        checkValid(uid(), date());
+        checkValid(uid(), uid());
+    }
+    
+    private void checkValid(Input one, Input two) throws Exception {
+        String input = "OR " + one.input + " " + two.input + "\r\n";
+        SearchKey key = SearchKey.buildOr(one.key, two.key);
+        ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")), 
+                new ByteArrayOutputStream());
+
+        assertEquals(key, parser.searchKey(reader));
+    }
+    
+    public class Input {
+        public String input;
+        public SearchKey key;
+        
+        public Input(String input, SearchKey key) {
+            super();
+            this.input = input;
+            this.key = key;
+        }
+    }
+}

Added: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java?rev=632108&view=auto
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java (added)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java Thu Feb 28 12:04:50 2008
@@ -0,0 +1,111 @@
+/****************************************************************
+ * 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.imapserver.codec.decode.imap4rev1;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.apache.james.api.imap.ImapCommand;
+import org.apache.james.api.imap.ImapMessage;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1CommandFactory;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.IdRange;
+import org.apache.james.api.imap.message.request.DayMonthYear;
+import org.apache.james.api.imap.message.request.SearchKey;
+import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+public class SearchCommandParserSearchKeySequenceSetTest extends MockObjectTestCase {
+
+    private static final DayMonthYear DATE = new DayMonthYear(1, 1, 2000);
+    SearchCommandParser parser;
+    Mock mockCommandFactory;
+    Mock mockMessageFactory;
+    Mock mockCommand;
+    Mock mockMessage;
+    ImapCommand command;
+    ImapMessage message;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        parser = new SearchCommandParser();
+        mockCommandFactory = mock(Imap4Rev1CommandFactory.class);
+        mockCommandFactory.expects(once()).method("getSearch");
+        mockMessageFactory = mock(Imap4Rev1MessageFactory.class);
+        mockCommand = mock(ImapCommand.class);
+        command = (ImapCommand) mockCommand.proxy();
+        mockMessage = mock(ImapMessage.class);
+        message = (ImapMessage) mockMessage.proxy();
+        parser.init((Imap4Rev1CommandFactory) mockCommandFactory.proxy());
+        parser.setMessageFactory((Imap4Rev1MessageFactory) mockMessageFactory.proxy());
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+    
+    public void testAllNumbers() throws Exception {
+        
+        IdRange[] range = {new IdRange(2), new IdRange(4), new IdRange(9), 
+                new IdRange(16), new IdRange(25), new IdRange(36), new IdRange(49),
+                new IdRange(64), new IdRange(81), new IdRange(100)};
+        check("2,4,9,16,25,36,49,64,81,100", range);
+    }
+    
+    public void testEndStar() throws Exception {
+        IdRange[] range = {new IdRange(8), new IdRange(9,10), new IdRange(17), 
+                new IdRange(100, Long.MAX_VALUE)};
+        check("8,9:10,17,100:*", range);
+    }
+    
+    public void testStartStar() throws Exception {
+        IdRange[] range = {new IdRange(Long.MAX_VALUE, 9), new IdRange(15), new IdRange(799, 820)};
+        check("*:9,15,799:820", range);
+    }
+
+    private void check(String sequence, IdRange[] range) throws Exception{
+        checkUid(sequence, range);
+        checkSequence(sequence, range);
+    }
+
+    private void checkUid(String sequence, IdRange[] range) throws Exception {
+        SearchKey key = SearchKey.buildUidSet(range);
+        checkValid("UID " + sequence, key);
+        checkValid("uid " + sequence, key);
+        checkValid("Uid " + sequence, key);
+    }
+    
+    private void checkSequence(String sequence, IdRange[] range) throws Exception {
+        SearchKey key = SearchKey.buildSequenceSet(range);
+        checkValid(sequence, key);
+        checkValid(sequence, key);
+        checkValid(sequence, key);
+    }
+    
+    private void checkValid(String input, final SearchKey key) throws Exception {
+        input = input + "\r\n";
+        ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")), 
+                new ByteArrayOutputStream());
+
+        final SearchKey searchKey = parser.searchKey(reader);
+        assertEquals(key, searchKey);
+    }
+}

Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java?rev=632108&r1=632107&r2=632108&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java Thu Feb 28 12:04:50 2008
@@ -27,6 +27,7 @@
 import org.apache.james.api.imap.ProtocolException;
 import org.apache.james.api.imap.imap4rev1.Imap4Rev1CommandFactory;
 import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.IdRange;
 import org.apache.james.api.imap.message.request.DayMonthYear;
 import org.apache.james.api.imap.message.request.SearchKey;
 import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
@@ -622,7 +623,68 @@
         checkInvalid("larger\r\n", key);
         checkInvalid("larger \r\n", key);
         checkInvalid("larger peach\r\n", key);
-     }
+    }
+    
+    public void testShouldParseUid() throws Exception {
+        IdRange[] range = {new IdRange(1)};
+        SearchKey key = SearchKey.buildUidSet(range);
+        checkValid("UID 1\r\n", key);
+        checkValid("Uid 1\r\n", key);
+        checkValid("uid 1\r\n", key);
+        checkInvalid("u\r\n", key);
+        checkInvalid("ui\r\n", key);
+        checkInvalid("uid\r\n", key);
+        checkInvalid("uid \r\n", key);
+    }
+    
+    public void testShouldParseNot() throws Exception {
+        SearchKey notdKey = SearchKey.buildSeen();
+        SearchKey key = SearchKey.buildNot(notdKey);
+        checkValid("NOT SEEN\r\n", key);
+        checkValid("Not seen\r\n", key);
+        checkValid("not Seen\r\n", key);
+        checkInvalid("n\r\n", key);
+        checkInvalid("no\r\n", key);
+        checkInvalid("not\r\n", key);
+        checkInvalid("not \r\n", key);
+    }
+    
+    public void testShouldParseOr() throws Exception {
+        SearchKey oneKey = SearchKey.buildSeen();
+        SearchKey twoKey = SearchKey.buildDraft();
+        SearchKey key = SearchKey.buildOr(oneKey, twoKey);
+        checkValid("OR SEEN DRAFT\r\n", key);
+        checkValid("oR seen draft\r\n", key);
+        checkValid("or Seen drAFT\r\n", key);
+        checkInvalid("o\r\n", key);
+        checkInvalid("or\r\n", key);
+        checkInvalid("or \r\n", key);
+        checkInvalid("or seen\r\n", key);
+        checkInvalid("or seen \r\n", key);
+    }
+    
+    public void testShouldParseSequenceSet() throws Exception {
+        checkSequenceSet(1);
+        checkSequenceSet(2);
+        checkSequenceSet(3);
+        checkSequenceSet(4);
+        checkSequenceSet(5);
+        checkSequenceSet(6);
+        checkSequenceSet(7);
+        checkSequenceSet(8);
+        checkSequenceSet(9);
+        checkSequenceSet(10);
+        checkSequenceSet(121);
+        checkSequenceSet(11354);
+        checkSequenceSet(145644656);
+        checkSequenceSet(1456452213);
+    }
+
+    private void checkSequenceSet(int number) throws Exception {
+        IdRange[] range = {new IdRange(number)};
+        SearchKey key = SearchKey.buildSequenceSet(range);
+        checkValid(number + "\r\n", key);
+    }
     
     private void checkInvalid(String input, final SearchKey key) throws Exception {
         ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")), 



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org