Author: rdonkin
Date: Tue Feb 26 14:32:02 2008
New Revision: 631407

URL: http://svn.apache.org/viewvc?rev=631407&view=rev
Log:
Started work on search decoder

Added:
    
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/DayMonthYear.java
    
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/SearchKey.java
    
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java
Modified:
    
james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/ValidSelected.test
    
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/imap4rev1/Imap4Rev1MessageFactory.java
    
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java
    
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/imap4rev1/SearchRequest.java
    
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/DecoderUtils.java
    
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java
    
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/StoreCommandParserTest.java
    
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java

Modified: 
james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/ValidSelected.test
URL: 
http://svn.apache.org/viewvc/james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/ValidSelected.test?rev=631407&r1=631406&r2=631407&view=diff
==============================================================================
--- 
james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/ValidSelected.test
 (original)
+++ 
james/server/trunk/experimental-seda-imap-function/src/test/resources/org/apache/james/test/functional/imap/scripts/ValidSelected.test
 Tue Feb 26 14:32:02 2008
@@ -25,7 +25,7 @@
 S: a001 NO COPY failed. Command not valid in this state.
 C: a001 EXPUNGE
 S: a001 NO EXPUNGE failed. Command not valid in this state.
-C: a001 SEARCH
+C: a001 SEARCH ALL
 S: a001 NO SEARCH failed. Command not valid in this state.
 C: a001 FETCH 1 ALL
 S: a001 NO FETCH failed. Command not valid in this state.

Modified: 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/imap4rev1/Imap4Rev1MessageFactory.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/imap4rev1/Imap4Rev1MessageFactory.java?rev=631407&r1=631406&r2=631407&view=diff
==============================================================================
--- 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/imap4rev1/Imap4Rev1MessageFactory.java
 (original)
+++ 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/imap4rev1/Imap4Rev1MessageFactory.java
 Tue Feb 26 14:32:02 2008
@@ -22,13 +22,13 @@
 
 import javax.mail.Flags;
 import javax.mail.internet.MimeMessage;
-import javax.mail.search.SearchTerm;
 
 import org.apache.james.api.imap.ImapCommand;
 import org.apache.james.api.imap.ImapMessage;
 import org.apache.james.api.imap.message.FetchData;
 import org.apache.james.api.imap.message.IdRange;
 import org.apache.james.api.imap.message.StatusDataItems;
