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 23:37:28 UTC
svn commit: r632141 - in /james/server/trunk:
imap-api/src/main/java/org/apache/james/api/imap/message/request/
imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/
imap-codec-library/src/test/java/org/apache/james/imaps...
Author: rdonkin
Date: Thu Feb 28 14:37:25 2008
New Revision: 632141
URL: http://svn.apache.org/viewvc?rev=632141&view=rev
Log:
Completed search parsing.
Added:
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserAndParenthesesTest.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserTopLevelAndTest.java
Modified:
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/SearchKey.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/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-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=632141&r1=632140&r2=632141&view=diff
==============================================================================
--- james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/SearchKey.java (original)
+++ james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/request/SearchKey.java Thu Feb 28 14:37:25 2008
@@ -1,6 +1,8 @@
package org.apache.james.api.imap.message.request;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import org.apache.james.api.imap.message.IdRange;
@@ -54,57 +56,59 @@
public static final int TYPE_NOT = 35;
// OR
public static final int TYPE_OR = 36;
+ // AND
+ public static final int TYPE_AND = 36;
private static final SearchKey UNSEEN = new SearchKey(TYPE_UNSEEN,
- null, null, null, 0, null, null, null);
+ null, null, 0, null, null, null);
private static final SearchKey UNFLAGGED = new SearchKey(
- TYPE_UNFLAGGED, null, null, null, 0, null, null, null);
+ TYPE_UNFLAGGED, null, null, 0, null, null, null);
private static final SearchKey UNDRAFT = new SearchKey(TYPE_UNDRAFT,
- null, null, null, 0, null, null, null);
+ null, null, 0, null, null, null);
private static final SearchKey UNDELETED = new SearchKey(
- TYPE_UNDELETED, null, null, null, 0, null, null, null);
+ TYPE_UNDELETED, null, null, 0, null, null, null);
private static final SearchKey UNANSWERED = new SearchKey(
- TYPE_UNANSWERED, null, null, null, 0, null, null, null);
+ TYPE_UNANSWERED, null, null, 0, null, null, null);
private static final SearchKey SEEN = new SearchKey(TYPE_SEEN, null,
- null, null, 0, null, null, null);
+ null, 0, null, null, null);
private static final SearchKey RECENT = new SearchKey(TYPE_RECENT,
- null, null, null, 0, null, null, null);
+ null, null, 0, null, null, null);
private static final SearchKey OLD = new SearchKey(TYPE_OLD, null,
- null, null, 0, null, null, null);
+ null, 0, null, null, null);
private static final SearchKey NEW = new SearchKey(TYPE_NEW, null,
- null, null, 0, null, null, null);
+ null, 0, null, null, null);
private static final SearchKey FLAGGED = new SearchKey(TYPE_FLAGGED,
- null, null, null, 0, null, null, null);
+ null, null, 0, null, null, null);
private static final SearchKey DRAFT = new SearchKey(TYPE_DRAFT, null,
- null, null, 0, null, null, null);
+ null, 0, null, null, null);
private static final SearchKey DELETED = new SearchKey(TYPE_DELETED,
- null, null, null, 0, null, null, null);
+ null,null, 0, null, null, null);
private static final SearchKey ANSWERED = new SearchKey(TYPE_ANSWERED,
- null, null, null, 0, null, null, null);
+ null, null, 0, null, null, null);
private static final SearchKey ALL = new SearchKey(TYPE_ALL, null,
- null, null, 0, null, 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,
+ return new SearchKey(TYPE_SEQUENCE_SET, null, null, 0, null,
null, ids);
}
public static SearchKey buildUidSet(IdRange[] ids) {
- return new SearchKey(TYPE_UID, null, null, null, 0, null, null, ids);
+ return new SearchKey(TYPE_UID, null, null, 0, null, null, ids);
}
// NO PARAMETERS
@@ -166,125 +170,139 @@
// ONE VALUE
public static SearchKey buildBcc(String value) {
- return new SearchKey(TYPE_BCC, null, null, null, 0, null, value,
+ return new SearchKey(TYPE_BCC, null, null, 0, null, value,
null);
}
public static SearchKey buildBody(String value) {
- return new SearchKey(TYPE_BODY, null, null, null, 0, null, value,
+ return new SearchKey(TYPE_BODY, null, null, 0, null, value,
null);
}
public static SearchKey buildCc(String value) {
- return new SearchKey(TYPE_CC, null, null, null, 0, null, value,
+ return new SearchKey(TYPE_CC, null, null, 0, null, value,
null);
}
public static SearchKey buildFrom(String value) {
- return new SearchKey(TYPE_FROM, null, null, null, 0, null, value,
+ return new SearchKey(TYPE_FROM, null, null, 0, null, value,
null);
}
public static SearchKey buildKeyword(String value) {
- return new SearchKey(TYPE_KEYWORD, null, null, null, 0, null,
+ return new SearchKey(TYPE_KEYWORD, null, null, 0, null,
value, null);
}
public static SearchKey buildSubject(String value) {
- return new SearchKey(TYPE_SUBJECT, null, null, null, 0, null,
+ return new SearchKey(TYPE_SUBJECT, null, null, 0, null,
value, null);
}
public static SearchKey buildText(String value) {
- return new SearchKey(TYPE_TEXT, null, null, null, 0, null, value,
+ return new SearchKey(TYPE_TEXT, null, null, 0, null, value,
null);
}
public static SearchKey buildTo(String value) {
- return new SearchKey(TYPE_TO, null, null, null, 0, null, value,
+ return new SearchKey(TYPE_TO, null, null, 0, null, value,
null);
}
public static SearchKey buildUnkeyword(String value) {
- return new SearchKey(TYPE_UNKEYWORD, null, null, null, 0, null,
+ return new SearchKey(TYPE_UNKEYWORD, 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,
+ return new SearchKey(TYPE_BEFORE, date, null, 0, null, null,
null);
}
public static SearchKey buildOn(DayMonthYear date) {
- return new SearchKey(TYPE_ON, date, null, null, 0, null, null, null);
+ return new SearchKey(TYPE_ON, date, null, 0, null, null, null);
}
public static SearchKey buildSentBefore(DayMonthYear date) {
- return new SearchKey(TYPE_SENTBEFORE, date, null, null, 0, null,
+ return new SearchKey(TYPE_SENTBEFORE, date, null, 0, null,
null, null);
}
public static SearchKey buildSentOn(DayMonthYear date) {
- return new SearchKey(TYPE_SENTON, date, null, null, 0, null, null,
+ return new SearchKey(TYPE_SENTON, date, null, 0, null, null,
null);
}
public static SearchKey buildSentSince(DayMonthYear date) {
- return new SearchKey(TYPE_SENTSINCE, date, null, null, 0, null,
+ return new SearchKey(TYPE_SENTSINCE, date, null, 0, null,
null, null);
}
public static SearchKey buildSince(DayMonthYear date) {
- return new SearchKey(TYPE_SINCE, date, null, null, 0, null, null,
+ return new SearchKey(TYPE_SINCE, date, 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,
+ return new SearchKey(TYPE_HEADER, null, null, 0, name, value,
null);
}
// ONE NUMBER
public static SearchKey buildLarger(long size) {
- return new SearchKey(TYPE_LARGER, null, null, null, size, null,
+ return new SearchKey(TYPE_LARGER, null, null, size, null,
null, null);
}
public static SearchKey buildSmaller(long size) {
- return new SearchKey(TYPE_SMALLER, null, null, null, size, null,
+ return new SearchKey(TYPE_SMALLER, 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);
+ final List keys = new ArrayList();
+ keys.add(key);
+ return new SearchKey(TYPE_NOT, null, keys, 0, null, null, null);
}
// OR
public static SearchKey buildOr(SearchKey keyOne, SearchKey keyTwo) {
- return new SearchKey(TYPE_OR, null, keyOne, keyTwo, 0, null, null,
+ final List keys = new ArrayList();
+ keys.add(keyOne);
+ keys.add(keyTwo);
+ return new SearchKey(TYPE_OR, null, keys, 0, null, null,
null);
}
+
+ /**
+ * Componses an <code>AND</code> key from
+ * given keys.
+ * @param keys <code>List</code> of {@link SearchKey}'s
+ * composing this key
+ * @return <code>SearchKey</code>, not null
+ */
+ public static SearchKey buildAnd(final List keys) {
+ return new SearchKey(TYPE_AND, null, keys, 0, null, null, null);
+ }
private final int type;
private final DayMonthYear date;
- private final SearchKey one;
- private final SearchKey two;
+ private final List keys;
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,
+ private SearchKey(final int type, final DayMonthYear date, final List keys,
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.keys = keys;
this.size = number;
this.name = name;
this.value = value;
@@ -327,24 +345,15 @@
public final long getSize() {
return size;
}
-
- /**
- * Gets key one.
- * @return the key to be NOT'd when {@link #TYPE_NOT},
- * the first first to be OR'd when {@link #TYPE_OR},
- * null otherwise
- */
- public final SearchKey getKeyOne() {
- return one;
- }
-
+
/**
* Gets key two.
- * @return the second key to be OR'd when {@link #TYPE_OR},
+ * @return <code>List</code> of <code>SearchKey</code>'s when {@link #TYPE_OR},
+ * {@link #TYPE_AND} or {@link #TYPE_NOT}
* otherwise null
*/
- public final SearchKey getKeyTwo() {
- return two;
+ public final List getKeys() {
+ return keys;
}
/**
@@ -373,10 +382,9 @@
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 + ((keys == null) ? 0 : keys.hashCode());
result = PRIME * result + type;
result = PRIME * result + ((value == null) ? 0 : value.hashCode());
return result;
@@ -403,19 +411,14 @@
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)
+ if (keys == null) {
+ if (other.keys != null)
return false;
- } else if (!two.equals(other.two))
+ } else if (!keys.equals(other.keys))
return false;
if (type != other.type)
return false;
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=632141&r1=632140&r2=632141&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 14:37:25 2008
@@ -18,6 +18,9 @@
****************************************************************/
package org.apache.james.imapserver.codec.decode.imap4rev1;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.james.api.imap.ImapCommand;
import org.apache.james.api.imap.ImapMessage;
import org.apache.james.api.imap.ProtocolException;
@@ -49,6 +52,8 @@
final char next = request.nextChar();
if (next >= '0' && next <= '9' || next == '*') {
return sequenceSet(request);
+ } else if (next == '(') {
+ return paren(request);
} else {
final int cap = consumeAndCap(request);
switch (cap) {
@@ -79,6 +84,24 @@
}
}
+ private SearchKey paren(ImapRequestLineReader request) throws ProtocolException {
+ request.consume();
+ List keys = new ArrayList();
+ addUntilParen(request, keys);
+ return SearchKey.buildAnd(keys);
+ }
+
+ private void addUntilParen(ImapRequestLineReader request, List keys) throws ProtocolException {
+ final char next = request.nextWordChar();
+ if (next == ')') {
+ request.consume();
+ } else {
+ final SearchKey key = searchKey( request );
+ keys.add(key);
+ addUntilParen(request, keys);
+ }
+ }
+
private int consumeAndCap(ImapRequestLineReader request) throws ProtocolException {
final char next = request.consume();
final int cap = next > 'Z' ? next ^ 32 : next;
@@ -696,11 +719,30 @@
}
}
- protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, String tag, boolean useUids) throws ProtocolException {
- // Parse the search term from the request
+ public SearchKey decode(ImapRequestLineReader request) throws ProtocolException {
request.nextWordChar();
- final SearchKey key = searchKey( request );
+ final SearchKey firstKey = searchKey( request );
+ final SearchKey result;
+ if (request.nextChar() == ' ') {
+ List keys = new ArrayList();
+ keys.add(firstKey);
+ while (request.nextChar() == ' ') {
+ request.nextWordChar();
+ final SearchKey key = searchKey( request );
+ keys.add(key);
+ }
+ result = SearchKey.buildAnd(keys);
+ } else {
+ result = firstKey;
+ }
endLine( request );
+ return result;
+ }
+
+ protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, String tag, boolean useUids) throws ProtocolException {
+ // Parse the search term from the request
+ final SearchKey key = decode( request );
+
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/SearchCommandParserAndParenthesesTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserAndParenthesesTest.java?rev=632141&view=auto
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserAndParenthesesTest.java (added)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserAndParenthesesTest.java Thu Feb 28 14:37:25 2008
@@ -0,0 +1,191 @@
+/****************************************************************
+ * 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.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+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.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.imap4rev1.SearchCommandParserTopLevelAndTest.Input;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+public class SearchCommandParserAndParenthesesTest extends MockObjectTestCase {
+
+ Input[] variety = {sequence(), uid(), fromHeader(), since(), stringQuoted(), stringUnquoted(), draft(),
+ mailingListHeader(), on(), unanswered()};
+
+ public static Input and(Input[] parts, boolean parens) {
+ List keys = new ArrayList();
+ StringBuffer buffer = new StringBuffer();
+ if (parens) {
+ buffer.append("(");
+ }
+ for (int i = 0; i < parts.length; i++) {
+ if (i>0) {
+ buffer.append(' ');
+ }
+ buffer.append(parts[i].input);
+ keys.add(parts[i].key);
+ }
+ if (parens) {
+ buffer.append(")");
+ }
+ Input input = new Input(buffer.toString(), SearchKey.buildAnd(keys));
+ return input;
+ }
+
+ public static 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 static 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 static Input fromHeader() {
+ SearchKey key = SearchKey.buildHeader("FROM", "Smith");
+ return new Input("HEADER FROM Smith", key);
+ }
+
+ public static Input to() {
+ SearchKey key = SearchKey.buildTo("JAMES Server Development <se...@james.apache.org>");
+ return new Input("To \"JAMES Server Development <se...@james.apache.org>\"", key);
+ }
+
+ public static Input mailingListHeader() {
+ SearchKey key = SearchKey.buildHeader("Mailing-List", "contact server-dev-help@james.apache.org; run by ezmlm");
+ return new Input("HEADER Mailing-List \"contact server-dev-help@james.apache.org; run by ezmlm\"", key);
+ }
+
+ public static Input since() {
+ SearchKey key = SearchKey.buildSince(new DayMonthYear(11,1, 2001));
+ return new Input("since 11-Jan-2001", key);
+ }
+
+ public static Input on() {
+ SearchKey key = SearchKey.buildOn(new DayMonthYear(1,2, 2001));
+ return new Input("on 1-Feb-2001", key);
+ }
+
+ public static Input stringUnquoted() {
+ SearchKey key = SearchKey.buildFrom("Smith");
+ return new Input("FROM Smith", key);
+ }
+
+ public static Input stringQuoted() {
+ SearchKey key = SearchKey.buildFrom("Smith And Jones");
+ return new Input("FROM \"Smith And Jones\"", key);
+ }
+
+ public static Input draft() {
+ SearchKey key = SearchKey.buildDraft();
+ return new Input("DRAFT", key);
+ }
+
+ public static Input unanswered() {
+ SearchKey key = SearchKey.buildUnanswered();
+ return new Input("unanswered", key);
+ }
+
+ public static final class Input {
+ public String input;
+ public SearchKey key;
+
+ public Input(String input, SearchKey key) {
+ super();
+ this.input = input;
+ this.key = key;
+ }
+ }
+
+ 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 testShouldParseTopLevelParentheses() throws Exception {
+ check(and(variety, true));
+ }
+
+ public void testShouldParseDeepParentheses() throws Exception {
+ Input[] deep = {and(variety, true), and(variety, true), sequence(), and(variety, true), draft(), mailingListHeader()};
+ Input[] mid = {and(deep, true), since(), and(variety, true), unanswered()};
+ Input[] top = {uid(), and(deep, true), and(mid, true), stringQuoted(), and(mid, true)};
+ check(and(top, true));
+ }
+
+ public void testShouldParseParenthesesOnTopLevel() throws Exception {
+ Input[] deep = {and(variety, true), and(variety, true), sequence(), and(variety, true), draft(), mailingListHeader()};
+ Input[] mid = {and(deep, true), since(), and(variety, true), unanswered()};
+ Input[] top = {uid(), and(deep, true), and(mid, true), stringQuoted(), and(mid, true)};
+ check(and(top, false));
+ }
+
+ private void check(Input in) throws UnsupportedEncodingException, ProtocolException {
+ String input = in.input + "\r\n";
+ ImapRequestLineReader reader = new ImapRequestLineReader(
+ new ByteArrayInputStream(input.getBytes("US-ASCII")),
+ new ByteArrayOutputStream());
+
+ final SearchKey result = parser.decode(reader);
+ assertEquals(in.key, result);
+ }
+
+
+}
Modified: 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=632141&r1=632140&r2=632141&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java Thu Feb 28 14:37:25 2008
@@ -34,7 +34,6 @@
import org.jmock.MockObjectTestCase;
public class SearchCommandParserOrTest extends MockObjectTestCase {
-
SearchCommandParser parser;
Mock mockCommandFactory;
Mock mockMessageFactory;
Modified: 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=632141&r1=632140&r2=632141&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java Thu Feb 28 14:37:25 2008
@@ -27,7 +27,6 @@
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;
@@ -35,7 +34,6 @@
public class SearchCommandParserSearchKeySequenceSetTest extends MockObjectTestCase {
- private static final DayMonthYear DATE = new DayMonthYear(1, 1, 2000);
SearchCommandParser parser;
Mock mockCommandFactory;
Mock mockMessageFactory;
Added: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserTopLevelAndTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserTopLevelAndTest.java?rev=632141&view=auto
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserTopLevelAndTest.java (added)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserTopLevelAndTest.java Thu Feb 28 14:37:25 2008
@@ -0,0 +1,193 @@
+/****************************************************************
+ * 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.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+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.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 SearchCommandParserTopLevelAndTest extends MockObjectTestCase {
+
+ Input[] one = {sequence()};
+
+ Input[] base = {sequence(), uid(), fromHeader(), since(), stringQuoted(), stringUnquoted(), draft()};
+
+ Input[] variety = {sequence(), uid(), fromHeader(), since(), stringQuoted(), stringUnquoted(), draft(),
+ mailingListHeader(), on(), unanswered(), };
+
+ public static 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 static 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 static Input fromHeader() {
+ SearchKey key = SearchKey.buildHeader("FROM", "Smith");
+ return new Input("HEADER FROM Smith", key);
+ }
+
+ public static Input to() {
+ SearchKey key = SearchKey.buildTo("JAMES Server Development <se...@james.apache.org>");
+ return new Input("To \"JAMES Server Development <se...@james.apache.org>\"", key);
+ }
+
+ public static Input mailingListHeader() {
+ SearchKey key = SearchKey.buildHeader("Mailing-List", "contact server-dev-help@james.apache.org; run by ezmlm");
+ return new Input("HEADER Mailing-List \"contact server-dev-help@james.apache.org; run by ezmlm\"", key);
+ }
+
+ public static Input since() {
+ SearchKey key = SearchKey.buildSince(new DayMonthYear(11,1, 2001));
+ return new Input("since 11-Jan-2001", key);
+ }
+
+ public static Input on() {
+ SearchKey key = SearchKey.buildOn(new DayMonthYear(1,2, 2001));
+ return new Input("on 1-Feb-2001", key);
+ }
+
+ public static Input stringUnquoted() {
+ SearchKey key = SearchKey.buildFrom("Smith");
+ return new Input("FROM Smith", key);
+ }
+
+ public static Input stringQuoted() {
+ SearchKey key = SearchKey.buildFrom("Smith And Jones");
+ return new Input("FROM \"Smith And Jones\"", key);
+ }
+
+ public static Input draft() {
+ SearchKey key = SearchKey.buildDraft();
+ return new Input("DRAFT", key);
+ }
+
+ public static Input unanswered() {
+ SearchKey key = SearchKey.buildUnanswered();
+ return new Input("unanswered", key);
+ }
+
+ public static final class Input {
+ public String input;
+ public SearchKey key;
+
+ public Input(String input, SearchKey key) {
+ super();
+ this.input = input;
+ this.key = key;
+ }
+ }
+
+ 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 testLargePermutations() throws Exception {
+ permute(16, one);
+ permute(32, one);
+ }
+
+ public void testBasePermutations() throws Exception {
+ permute(2, base);
+ permute(3, base);
+ permute(4, base);
+ permute(5, base);
+ }
+
+ public void testVarietyPermutations() throws Exception {
+ permute(5, variety);
+ }
+
+ private void permute(int mutations, Input[] inputs) throws Exception {
+ permute(mutations, new ArrayList(), new StringBuffer(), inputs);
+ }
+
+ private void permute(int mutations, List keys, StringBuffer buffer, Input[] inputs) throws Exception {
+ if (mutations == 0) {
+ check(keys, buffer);
+ } else {
+ mutations -= 1;
+ for (int i = 0; i < inputs.length; i++) {
+ StringBuffer nextBuffer = new StringBuffer(buffer);
+ if (nextBuffer.length() > 0) {
+ nextBuffer.append(' ');
+ }
+ nextBuffer.append(inputs[i].input);
+ List nextKeys = new ArrayList(keys);
+ nextKeys.add(inputs[i].key);
+ permute(mutations, nextKeys, nextBuffer, inputs);
+ }
+ }
+ }
+
+ private void check(List keys, StringBuffer buffer) throws UnsupportedEncodingException, ProtocolException {
+ buffer.append("\r\n");
+ String input = buffer.toString();
+ SearchKey key = SearchKey.buildAnd(keys);
+ ImapRequestLineReader reader = new ImapRequestLineReader(
+ new ByteArrayInputStream(input.getBytes("US-ASCII")),
+ new ByteArrayOutputStream());
+
+ assertEquals(input, key, parser.decode(reader));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org