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]