+import org.apache.james.api.imap.message.request.SearchKey;
 
 /**
  * Creates messages.
@@ -79,7 +79,7 @@
     public ImapMessage createRenameMessage(final ImapCommand command, final 
String existingName, final String newName, 
             final String tag);
     
-    public ImapMessage createSearchImapMessage(final ImapCommand command, 
final SearchTerm searchTerm, final boolean useUids,
+    public ImapMessage createSearchMessage(final ImapCommand command, final 
SearchKey key, final boolean useUids,
             final String tag);
     
     public ImapMessage createSelectMessage(final ImapCommand command, final 
String mailboxName, final String tag);

Added: 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/DayMonthYear.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/DayMonthYear.java?rev=631407&view=auto
==============================================================================
--- 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/DayMonthYear.java
 (added)
+++ 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/DayMonthYear.java
 Tue Feb 26 14:32:02 2008
@@ -0,0 +1,99 @@
+/****************************************************************
+ * 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.api.imap.message.request;
+
+/**
+ * An IMAP <code>date</code> production.
+ */
+public class DayMonthYear {
+
+    private final int day;
+    private final int month;
+    private final int year;
+    
+    public DayMonthYear(final int day, final int month, final int year) {
+        super();
+        this.day = day;
+        this.month = month;
+        this.year = year;
+    }
+    
+    /**
+     * Gets the day component of this date.
+     * @return the day of the month, one based
+     */
+    public final int getDay() {
+        return day;
+    }
+    
+    /**
+     * Gets the month component of this date.
+     * @return the month of the year, one based
+     */
+    public final int getMonth() {
+        return month;
+    }
+    
+    /**
+     * Gets the year component of this date.
+     * @return the year
+     */
+    public final int getYear() {
+        return year;
+    }
+    
+    public String toString() {
+        return day + "-" + month + "-" + year; 
+    }
+
+    /**
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + day;
+        result = PRIME * result + month;
+        result = PRIME * result + year;
+        return result;
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final DayMonthYear other = (DayMonthYear) obj;
+        if (day != other.day)
+            return false;
+        if (month != other.month)
+            return false;
+        if (year != other.year)
+            return false;
+        return true;
+    }
+    
+    
+}

Added: 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/SearchKey.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/SearchKey.java?rev=631407&view=auto
==============================================================================
--- 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/SearchKey.java
 (added)
+++ 
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/SearchKey.java
 Tue Feb 26 14:32:02 2008
@@ -0,0 +1,429 @@
+package org.apache.james.api.imap.message.request;
+
+import java.util.Arrays;
+
+import org.apache.james.api.imap.message.IdRange;
+
+/**
+ * Atom key used by a search.
+ * Build instances by factory methods.
+ */
+public final class SearchKey {
+
+    // NUMBERS
+    public static final int TYPE_SEQUENCE_SET = 1;
+    public static final int TYPE_UID = 2; 
+    // NO PARAMETERS
+    public static final int TYPE_ALL = 3;
+    public static final int TYPE_ANSWERED = 4;
+    public static final int TYPE_DELETED = 5;
+    public static final int TYPE_DRAFT = 6;
+    public static final int TYPE_FLAGGED = 7;
+    public static final int TYPE_NEW = 8;
+    public static final int TYPE_OLD = 9;
+    public static final int TYPE_RECENT = 10;
+    public static final int TYPE_SEEN = 11;
+    public static final int TYPE_UNANSWERED = 12;
+    public static final int TYPE_UNDELETED = 13;
+    public static final int TYPE_UNDRAFT = 14;
+    public static final int TYPE_UNFLAGGED = 15;
+    public static final int TYPE_UNSEEN = 16;
+    // ONE VALUE
+    public static final int TYPE_BCC = 17;
+    public static final int TYPE_BODY = 18;
+    public static final int TYPE_CC = 19;
+    public static final int TYPE_FROM = 20;
+    public static final int TYPE_KEYWORD = 21;
+    public static final int TYPE_SUBJECT = 22;
+    public static final int TYPE_TEXT = 23;
+    public static final int TYPE_TO = 24;
+    public static final int TYPE_UNKEYWORD = 25;
+    // ONE DATE
+    public static final int TYPE_BEFORE = 26;
+    public static final int TYPE_ON = 27;
+    public static final int TYPE_SENTBEFORE = 28;
+    public static final int TYPE_SENTON = 29;
+    public static final int TYPE_SENTSINCE = 30;
+    public static final int TYPE_SINCE = 31;
+    // FIELD VALUE
+    public static final int TYPE_HEADER = 32;
+    // ONE NUMBER
+    public static final int TYPE_LARGER = 33;
+    public static final int TYPE_SMALLER = 34;
+    // NOT
+    public static final int TYPE_NOT = 35;
+    // OR
+    public static final int TYPE_OR = 36;
+    
+    private static final SearchKey UNSEEN = new SearchKey(TYPE_UNSEEN,
+            null, null, null, 0, null, null, null);
+
+    private static final SearchKey UNFLAGGED = new SearchKey(
+            TYPE_UNFLAGGED, null, null, null, 0, null, null, null);
+
+    private static final SearchKey UNDRAFT = new SearchKey(TYPE_UNDRAFT,
+            null, null, null, 0, null, null, null);
+
+    private static final SearchKey UNDELETED = new SearchKey(
+            TYPE_UNDELETED, null, null, null, 0, null, null, null);
+
+    private static final SearchKey UNANSWERED = new SearchKey(
+            TYPE_UNANSWERED, null, null, null, 0, null, null, null);
+
+    private static final SearchKey SEEN = new SearchKey(TYPE_SEEN, null,
+            null, null, 0, null, null, null);
+
+    private static final SearchKey RECENT = new SearchKey(TYPE_RECENT,
+            null, null, null, 0, null, null, null);
+
+    private static final SearchKey OLD = new SearchKey(TYPE_OLD, null,
+            null, null, 0, null, null, null);
+
+    private static final SearchKey NEW = new SearchKey(TYPE_NEW, null,
+            null, null, 0, null, null, null);
+
+    private static final SearchKey FLAGGED = new SearchKey(TYPE_FLAGGED,
+            null, null, null, 0, null, null, null);
+
+    private static final SearchKey DRAFT = new SearchKey(TYPE_DRAFT, null,
+            null, null, 0, null, null, null);
+
+    private static final SearchKey DELETED = new SearchKey(TYPE_DELETED,
+            null, null, null, 0, null, null, null);
+
+    private static final SearchKey ANSWERED = new SearchKey(TYPE_ANSWERED,
+            null, null, null, 0, null, null, null);
+
+    private static final SearchKey ALL = new SearchKey(TYPE_ALL, null,
+            null, null, 0, null, null, null);
+
+    // NUMBERS
+    public static SearchKey buildSequenceSet(IdRange[] ids) {
+        return new SearchKey(TYPE_SEQUENCE_SET, null, null, null, 0, null,
+                null, ids);
+    }
+
+    public static SearchKey buildUidSet(IdRange[] ids) {
+        return new SearchKey(TYPE_UID, null, null, null, 0, null, null, ids);
+    }
+
+    // NO PARAMETERS
+    public static SearchKey buildAll() {
+        return ALL;
+    }
+
+    public static SearchKey buildAnswered() {
+        return ANSWERED;
+    }
+
+    public static SearchKey buildDeleted() {
+        return DELETED;
+    }
+
+    public static SearchKey buildDraft() {
+        return DRAFT;
+    }
+
+    public static SearchKey buildFlagged() {
+        return FLAGGED;
+    }
+
+    public static SearchKey buildNew() {
+        return NEW;
+    }
+
+    public static SearchKey buildOld() {
+        return OLD;
+    }
+
+    public static SearchKey buildRecent() {
+        return RECENT;
+    }
+
+    public static SearchKey buildSeen() {
+        return SEEN;
+    }
+
+    public static SearchKey buildUnanswered() {
+        return UNANSWERED;
+    }
+
+    public static SearchKey buildUndeleted() {
+        return UNDELETED;
+    }
+
+    public static SearchKey buildUndraft() {
+        return UNDRAFT;
+    }
+
+    public static SearchKey buildUnflagged() {
+        return UNFLAGGED;
+    }
+
+    public static SearchKey buildUnseen() {
+        return UNSEEN;
+    }
+
+    // ONE VALUE
+    public static SearchKey buildBcc(String value) {
+        return new SearchKey(TYPE_BCC, null, null, null, 0, null, value,
+                null);
+    }
+
+    public static SearchKey buildBody(String value) {
+        return new SearchKey(TYPE_BODY, null, null, null, 0, null, value,
+                null);
+    }
+
+    public static SearchKey buildCc(String value) {
+        return new SearchKey(TYPE_CC, null, null, null, 0, null, value,
+                null);
+    }
+
+    public static SearchKey buildFrom(String value) {
+        return new SearchKey(TYPE_FROM, null, null, null, 0, null, value,
+                null);
+    }
+
+    public static SearchKey buildLKeyword(String value) {
+        return new SearchKey(TYPE_KEYWORD, null, null, null, 0, null,
+                value, null);
+    }
+
+    public static SearchKey buildSubject(String value) {
+        return new SearchKey(TYPE_SUBJECT, null, null, null, 0, null,
+                value, null);
+    }
+
+    public static SearchKey buildText(String value) {
+        return new SearchKey(TYPE_TEXT, null, null, null, 0, null, value,
+                null);
+    }
+
+    public static SearchKey buildTo(String value) {
+        return new SearchKey(TYPE_TO, null, null, null, 0, null, value,
+                null);
+    }
+
+    public static SearchKey buildUnkeyword(String value) {
+        return new SearchKey(TYPE_UNKEYWORD, null, null, null, 0, null,
+                value, null);
+    }
+
+    // ONE DATE
+    public static SearchKey buildBefore(DayMonthYear date) {
+        return new SearchKey(TYPE_BEFORE, date, null, null, 0, null, null,
+                null);
+    }
+
+    public static SearchKey buildOn(DayMonthYear date) {
+        return new SearchKey(TYPE_ON, date, null, null, 0, null, null, null);
+    }
+
+    public static SearchKey buildSentBefore(DayMonthYear date) {
+        return new SearchKey(TYPE_SENTBEFORE, date, null, null, 0, null,
+                null, null);
+    }
+
+    public static SearchKey buildSentOn(DayMonthYear date) {
+        return new SearchKey(TYPE_SENTON, date, null, null, 0, null, null,
+                null);
+    }
+
+    public static SearchKey buildSentSince(DayMonthYear date) {
+        return new SearchKey(TYPE_SENTSINCE, date, null, null, 0, null,
+                null, null);
+    }
+
+    public static SearchKey buildSince(DayMonthYear date) {
+        return new SearchKey(TYPE_SINCE, date, null, null, 0, null, null,
+                null);
+    }
+
+    // FIELD VALUE
+    public static SearchKey buildHeader(String name, String value) {
+        return new SearchKey(TYPE_HEADER, null, null, null, 0, name, value,
+                null);
+    }
+
+    // ONE NUMBER
+    public static SearchKey buildLarger(long size) {
+        return new SearchKey(TYPE_LARGER, null, null, null, size, null,
+                null, null);
+    }
+
+    public static SearchKey buildSmaller(long size) {
+        return new SearchKey(TYPE_SMALLER, null, null, null, size, null,
+                null, null);
+    }
+
+    // NOT
+    public static SearchKey buildNot(SearchKey key) {
+        return new SearchKey(TYPE_NOT, null, key, null, 0, null, null, null);
+    }
+
+    // OR
+    public static SearchKey buildOr(SearchKey keyOne, SearchKey keyTwo) {
+        return new SearchKey(TYPE_OR, null, keyOne, keyTwo, 0, null, null,
+                null);
+    }
+
+
+    private final int type;
+    private final DayMonthYear date;
+    private final SearchKey one;
+    private final SearchKey two;
+    private final long size;
+    private final String name;
+    private final String value;
+    private IdRange[] sequence;
+
+    private SearchKey(final int type, final DayMonthYear date, final SearchKey 
one, final SearchKey two, 
+            final long number, final String name, final String value, 
IdRange[] sequence) {
+        super();
+        this.type = type;
+        this.date = date;
+        this.one = one;
+        this.two = two;
+        this.size = number;
+        this.name = name;
+        this.value = value;
+        this.sequence = sequence;
+    }
+
+    /**
+     * Gets a date value to be search upon.
+     * @return the date when: [EMAIL PROTECTED] #TYPE_BEFORE}, [EMAIL 
PROTECTED] #TYPE_ON},
+     * [EMAIL PROTECTED] #TYPE_SENTBEFORE}, [EMAIL PROTECTED] #TYPE_SENTON}, 
[EMAIL PROTECTED] #TYPE_SENTSINCE},
+     * [EMAIL PROTECTED] #TYPE_SINCE}; otherwise null
+     */
+    public final DayMonthYear getDate() {
+        return date;
+    }
+
+    /**
+     * Gets sequence numbers.
+     * @return msn when [EMAIL PROTECTED] #TYPE_SEQUENCE_SET}, uids when 
[EMAIL PROTECTED] #TYPE_UID},
+     * null otherwise
+     */
+    public final IdRange[] getSequenceNumbers() {
+        return sequence;
+    }
+
+    /**
+     * Gets the field name.
+     * @return the field name when [EMAIL PROTECTED] #TYPE_HEADER},
+     * null otherwise
+     */
+    public final String getName() {
+        return name;
+    }
+
+    /**
+     * Gets the size searched for.
+     * @return the size when [EMAIL PROTECTED] #TYPE_LARGER} or [EMAIL 
PROTECTED] #TYPE_SMALLER},
+     * otherwise 0
+     */
+    public final long getSize() {
+        return size;
+    }
+
+    /**
+     * Gets key one.
+     * @return the key to be NOT'd when [EMAIL PROTECTED] #TYPE_NOT},
+     * the first first to be OR'd when [EMAIL PROTECTED] #TYPE_OR},
+     * null otherwise
+     */
+    public final SearchKey getKeyOne() {
+        return one;
+    }
+
+    /**
+     * Gets key two.
+     * @return the second key to be OR'd when [EMAIL PROTECTED] #TYPE_OR},
+     * otherwise null
+     */
+    public final SearchKey getKeyTwo() {
+        return two;
+    }
+
+    /**
+     * Gets the type of key.
+     * @return the type
+     */
+    public final int getType() {
+        return type;
+    }
+
+
+    /**
+     * Gets the value to be searched for.
+     * @return the value, 
+     * or null when this type is not associated with a value.
+     */
+    public final String getValue() {
+        return value;
+    }
+
+    /**
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + ((date == null) ? 0 : date.hashCode());
+        result = PRIME * result + ((name == null) ? 0 : name.hashCode());
+        result = PRIME * result + ((one == null) ? 0 : one.hashCode());
+        result = PRIME * result + Arrays.hashCode(sequence);
+        result = PRIME * result + (int) (size ^ (size >>> 32));
+        result = PRIME * result + ((two == null) ? 0 : two.hashCode());
+        result = PRIME * result + type;
+        result = PRIME * result + ((value == null) ? 0 : value.hashCode());
+        return result;
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final SearchKey other = (SearchKey) obj;
+        if (date == null) {
+            if (other.date != null)
+                return false;
+        } else if (!date.equals(other.date))
+            return false;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        if (one == null) {
+            if (other.one != null)
+                return false;
+        } else if (!one.equals(other.one))
+            return false;
+        if (!Arrays.equals(sequence, other.sequence))
+            return false;
+        if (size != other.size)
+            return false;
+        if (two == null) {
+            if (other.two != null)
+                return false;
+        } else if (!two.equals(other.two))
+            return false;
+        if (type != other.type)
+            return false;
+        if (value == null) {
+            if (other.value != null)
+                return false;
+        } else if (!value.equals(other.value))
+            return false;
+        return true;
+    }     
+}
\ No newline at end of file

Modified: 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java?rev=631407&r1=631406&r2=631407&view=diff
==============================================================================
--- 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java
 (original)
+++ 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java
 Tue Feb 26 14:32:02 2008
@@ -22,7 +22,6 @@
 
 import javax.mail.Flags;
 import javax.mail.internet.MimeMessage;
-import javax.mail.search.SearchTerm;
 
 import org.apache.james.api.imap.ImapCommand;
 import org.apache.james.api.imap.ImapMessage;
@@ -30,6 +29,7 @@
 import org.apache.james.api.imap.message.FetchData;
 import org.apache.james.api.imap.message.IdRange;
 import org.apache.james.api.imap.message.StatusDataItems;
+import org.apache.james.api.imap.message.request.SearchKey;
 import org.apache.james.imap.message.request.imap4rev1.AppendRequest;
 import org.apache.james.imap.message.request.imap4rev1.AuthenticateRequest;
 import org.apache.james.imap.message.request.imap4rev1.CapabilityRequest;
@@ -130,8 +130,8 @@
         return new RenameRequest(command, existingName, newName, tag);
     }
 
-    public ImapMessage createSearchImapMessage(ImapCommand command, SearchTerm 
searchTerm, boolean useUids, String tag) {
-        return new SearchRequest(command, searchTerm, useUids, tag);
+    public ImapMessage createSearchMessage(ImapCommand command, SearchKey key, 
boolean useUids, String tag) {
+        return new SearchRequest(command, key, useUids, tag);
     }
 
     public ImapMessage createSelectMessage(ImapCommand command, String 
mailboxName, String tag) {

Modified: 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/imap4rev1/SearchRequest.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/imap4rev1/SearchRequest.java?rev=631407&r1=631406&r2=631407&view=diff
==============================================================================
--- 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/imap4rev1/SearchRequest.java
 (original)
+++ 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/imap4rev1/SearchRequest.java
 Tue Feb 26 14:32:02 2008
@@ -18,25 +18,26 @@
  ****************************************************************/
 package org.apache.james.imap.message.request.imap4rev1;
 
-import javax.mail.search.SearchTerm;
 
 import org.apache.james.api.imap.ImapCommand;
+import org.apache.james.api.imap.message.request.SearchKey;
 import org.apache.james.imap.message.request.base.AbstractImapRequest;
 
 public class SearchRequest extends AbstractImapRequest {
-    private final SearchTerm searchTerm;
+
+    private final SearchKey searchKey;
 
     private final boolean useUids;
 
     public SearchRequest(final ImapCommand command,
-            final SearchTerm searchTerm, final boolean useUids, final String 
tag) {
+            final SearchKey SearchKey, final boolean useUids, final String 
tag) {
         super(tag, command);
-        this.searchTerm = searchTerm;
+        this.searchKey = SearchKey;
         this.useUids = useUids;
     }
 
-    public final SearchTerm getSearchTerm() {
-        return searchTerm;
+    public final SearchKey getSearchKey() {
+        return searchKey;
     }
 
     public final boolean isUseUids() {

Modified: 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/DecoderUtils.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/DecoderUtils.java?rev=631407&r1=631406&r2=631407&view=diff
==============================================================================
--- 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/DecoderUtils.java
 (original)
+++ 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/DecoderUtils.java
 Tue Feb 26 14:32:02 2008
@@ -77,7 +77,7 @@
             }
         }
     }
-
+    
     /**
      * Decodes the given string as a standard IMAP date-time.
      * @param dateString standard IMAP date-time
@@ -397,7 +397,7 @@
     }
 
 
-    private static int decodeFixedDay(final char dayHigh, final char dayLow) 
throws ProtocolException {
+    public static int decodeFixedDay(final char dayHigh, final char dayLow) 
throws ProtocolException {
         int result = decodeDigit(dayLow);
         if (dayHigh == '1') {
             result += 10;

Modified: 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java?rev=631407&r1=631406&r2=631407&view=diff
==============================================================================
--- 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java
 (original)
+++ 
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java
 Tue Feb 26 14:32:02 2008
@@ -31,6 +31,7 @@
 import org.apache.james.api.imap.ProtocolException;
 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.imapserver.codec.decode.DecoderUtils;
 import org.apache.james.imapserver.codec.decode.ImapCommandParser;
 import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
@@ -185,8 +186,41 @@
     }
 
     /**
+     * Reads one <code>date</code> argument from the request.
+     * @param request <code>ImapRequestLineReader</code>, not null
+     * @return <code>DayMonthYear</code>, not null
+     * @throws ProtocolException
+     */
+    public DayMonthYear date(ImapRequestLineReader request) throws 
ProtocolException {
+        
+        final char dayHigh = request.consume();
+        final char dayLow = request.consume();
+        final int day = DecoderUtils.decodeFixedDay(dayHigh, dayLow);
+        
+        nextIsDash(request);
+        final char monthFirstChar = request.consume();
+        final char monthSecondChar = request.consume();
+        final char monthThirdChar = request.consume();
+        final int month = DecoderUtils.decodeMonth(monthFirstChar, 
monthSecondChar, monthThirdChar) + 1;
+        nextIsDash(request);
+        final char milleniumChar = request.consume();
+        final char centuryChar = request.consume();
+        final char decadeChar = request.consume();
+        final char yearChar = request.consume();
+        final int year = DecoderUtils.decodeYear(milleniumChar, centuryChar, 
decadeChar, yearChar);
+        final DayMonthYear result = new DayMonthYear(day, month, year);
+        return result;
+    }
+
+    private void nextIsDash(ImapRequestLineReader request) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != '-') {
+            throw new ProtocolException("Expected dash but was " + next);
+        }
+    }
+    
+    /**
      * Reads a "date-time" argument from the request.
-     * TODO handle timezones properly
      */
     public Date dateTime( ImapRequestLineReader request ) throws 
ProtocolException
     {

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=631407&r1=631406&r2=631407&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
 Tue Feb 26 14:32:02 2008
@@ -18,13 +18,12 @@
  ****************************************************************/
 package org.apache.james.imapserver.codec.decode.imap4rev1;
 
-import javax.mail.Message;
-import javax.mail.search.SearchTerm;
-
 import org.apache.james.api.imap.ImapCommand;
 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.request.DayMonthYear;
+import org.apache.james.api.imap.message.request.SearchKey;
 import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
 import org.apache.james.imapserver.codec.decode.InitialisableCommandFactory;
 
@@ -44,37 +43,151 @@
     
     /**
      * Parses the request argument into a valid search term.
-     * Not yet implemented - all searches will return everything for now.
-     * TODO implement search
      */
-    public SearchTerm searchTerm( ImapRequestLineReader request )
-            throws ProtocolException
-    {
-        // Dummy implementation
-        // Consume to the end of the line.
-        char next = request.nextChar();
-        while ( next != '\n' ) {
-            request.consume();
-            next = request.nextChar();
-        }
-
-        // Return a search term that matches everything.
-        return new SearchTerm()
-        {
-            private static final long serialVersionUID = 5290284637903768771L;
-
-            public boolean match( Message message )
-            {
-                return true;
-            }
-        };
+    public SearchKey searchKey( ImapRequestLineReader request ) throws 
ProtocolException {
+        final SearchKey result;
+        final char next = request.nextWordChar();
+        request.consume();
+        switch (next) {
+            case 'a':
+            case 'A':
+                result = a(request);
+                break;
+            case 'b':
+            case 'B':
+                result = b(request);
+                break;
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+        return result;
+    }
+
+    private SearchKey b(ImapRequestLineReader request) throws 
ProtocolException {
+        final SearchKey result;
+        final char next = request.consume();
+        switch (next) {
+            case 'c':
+            case 'C':
+                result = bcc(request);
+                break;
+            case 'E':
+            case 'e':
+                nextIsF(request);
+                nextIsO(request);
+                nextIsR(request);
+                nextIsE(request);
+                final DayMonthYear value = date(request);
+                result = SearchKey.buildBefore(value);
+                break;
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+
+        return result;
+    }
+
+    private SearchKey bcc(ImapRequestLineReader request) throws 
ProtocolException {
+        final SearchKey result;
+        nextIsC(request);
+        final String value = astring(request);
+        result = SearchKey.buildBcc(value);
+        return result;
+    }
+
+    private SearchKey a(ImapRequestLineReader request) throws 
ProtocolException {
+        final SearchKey result;
+        final char next = request.consume();
+        switch (next) {
+            case 'l':
+            case 'L':
+                nextIsL(request);
+                result = SearchKey.buildAll();
+                break;
+            case 'n':
+            case 'N':
+                nextIsS(request);
+                nextIsW(request);
+                nextIsE(request);
+                nextIsR(request);
+                nextIsE(request);
+                nextIsD(request);
+                result = SearchKey.buildAnswered();
+                break;
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+        return result;
+    }
+    
+    private void nextIsO( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'O' && next != 'o') {
+            throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private void nextIsF( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'F' && next != 'f') {
+            throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private void nextIsC( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'C' && next != 'c') {
+            throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private void nextIsD( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'D' && next != 'd') {
+            throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private void nextIsR( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'R' && next != 'r') {
+            throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private void nextIsE( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'E' && next != 'e') {
+            throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private void nextIsW( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'W' && next != 'w') {
+            throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private void nextIsS( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'S' && next != 's') {
+            throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private void nextIsL( ImapRequestLineReader request ) throws 
ProtocolException {
+        final char next = request.consume();
+        if (next != 'L' && next != 'l') {
+            throw new ProtocolException("Unknown search key");
+        }
     }
 
     protected ImapMessage decode(ImapCommand command, ImapRequestLineReader 
request, String tag, boolean useUids) throws ProtocolException {
         // Parse the search term from the request
-        final SearchTerm searchTerm = searchTerm( request );
+        final SearchKey key = searchKey( request );
         endLine( request );
-        final ImapMessage result = 
getMessageFactory().createSearchImapMessage(command, searchTerm, useUids, tag);
+        final ImapMessage result = 
getMessageFactory().createSearchMessage(command, key, useUids, tag);
         return result;
     }
 

Added: 
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=631407&view=auto
==============================================================================
--- 
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java
 (added)
+++ 
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java
 Tue Feb 26 14:32:02 2008
@@ -0,0 +1,147 @@
+/****************************************************************
+ * 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 java.util.Date;
+
+import javax.mail.Flags;
+
+import org.apache.james.api.imap.ImapCommand;
+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.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.IdRange;
+import org.apache.james.api.imap.message.request.SearchKey;
+import org.apache.james.api.imap.message.request.DayMonthYear;
+import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+import org.jmock.core.Constraint;
+
+public class SearchCommandParserSearchKeyTest 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 testShouldParseAll() throws Exception {
+        SearchKey key = SearchKey.buildAll();
+        checkValid("ALL\r\n", key);
+        checkValid("all\r\n", key);
+        checkValid("alL\r\n", key);
+        checkInvalid("al\r\n", key);
+        checkInvalid("alm\r\n", key);
+        checkInvalid("alm\r\n", key);
+    }
+    
+    public void testShouldParseAnswered() throws Exception {
+        SearchKey key = SearchKey.buildAnswered();
+        checkValid("ANSWERED\r\n", key);
+        checkValid("answered\r\n", key);
+        checkValid("aNSWEred\r\n", key);
+        checkInvalid("a\r\n", key);
+        checkInvalid("an\r\n", key);
+        checkInvalid("ans\r\n", key);
+        checkInvalid("answ\r\n", key);
+        checkInvalid("answe\r\n", key);
+        checkInvalid("answer\r\n", key);
+        checkInvalid("answere\r\n", key);
+    }
+    
+    public void testShouldParseBcc() throws Exception {
+        SearchKey key = SearchKey.buildBcc("Somebody");
+        checkValid("BCC Somebody\r\n", key);
+        checkValid("BCC \"Somebody\"\r\n", key);
+        checkValid("bcc Somebody\r\n", key);
+        checkValid("bcc \"Somebody\"\r\n", key);
+        checkValid("Bcc Somebody\r\n", key);
+        checkValid("Bcc \"Somebody\"\r\n", key);
+        checkInvalid("b\r\n", key);
+        checkInvalid("bc\r\n", key);
+        checkInvalid("bg\r\n", key);
+    }
+    
+    public void testShouldParseBefore() throws Exception {
+        SearchKey key = SearchKey.buildBefore(DATE);
+        checkValid("BEFORE 1-Jan-2000\r\n", key);
+        checkValid("before 1-Jan-2000\r\n", key);
+        checkValid("BEforE 1-Jan-2000\r\n", key);
+        checkInvalid("b\r\n", key);
+        checkInvalid("B\r\n", key);
+        checkInvalid("BE\r\n", key);
+        checkInvalid("BEf\r\n", key);
+        checkInvalid("BEfo\r\n", key);
+        checkInvalid("BEfor\r\n", key);
+        checkInvalid("BEforE\r\n", key);
+        checkInvalid("BEforE \r\n", key);
+        checkInvalid("BEforE 1\r\n", key);
+        checkInvalid("BEforE 1-\r\n", key);
+        checkInvalid("BEforE 1-J\r\n", key);
+        checkInvalid("BEforE 1-Ja\r\n", key);
+        checkInvalid("BEforE 1-Jan\r\n", key);
+        checkInvalid("BEforE 1-Jan-\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));
+    }
+
+
+    private void checkInvalid(String input, final SearchKey key) throws 
Exception {
+        ImapRequestLineReader reader = new ImapRequestLineReader(new 
ByteArrayInputStream(input.getBytes("US-ASCII")), 
+                new ByteArrayOutputStream());
+
+        try {
+            parser.searchKey(reader);
+            fail("Expected protocol exception to be throw since input is 
invalid");
+        } catch (ProtocolException e) {
+            //expected
+        }
+    }
+}

Modified: 
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/StoreCommandParserTest.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/StoreCommandParserTest.java?rev=631407&r1=631406&r2=631407&view=diff
==============================================================================
--- 
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/StoreCommandParserTest.java
 (original)
+++ 
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/StoreCommandParserTest.java
 Tue Feb 26 14:32:02 2008
@@ -21,7 +21,6 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
 
 import javax.mail.Flags;
 

Modified: 
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java?rev=631407&r1=631406&r2=631407&view=diff
==============================================================================
--- 
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java
 (original)
+++ 
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java
 Tue Feb 26 14:32:02 2008
@@ -29,6 +29,7 @@
 import org.apache.james.api.imap.ImapMessage;
 import org.apache.james.api.imap.ProtocolException;
 import org.apache.james.api.imap.message.request.ImapRequest;
+import org.apache.james.api.imap.message.request.SearchKey;
 import 
org.apache.james.api.imap.message.response.imap4rev1.StatusResponseFactory;
 import org.apache.james.api.imap.process.ImapProcessor;
 import org.apache.james.api.imap.process.ImapSession;
@@ -60,12 +61,12 @@
             ImapSession session, String tag, ImapCommand command, Responder 
responder)
             throws MailboxException, AuthorizationException, ProtocolException 
{
         final SearchRequest request = (SearchRequest) message;
-        final SearchTerm searchTerm = request.getSearchTerm();
+        final SearchKey searchKey = request.getSearchKey();
         final boolean useUids = request.isUseUids();
-        doProcess(searchTerm, useUids, session, tag, command, responder);
+        doProcess(searchKey, useUids, session, tag, command, responder);
     }
 
-    private void doProcess(final SearchTerm searchTerm,
+    private void doProcess(final SearchKey searchKey,
             final boolean useUids, final ImapSession session, final String tag,
             final ImapCommand command, final Responder responder) throws 
MailboxException,
             AuthorizationException, ProtocolException {



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to