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/03/02 21:21:28 UTC
svn commit: r632829 - in /james/server/trunk:
core-library/src/main/java/org/apache/james/mailboxmanager/
core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/
imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/proc...
Author: rdonkin
Date: Sun Mar 2 12:21:26 2008
New Revision: 632829
URL: http://svn.apache.org/viewvc?rev=632829&view=rev
Log:
Redesigned search query to reduce work for backend implementors and to increase protocol independence.
Added:
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java
- copied, changed from r632730, james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java
Removed:
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java
Modified:
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/ImapMailbox.java
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java
james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java
Copied: james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java (from r632730, james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java)
URL: http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java?p2=james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java&p1=james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java&r1=632730&r2=632829&rev=632829&view=diff
==============================================================================
--- james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchParameters.java (original)
+++ james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java Sun Mar 2 12:21:26 2008
@@ -20,74 +20,298 @@
package org.apache.james.mailboxmanager;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
-public class SearchParameters {
+import javax.mail.Flags.Flag;
- public static final String HEADER = "HEADER";
- public static final String UID = "UID";
- public static final String NOT = "NOT";
- public static final String OR = "OR";
- public static final String SMALLER = "SMALLER";
- public static final String LARGER = "LARGER";
- public static final String SINCE = "SINCE";
- public static final String SENTSINCE = "SENTSINCE";
- public static final String SENTON = "SENTON";
- public static final String SENTBEFORE = "SENTBEFORE";
- public static final String ON = "ON";
- public static final String BEFORE = "BEFORE";
- public static final String UNKEYWORD = "UNKEYWORD";
- public static final String TO = "TO";
- public static final String TEXT = "TEXT";
- public static final String SUBJECT = "SUBJECT";
- public static final String KEYWORD = "KEYWORD";
- public static final String FROM = "FROM";
- public static final String CC = "CC";
- public static final String BODY = "BODY";
- public static final String BCC = "BCC";
- public static final String UNSEEN = "UNSEEN";
- public static final String UNFLAGGED = "UNFLAGGED";
- public static final String UNDRAFT = "UNDRAFT";
- public static final String UNDELETED = "UNDELETED";
- public static final String UNANSWERED = "UNANSWERED";
- public static final String SEEN = "SEEN";
- public static final String RECENT = "RECENT";
- public static final String OLD = "OLD";
- public static final String NEW = "NEW";
- public static final String FLAGGED = "FLAGGED";
- public static final String DRAFT = "DRAFT";
- public static final String DELETED = "DELETED";
- public static final String ANSWERED = "ANSWERED";
- public static final String ALL = "ALL";
-
- public final static Set BASE_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
- ALL, ANSWERED, DELETED, DRAFT, FLAGGED, NEW, OLD, RECENT, SEEN,
- UNANSWERED, UNDELETED, UNDRAFT, UNFLAGGED, UNSEEN
- })));
-
- public final static Set STRING_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
- BCC, BODY, CC, FROM, KEYWORD, SUBJECT, TEXT, TO, UNKEYWORD
- })));
- public final static Set DATE_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
- BEFORE, ON, SENTBEFORE, SENTON, SENTSINCE , SINCE
- })));
- public final static Set NUMBER_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
- LARGER, SMALLER
- })));
-
- public final static Set SPECIAL_SEARCH_TERMS = new HashSet(Arrays.asList(new String[] {
- OR, NOT,UID, HEADER
- }));
+/**
+ * <p>Models a query used to search for messages.
+ * A query is the logical <code>AND</code> of the contained criteria.
+ * </p><p>
+ * Each <code>Criterion</code> is composed of an <code>Operator</code>
+ * (combining value and operation) together with field
+ * information (optional since the criteria type may imply a particular
+ * field).
+ * Factory methods are provided for criteria.
+ * </p>
+ */
+public class SearchQuery {
+
+ /**
+ * Creates a filter for message size less than the given value
+ * @param value messages with size less than this value will be selected
+ * by the returned criterion
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion sizeLessThan(long value) {
+ return new SizeCriterion(new NumericOperator(value, NumericOperator.LESS_THAN));
+ }
+
+ /**
+ * Creates a filter for message size greater than the given value
+ * @param value messages with size greater than this value will be selected
+ * by the returned criterion
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion sizeGreaterThan(long value) {
+ return new SizeCriterion(new NumericOperator(value, NumericOperator.GREATER_THAN));
+ }
+
+ /**
+ * Creates a filter matching messages with internal date after the given date.
+ * @param day one based day of the month
+ * @param month one based month of the year
+ * @param year year
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion internalDateAfter(int day, int month, int year) {
+ return new InternalDateCriterion(new DateOperator(DateOperator.AFTER, day, month, year));
+ }
+
+ /**
+ * Creates a filter matching messages with internal date on the given date.
+ * @param day one based day of the month
+ * @param month one based month of the year
+ * @param year year
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion internalDateOn(int day, int month, int year) {
+ return new InternalDateCriterion(new DateOperator(DateOperator.ON, day, month, year));
+ }
+
+
+ /**
+ * Creates a filter matching messages with internal date before the given date.
+ * @param day one based day of the month
+ * @param month one based month of the year
+ * @param year year
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion internalDateBefore(int day, int month, int year) {
+ return new InternalDateCriterion(new DateOperator(DateOperator.BEFORE, day, month, year));
+ }
+
-
- List criterias = new ArrayList();
+ /**
+ * Creates a filter matching messages with the date of the given header
+ * after the given date. If the header's value is not a date then it will
+ * not be included.
+ * @param headerName name of the header whose value will be compared, not null
+ * @param day one based day of the month
+ * @param month one based month of the year
+ * @param year year
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion headerDateAfter(String headerName, int day, int month, int year) {
+ return new HeaderCriterion(headerName, new DateOperator(DateOperator.AFTER, day, month, year));
+ }
+
+ /**
+ * Creates a filter matching messages with the date of the given header
+ * on the given date. If the header's value is not a date then it will
+ * not be included.
+ * @param headerName name of the header whose value will be compared, not null
+ * @param day one based day of the month
+ * @param month one based month of the year
+ * @param year year
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion headerDateOn(String headerName, int day, int month, int year) {
+ return new HeaderCriterion(headerName, new DateOperator(DateOperator.ON, day, month, year));
+ }
+
+ /**
+ * Creates a filter matching messages with the date of the given header
+ * before the given date. If the header's value is not a date then it will
+ * not be included.
+ * @param headerName name of the header whose value will be compared, not null
+ * @param day one based day of the month
+ * @param month one based month of the year
+ * @param year year
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion headerDateBefore(String headerName, int day, int month, int year) {
+ return new HeaderCriterion(headerName, new DateOperator(DateOperator.BEFORE, day, month, year));
+ }
+
+ /**
+ * Creates a filter matching messages whose header value contains the given value.
+ * @param headerName name of the header whose value will be compared, not null
+ * @param value when null or empty the existance of the header will be checked,
+ * otherwise contained value
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion headerContains(String headerName, String value) {
+ if (value == null || value.length() == 0) {
+ return headerExists(headerName);
+ } else {
+ return new HeaderCriterion(headerName, new ContainsOperator(value));
+ }
+ }
+
+ /**
+ * Creates a filter matching messages with a header matching the given name.
+ * @param headerName name of the header whose value will be compared, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion headerExists(String headerName) {
+ return new HeaderCriterion(headerName, ExistsOperator.exists());
+ }
+
+ /**
+ * Creates a filter matching messages which contains the given text
+ * either within the body or in the headers. Implementations may choose
+ * to ignore mime parts which cannot be decoded to text.
+ * @param value search value
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion mailContains(String value) {
+ return new TextCriterion(value, TextCriterion.FULL_MESSAGE);
+ }
+
+ /**
+ * Creates a filter matching messages which contains the given text
+ * within the body. Implementations may choose
+ * to ignore mime parts which cannot be decoded to text.
+ * @param value search value
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion bodyContains(String value) {
+ return new TextCriterion(value, TextCriterion.BODY);
+ }
+
+ /**
+ * Creates a filter matching messages within any of the given ranges.
+ * @param range <code>NumericRange</code>'s, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion uid(NumericRange[] range) {
+ return new UidCriterion(range);
+ }
+
+ /**
+ * Creates a filter composing the two different criteria.
+ * @param one <code>Criterion</code>, not null
+ * @param two <code>Criterion</code>, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion or(Criterion one, Criterion two) {
+ final List criteria = new ArrayList();
+ criteria.add(one);
+ criteria.add(two);
+ return new ConjunctionCriterion(ConjunctionCriterion.OR, criteria);
+ }
+
+ /**
+ * Creates a filter composing the two different criteria.
+ * @param one <code>Criterion</code>, not null
+ * @param two <code>Criterion</code>, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion and(Criterion one, Criterion two) {
+ final List criteria = new ArrayList();
+ criteria.add(one);
+ criteria.add(two);
+ return new ConjunctionCriterion(ConjunctionCriterion.AND, criteria);
+ }
+
+ /**
+ * Creates a filter inverting the given criteria.
+ * @param criterion <code>Criterion</code>, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion not(Criterion criterion) {
+ final List criteria = new ArrayList();
+ criteria.add(criterion);
+ return new ConjunctionCriterion(ConjunctionCriterion.NOR, criteria);
+ }
+
+ /**
+ * Creates a filter on the given flag.
+ * @param flag <code>Flag</code>, not null
+ * @param isSet true if the messages with the flag set should be matched,
+ * false otherwise
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion flagSet(final Flag flag, final boolean isSet) {
+ final Criterion result;
+ if (isSet) {
+ result = flagIsSet(flag);
+ } else {
+ result = flagIsUnSet(flag);
+ }
+ return result;
+ }
+
+ /**
+ * Creates a filter on the given flag selecting messages where the given
+ * flag is selected.
+ * @param flag <code>Flag</code>, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion flagIsSet(final Flag flag) {
+ return new FlagCriterion(flag, BooleanOperator.set());
+ }
+
+ /**
+ * Creates a filter on the given flag selecting messages where the given
+ * flag is not selected.
+ * @param flag <code>Flag</code>, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion flagIsUnSet(final Flag flag) {
+ return new FlagCriterion(flag, BooleanOperator.unset());
+ }
+
+ /**
+ * Creates a filter on the given flag.
+ * @param flag <code>Flag</code>, not null
+ * @param isSet true if the messages with the flag set should be matched,
+ * false otherwise
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion flagSet(final String flag, final boolean isSet) {
+ final Criterion result;
+ if (isSet) {
+ result = flagIsSet(flag);
+ } else {
+ result = flagIsUnSet(flag);
+ }
+ return result;
+ }
+
+ /**
+ * Creates a filter on the given flag selecting messages where the given
+ * flag is selected.
+ * @param flag <code>Flag</code>, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion flagIsSet(final String flag) {
+ return new CustomFlagCriterion(flag, BooleanOperator.set());
+ }
+
+ /**
+ * Creates a filter on the given flag selecting messages where the given
+ * flag is not selected.
+ * @param flag <code>Flag</code>, not null
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion flagIsUnSet(final String flag) {
+ return new CustomFlagCriterion(flag, BooleanOperator.unset());
+ }
+
+ /**
+ * Creates a filter matching all messages.
+ * @return <code>Criterion</code>, not null
+ */
+ public static final Criterion all() {
+ return AllCriterion.all();
+ }
+
+
+ List criterias = new ArrayList();
- public void addCriteria(SearchCriteria crit) {
+ public void andCriteria(Criterion crit) {
criterias.add(crit);
}
@@ -99,191 +323,13 @@
public String toString() {
return "Search:"+criterias.toString();
}
-
- public static class SearchCriteria {
-
-
- public String getName() {
- return "search-criteria";
- }
-
- // @Override
- public String toString() {
- return "['"+getName()+"']";
- }
- }
-
- public static class NamedSearchCriteria extends SearchCriteria {
- String name;
-
- public NamedSearchCriteria(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- // @Override
- public String toString() {
- return "['"+name+"']";
- }
- }
-
- public static class StringSearchCriteria extends NamedSearchCriteria {
- String value;
-
- public StringSearchCriteria(String name, String value) {
- super(name);
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
- public String toString() {
- return "['"+name+"':'"+value+"']";
- }
- }
-
- public static class NumberSearchCriteria extends NamedSearchCriteria {
- long value;
-
- public NumberSearchCriteria(String name, long value) {
- super(name);
- this.value = value;
- }
-
- public long getValue() {
- return value;
- }
- public String toString() {
- return "['"+name+"':'"+value+"']";
- }
- }
-
-
-
- public static class DateSearchCriteria extends NamedSearchCriteria {
- Date value;
-
- public DateSearchCriteria(String name, Date value) {
- super(name);
- this.value = value;
- }
-
- public Date getValue() {
- return value;
- }
- public String toString() {
- return "['"+name+"':'"+value+"']";
- }
-
- }
-
- public static class HeaderSearchCriteria extends SearchCriteria {
- String fieldName;
- String value;
-
- public HeaderSearchCriteria(String fieldName, String value) {
- this.fieldName = fieldName;
- this.value = value;
- }
- public String getName() {
- return HEADER;
- }
-
- public String getFieldName() {
- return fieldName;
- }
-
- public String getValue() {
- return value;
- }
-
- public String toString() {
- return "[header:'"+fieldName+"':'"+value+"']";
- }
-
- }
-
- public static class UIDSearchCriteria extends SearchCriteria {
- NumericRange[] idRanges;
-
- public UIDSearchCriteria(NumericRange[] idRanges) {
- this.idRanges = idRanges;
- }
- public String getName() {
- return UID;
- }
-
- public NumericRange[] getIdRanges() {
- return idRanges;
- }
- }
-
- public static class NotSearchCriteria extends SearchCriteria {
- final List criteria;
-
- public NotSearchCriteria(SearchCriteria inverse) {
- this();
- add(inverse);
- }
-
- public NotSearchCriteria() {
- this.criteria = new ArrayList();
- }
-
- public void add(SearchCriteria criterion) {
- criteria.add(criterion);
- }
-
- public String getName() {
- return NOT;
- }
-
- public List getCriteria() {
- return criteria;
- }
-
- public String toString() {
- return "[NOT "+ criteria +"]";
- }
-
- }
- public static class OrSearchCriteria extends SearchCriteria {
- final List criteria;
-
- public OrSearchCriteria (SearchCriteria a, SearchCriteria b) {
- this();
- add(a);
- add(b);
- }
-
- public OrSearchCriteria() {
- criteria = new ArrayList();
- }
-
- public void add(SearchCriteria criterion) {
- criteria.add(criterion);
- }
-
- public String getName() {
- return OR;
- }
-
-
- public List getCriteria() {
- return criteria;
- }
-
- public String toString() {
- return "[OR "+ criteria +"]";
- }
-
- }
-
-
+
+ /**
+ * Numbers within a particular range.
+ * Range includes both high and low boundaries.
+ * May be a single value.
+ * {@link Long#MAX_VALUE} represents unlimited in either direction.
+ */
public static final class NumericRange {
private final long lowValue;
private final long highValue;
@@ -310,6 +356,437 @@
public String toString() {
return "[" + lowValue + "->" + highValue + "]";
+ }
+ }
+
+ /**
+ * Marker superclass for criteria.
+ */
+ public static abstract class Criterion {}
+
+ /**
+ * Conjuction applying to the contained criteria.
+ * {@link #getType} indicates how the conjoined criteria
+ * should be related.
+ */
+ public static final class ConjunctionCriterion extends Criterion {
+ /** Logical <code>AND</code> */
+ public static final int AND = 1;
+ /** Logical <code>OR</code> */
+ public static final int OR = 2;
+ /** Logical <code>NOT</code> */
+ public static final int NOR = 3;
+
+ private final int type;
+ private final List criteria;
+
+ public ConjunctionCriterion(final int type, final List criteria) {
+ super();
+ this.type = type;
+ this.criteria = criteria;
+ }
+
+ /**
+ * Gets the criteria related through this conjuction.
+ * @return <code>List</code> of {@link Criterion}
+ */
+ public final List getCriteria() {
+ return criteria;
+ }
+
+ /**
+ * Gets the type of conjunction.
+ * @return the type, either {@link #AND}, {@link #OR} or {@link NOR}
+ */
+ public final int getType() {
+ return type;
+ }
+
+
+ }
+
+ /**
+ * Any message.
+ */
+ public static final class AllCriterion extends Criterion {
+ private static final AllCriterion ALL = new AllCriterion();
+
+ private static final Criterion all() {
+ return ALL;
+ }
+ }
+
+ /**
+ * Message text.
+ */
+ public static final class TextCriterion extends Criterion {
+ /**
+ * Only the message body content.
+ */
+ public static final int BODY = 1;
+ /**
+ * The full message content including headers.
+ */
+ public static final int FULL_MESSAGE = 2;
+
+ private final int type;
+ private final ContainsOperator operator;
+
+ private TextCriterion(final String value, final int type) {
+ super();
+ this.operator = new ContainsOperator(value);
+ this.type = type;
+ }
+
+ /**
+ * Gets the type of text to be searched.
+ * @return the type, either {@link #BODY} or {@link #FULL_MESSAGE}
+ */
+ public final int getType() {
+ return type;
+ }
+
+ /**
+ * Gets the search operation and value to be evaluated.
+ * @return the <code>Operator</code>, not null
+ */
+ public final ContainsOperator getOperator() {
+ return operator;
+ }
+ }
+
+ /**
+ * Header value content search.
+ */
+ public static final class HeaderCriterion extends Criterion {
+ private final HeaderOperator operator;
+ private final String headerName;
+
+ private HeaderCriterion(final String headerName, final HeaderOperator operator) {
+ super();
+ this.operator = operator;
+ this.headerName = headerName;
+ }
+
+ /**
+ * Gets the name of the header whose value is to be searched.
+ * @return the headerName
+ */
+ public final String getHeaderName() {
+ return headerName;
+ }
+
+ /**
+ * Gets the search operation and value to be evaluated.
+ * @return the <code>Operator</code>, not null
+ */
+ public final HeaderOperator getOperator() {
+ return operator;
+ }
+ }
+
+ /**
+ * Filters on the internal date.
+ */
+ public static final class InternalDateCriterion extends Criterion {
+ private final DateOperator operator;
+
+ public InternalDateCriterion(final DateOperator operator) {
+ super();
+ this.operator = operator;
+ }
+
+ /**
+ * Gets the search operation and value to be evaluated.
+ * @return the <code>Operator</code>, not null
+ */
+ public final DateOperator getOperator() {
+ return operator;
+ }
+ }
+
+ /**
+ * Filters on the size of the message in octets.
+ */
+ public static final class SizeCriterion extends Criterion {
+ private final NumericOperator operator;
+ private SizeCriterion(final NumericOperator operator) {
+ super();
+ this.operator = operator;
+ }
+
+ /**
+ * Gets the search operation and value to be evaluated.
+ * @return the <code>NumericOperator</code>, not null
+ */
+ public final NumericOperator getOperator() {
+ return operator;
+ }
+ }
+
+ /**
+ * Filters on a custom flag valuation.
+ */
+ public static final class CustomFlagCriterion extends Criterion {
+ private final String flag;
+ private final BooleanOperator operator;
+
+ private CustomFlagCriterion(final String flag, final BooleanOperator operator) {
+ super();
+ this.flag = flag;
+ this.operator = operator;
+ }
+
+ /**
+ * Gets the custom flag to be search.
+ * @return the flag name, not null
+ */
+ public final String getFlag() {
+ return flag;
+ }
+
+ /**
+ * Gets the value to be tested.
+ * @return the <code>BooleanOperator</code>, not null
+ */
+ public final BooleanOperator getOperator() {
+ return operator;
+ }
+
+
+ }
+
+ /**
+ * Filters on a standard flag.
+ */
+ public static final class FlagCriterion extends Criterion {
+ private final Flag flag;
+ private final BooleanOperator operator;
+
+ private FlagCriterion(final Flag flag, final BooleanOperator operator) {
+ super();
+ this.flag = flag;
+ this.operator = operator;
+ }
+
+ /**
+ * Gets the flag filtered on.
+ * @return the flag, not null
+ */
+ public final Flag getFlag() {
+ return flag;
+ }
+
+ /**
+ * Gets the test to be preformed.
+ * @return the <code>BooleanOperator</code>, not null
+ */
+ public final BooleanOperator getOperator() {
+ return operator;
+ }
+ }
+
+ /**
+ * Filters on message identity.
+ */
+ public static final class UidCriterion extends Criterion {
+ private final InOperator operator;
+
+ public UidCriterion(final NumericRange[] ranges) {
+ super();
+ this.operator = new InOperator(ranges);
+ }
+
+ /**
+ * Gets the filtering operation.
+ * @return the <code>InOperator</code>
+ */
+ public final InOperator getOperator() {
+ return operator;
+ }
+ }
+
+ /**
+ * Search operator.
+ */
+ public static abstract class Operator {}
+
+ /**
+ * Marks operator as suitable for header value searching.
+ */
+ public interface HeaderOperator {}
+
+ /**
+ * Contained value search.
+ */
+ public static final class ContainsOperator extends Operator implements HeaderOperator {
+ private final String value;
+
+ public ContainsOperator(final String value) {
+ super();
+ this.value = value;
+ }
+
+ /**
+ * Gets the value to be searched for.
+ * @return the value
+ */
+ public final String getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * Existance search.
+ */
+ public static final class ExistsOperator extends Operator implements HeaderOperator {
+ private static final ExistsOperator EXISTS = new ExistsOperator();
+
+ public static final ExistsOperator exists() {
+ return EXISTS;
+ }
+ }
+
+ /**
+ * Boolean value search.
+ */
+ public static final class BooleanOperator extends Operator {
+
+ private static final BooleanOperator SET = new BooleanOperator(true);
+ private static final BooleanOperator UNSET = new BooleanOperator(false);
+
+ public static final BooleanOperator set() {
+ return SET;
+ }
+
+ public static final BooleanOperator unset() {
+ return UNSET;
+ }
+
+ private final boolean set;
+
+ private BooleanOperator(final boolean set) {
+ super();
+ this.set = set;
+ }
+
+ /**
+ * Is the search for set?
+ * @return true indicates that set values
+ * should be selected, false indicates
+ * that unset values should be selected
+ */
+ public final boolean isSet() {
+ return set;
+ }
+ }
+
+ /**
+ * Searches numberic values.
+ */
+ public static final class NumericOperator extends Operator {
+ public static final int EQUALS = 1;
+ public static final int LESS_THAN = 2;
+ public static final int GREATER_THAN = 3;
+
+ private final long value;
+ private final int type;
+
+ private NumericOperator(final long value, final int type) {
+ super();
+ this.value = value;
+ this.type = type;
+ }
+
+ /**
+ * Gets the operation type
+ * @return the type either {@link #EQUALS}, {@link #LESS_THAN} or {@link #GREATER_THAN}
+ */
+ public final int getType() {
+ return type;
+ }
+
+ /**
+ * Gets the value to be compared.
+ * @return the value
+ */
+ public final long getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * Operates on a date.
+ */
+ public static final class DateOperator extends Operator implements HeaderOperator {
+ public static final int BEFORE = 1;
+ public static final int AFTER = 2;
+ public static final int ON = 3;
+
+ private final int type;
+ private final int day;
+ private final int month;
+ private final int year;
+
+ public DateOperator(final int type, final int day, final int month, final int year) {
+ super();
+ this.type = type;
+ this.day = day;
+ this.month = month;
+ this.year = year;
+ }
+
+ /**
+ * Gets the day-of-the-month.
+ * @return the day, one based
+ */
+ public final int getDay() {
+ return day;
+ }
+
+ /**
+ * Gets the month-of-the-year.
+ * @return the month, one based
+ */
+ public final int getMonth() {
+ return month;
+ }
+
+ /**
+ * Gets the operator type.
+ * @return the type, either {@link #BEFORE}, {@link #AFTER} or {@link ON}
+ */
+ public final int getType() {
+ return type;
+ }
+
+ /**
+ * Gets the year.
+ * @return the year
+ */
+ public final int getYear() {
+ return year;
+ }
+ }
+
+ /**
+ * Search for numbers within set of ranges.
+ */
+ public static final class InOperator extends Operator {
+ private final NumericRange[] range;
+
+ public InOperator(final NumericRange[] range) {
+ super();
+ this.range = range;
+ }
+
+ /**
+ * Gets the filtering ranges.
+ * Values falling within these ranges will be selected.
+ * @return the <code>NumericRange</code>'s search on, not null
+ */
+ public final NumericRange[] getRange() {
+ return range;
}
}
}
Modified: james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/ImapMailbox.java
URL: http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/ImapMailbox.java?rev=632829&r1=632828&r2=632829&view=diff
==============================================================================
--- james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/ImapMailbox.java (original)
+++ james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/mailbox/ImapMailbox.java Sun Mar 2 12:21:26 2008
@@ -29,7 +29,7 @@
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MailboxSession;
import org.apache.james.mailboxmanager.MessageResult;
-import org.apache.james.mailboxmanager.SearchParameters;
+import org.apache.james.mailboxmanager.SearchQuery;
import org.apache.james.mailboxmanager.MessageResult.FetchGroup;
@@ -56,8 +56,7 @@
* @throws UnsupportedCriteriaException when any of the search parameters are
* not supported by this mailbox
*/
- Iterator search(GeneralMessageSet set, SearchParameters searchTerm, FetchGroup fetchGroup,
- MailboxSession mailboxSession) throws MailboxManagerException;
+ Iterator search(SearchQuery searchQuery, FetchGroup fetchGroup, MailboxSession mailboxSession) throws MailboxManagerException;
long getUidValidity(MailboxSession mailboxSession) throws MailboxManagerException;
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=632829&r1=632828&r2=632829&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 Sun Mar 2 12:21:26 2008
@@ -41,10 +41,9 @@
import org.apache.james.imapserver.store.MailboxException;
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MessageResult;
-import org.apache.james.mailboxmanager.SearchParameters;
+import org.apache.james.mailboxmanager.SearchQuery;
import org.apache.james.mailboxmanager.MessageResult.FetchGroup;
import org.apache.james.mailboxmanager.impl.FetchGroupImpl;
-import org.apache.james.mailboxmanager.impl.GeneralMessageSetImpl;
import org.apache.james.mailboxmanager.mailbox.ImapMailbox;
public class SearchProcessor extends AbstractImapRequestProcessor {
@@ -76,8 +75,8 @@
final Iterator it;
try {
// TODO: implementation
- it = mailbox.search(GeneralMessageSetImpl.all(),
- new SearchParameters(), resultCode, ImapSessionUtils.getMailboxSession(session));
+ it = mailbox.search(new SearchQuery(),
+ resultCode, ImapSessionUtils.getMailboxSession(session));
} catch (MailboxManagerException e) {
throw new MailboxException(e);
}
Modified: james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java?rev=632829&r1=632828&r2=632829&view=diff
==============================================================================
--- james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java (original)
+++ james/server/trunk/imapserver-function/src/main/java/org/apache/james/imapserver/commands/SearchCommand.java Sun Mar 2 12:21:26 2008
@@ -19,7 +19,15 @@
package org.apache.james.imapserver.commands;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Set;
+
+import javax.mail.Flags.Flag;
import org.apache.james.imapserver.ImapRequestLineReader;
import org.apache.james.imapserver.ImapResponse;
@@ -29,13 +37,13 @@
import org.apache.james.imapserver.store.MailboxException;
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MessageResult;
-import org.apache.james.mailboxmanager.SearchParameters;
+import org.apache.james.mailboxmanager.SearchQuery;
import org.apache.james.mailboxmanager.MessageResult.FetchGroup;
-import org.apache.james.mailboxmanager.SearchParameters.NumericRange;
-import org.apache.james.mailboxmanager.SearchParameters.SearchCriteria;
+import org.apache.james.mailboxmanager.SearchQuery.Criterion;
+import org.apache.james.mailboxmanager.SearchQuery.NumericRange;
import org.apache.james.mailboxmanager.impl.FetchGroupImpl;
-import org.apache.james.mailboxmanager.impl.GeneralMessageSetImpl;
import org.apache.james.mailboxmanager.mailbox.ImapMailbox;
+import org.apache.mailet.RFC2822Headers;
/**
* Handles processeing for the SEARCH imap command.
@@ -44,11 +52,65 @@
*/
class SearchCommand extends SelectedStateCommand implements UidEnabledCommand
{
+ public static final String HEADER = "HEADER";
+ public static final String UID = "UID";
+ public static final String NOT = "NOT";
+ public static final String OR = "OR";
+ public static final String SMALLER = "SMALLER";
+ public static final String LARGER = "LARGER";
+ public static final String SINCE = "SINCE";
+ public static final String SENTSINCE = "SENTSINCE";
+ public static final String SENTON = "SENTON";
+ public static final String SENTBEFORE = "SENTBEFORE";
+ public static final String ON = "ON";
+ public static final String BEFORE = "BEFORE";
+ public static final String UNKEYWORD = "UNKEYWORD";
+ public static final String TO = "TO";
+ public static final String TEXT = "TEXT";
+ public static final String SUBJECT = "SUBJECT";
+ public static final String KEYWORD = "KEYWORD";
+ public static final String FROM = "FROM";
+ public static final String CC = "CC";
+ public static final String BODY = "BODY";
+ public static final String BCC = "BCC";
+ public static final String UNSEEN = "UNSEEN";
+ public static final String UNFLAGGED = "UNFLAGGED";
+ public static final String UNDRAFT = "UNDRAFT";
+ public static final String UNDELETED = "UNDELETED";
+ public static final String UNANSWERED = "UNANSWERED";
+ public static final String SEEN = "SEEN";
+ public static final String RECENT = "RECENT";
+ public static final String OLD = "OLD";
+ public static final String NEW = "NEW";
+ public static final String FLAGGED = "FLAGGED";
+ public static final String DRAFT = "DRAFT";
+ public static final String DELETED = "DELETED";
+ public static final String ANSWERED = "ANSWERED";
+ public static final String ALL = "ALL";
+
+ public final static Set BASE_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
+ ALL, ANSWERED, DELETED, DRAFT, FLAGGED, OLD, RECENT, SEEN,
+ UNANSWERED, UNDELETED, UNDRAFT, UNFLAGGED, UNSEEN
+ })));
+ public final static Set STRING_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
+ BCC, BODY, CC, FROM, SUBJECT, TO
+ })));
+ public final static Set DATE_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
+ BEFORE, ON, SENTBEFORE, SENTON, SENTSINCE , SINCE
+ })));
+ public final static Set SPECIAL_SEARCH_TERMS = new HashSet(Arrays.asList(new String[] {
+ OR, NOT, UID, HEADER
+ }));
+ public final static Set NUMBER_SEARCH_TERMS = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] {
+ LARGER, SMALLER
+ })));
+
public static final String NAME = "SEARCH";
public static final String ARGS = "<search term>";
private SearchCommandParser parser = new SearchCommandParser();
+
/** @see CommandTemplate#doProcess */
protected void doProcess( ImapRequestLineReader request,
ImapResponse response,
@@ -65,7 +127,7 @@
throws ProtocolException, MailboxException
{
// Parse the search term from the request
- SearchParameters searchTerm = parser.searchTerm( request );
+ SearchQuery searchTerm = parser.searchTerm( request );
parser.endLine( request );
final SelectedMailboxSession selected = session.getSelected();
@@ -73,7 +135,7 @@
final FetchGroup result = FetchGroupImpl.MINIMAL;
final Iterator it;
try {
- it = mailbox.search(GeneralMessageSetImpl.all(),searchTerm, result, session.getMailboxSession());
+ it = mailbox.search(searchTerm,result, session.getMailboxSession());
} catch (MailboxManagerException e) {
throw new MailboxException(e);
}
@@ -120,16 +182,16 @@
/**
* Parses the request argument into a valid search term.
*/
- public SearchParameters searchTerm( ImapRequestLineReader request )
+ public SearchQuery searchTerm( ImapRequestLineReader request )
throws ProtocolException
{
- SearchParameters search = new SearchParameters();
+ SearchQuery search = new SearchQuery();
char next = request.nextChar();
while ( next != '\n' && next != '\r') {
- SearchParameters.SearchCriteria crit = parseCriteria(request);
- search.addCriteria(crit);
+ SearchQuery.Criterion crit = parseCriteria(request);
+ search.andCriteria(crit);
next = request.nextChar();
while ( next == ' ' ) {
request.consume();
@@ -140,29 +202,148 @@
return search;
}
- private SearchCriteria parseCriteria(ImapRequestLineReader request) throws ProtocolException {
+ private Criterion parseCriteria(ImapRequestLineReader request) throws ProtocolException {
String term = atom(request).toUpperCase();
-
- if (SearchParameters.BASE_SEARCH_TERMS.contains(term)) {
- return new SearchParameters.NamedSearchCriteria(term);
- } else if (SearchParameters.STRING_SEARCH_TERMS.contains(term)) {
- return new SearchParameters.StringSearchCriteria(term, astring(request));
- } else if (SearchParameters.NUMBER_SEARCH_TERMS.contains(term)) {
- return new SearchParameters.NumberSearchCriteria(term, number(request));
- } else if (SearchParameters.DATE_SEARCH_TERMS.contains(term)) {
- return new SearchParameters.DateSearchCriteria(term, date(request));
+ if (ALL.equals(term)) {
+ return SearchQuery.all();
+ } else if (NEW.equals(term)) {
+ return SearchQuery.and(flag(RECENT), flag(UNSEEN));
+ } else if (KEYWORD.equals(term)) {
+ return keyword(true, request);
+ } else if (UNKEYWORD.equals(term)) {
+ return keyword(false, request);
+ } else if (TEXT.equals(term)) {
+ return SearchQuery.mailContains(astring(request));
+ } else if (BODY.equals(term)) {
+ return SearchQuery.bodyContains(astring(request));
+ } else if (SearchCommand.BASE_SEARCH_TERMS.contains(term)) {
+ return flag(term);
+ } else if (SearchCommand.STRING_SEARCH_TERMS.contains(term)) {
+ return header(term, astring(request));
+ } else if (SearchCommand.NUMBER_SEARCH_TERMS.contains(term)) {
+ return numeric(request, term);
+ } else if (SearchCommand.DATE_SEARCH_TERMS.contains(term)) {
+ return date(request, term);
} else if ("HEADER".equals(term)) {
- return new SearchParameters.HeaderSearchCriteria(astring(request), astring(request));
+ return SearchQuery.headerContains(astring(request), astring(request));
} else if ("UID".equals(term)) {
- return new SearchParameters.UIDSearchCriteria(toNumericRange(parseIdRange(request)));
+ return SearchQuery.uid(toNumericRange(parseIdRange(request)));
} else if ("OR".equals(term)) {
- return new SearchParameters.OrSearchCriteria(parseCriteria(request), parseCriteria(request));
+ return SearchQuery.or(parseCriteria(request), parseCriteria(request));
} else if ("NOT".equals(term)) {
- return new SearchParameters.NotSearchCriteria(parseCriteria(request));
+ return SearchQuery.not(parseCriteria(request));
} else {
throw new ProtocolException("Term '"+term+"' not supported in the current search implementation!");
}
}
+
+ private Criterion header(String term, String value) throws ProtocolException {
+ final String headerName;
+ if ( BCC.equals(term)) {
+ headerName = RFC2822Headers.BCC;
+ } else if (CC.equals(term)) {
+ headerName = RFC2822Headers.CC;
+ } else if (FROM.equals(term)) {
+ headerName = RFC2822Headers.FROM;
+ } else if (SUBJECT.equals(term)) {
+ headerName = RFC2822Headers.SUBJECT;
+ } else if (TO.equals(term)) {
+ headerName = RFC2822Headers.TO;
+ } else {
+ throw new ProtocolException("Unknown search key");
+ }
+ return SearchQuery.headerContains(headerName, value);
+ }
+
+ private Criterion keyword(boolean isSet, ImapRequestLineReader request) throws ProtocolException {
+ final String keyword = astring(request);
+ return SearchQuery.flagSet(keyword, isSet);
+ }
+
+ private Criterion flag(String term) throws ProtocolException {
+ final Flag flag;
+ final boolean value;
+ if (ANSWERED.equals(term)) {
+ flag = Flag.ANSWERED;
+ value = true;
+ } else if (DELETED.equals(term)) {
+ flag = Flag.DELETED;
+ value = true;
+ } else if (DRAFT.equals(term)) {
+ flag = Flag.DRAFT;
+ value = true;
+ } else if (FLAGGED.equals(term)) {
+ flag = Flag.FLAGGED;
+ value = true;
+ } else if (OLD.equals(term)) {
+ flag = Flag.RECENT;
+ value = false;
+ } else if (RECENT.equals(term)) {
+ flag = Flag.RECENT;
+ value = true;
+ } else if (SEEN.equals(term)) {
+ flag = Flag.SEEN;
+ value = true;
+ } else if (UNANSWERED.equals(term)) {
+ flag = Flag.ANSWERED;
+ value = false;
+ } else if (UNDELETED.equals(term)) {
+ flag = Flag.DELETED;
+ value = false;
+ } else if (UNDRAFT.equals(term)) {
+ flag = Flag.DRAFT;
+ value = false;
+ } else if (UNFLAGGED.equals(term)) {
+ flag = Flag.FLAGGED;
+ value = false;
+ } else if (UNSEEN.equals(term)) {
+ flag = Flag.SEEN;
+ value = false;
+ } else {
+ throw new ProtocolException("Unknown search key");
+ }
+ final Criterion result = SearchQuery.flagSet(flag, value);
+ return result;
+ }
+
+ private Criterion date(ImapRequestLineReader request, String term) throws ProtocolException {
+ final Date date = date(request);
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ final int day = calendar.get(Calendar.DAY_OF_MONTH);
+ final int month = calendar.get(Calendar.MONTH) + 1;
+ final int year = calendar.get(Calendar.YEAR);
+ final Criterion result;
+ if (BEFORE.equals(term)) {
+ result = SearchQuery.internalDateBefore(day, month, year);
+ } else if (ON.equals(term)) {
+ result = SearchQuery.internalDateOn(day, month, year);
+ } else if (SENTBEFORE.equals(term)) {
+ result = SearchQuery.headerDateBefore(RFC2822Headers.DATE, day, month, year);
+ } else if (SENTON.equals(term)) {
+ result = SearchQuery.headerDateBefore(RFC2822Headers.DATE, day, month, year);
+ } else if (SENTSINCE.equals(term)) {
+ result = SearchQuery.headerDateBefore(RFC2822Headers.DATE, day, month, year);
+ } else if (SINCE.equals(term)) {
+ result = SearchQuery.internalDateAfter(day, month, year);
+ } else {
+ throw new ProtocolException("Unknown search key");
+ }
+ return result;
+ }
+
+ private Criterion numeric(ImapRequestLineReader request, String term) throws ProtocolException {
+ final long value = number(request);
+ final Criterion result;
+ if (LARGER.equals(term)) {
+ result = SearchQuery.sizeGreaterThan(value);
+ } else if (SMALLER.equals(term)) {
+ result = SearchQuery.sizeLessThan(value);
+ } else {
+ throw new ProtocolException("Unknown search key");
+ }
+ return result;
+ }
private NumericRange[] toNumericRange(final IdRange[] ranges) {
final NumericRange[] result;
Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java
URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java?rev=632829&r1=632828&r2=632829&view=diff
==============================================================================
--- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java (original)
+++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java Sun Mar 2 12:21:26 2008
@@ -41,8 +41,7 @@
import org.apache.james.mailboxmanager.MailboxManagerException;
import org.apache.james.mailboxmanager.MailboxSession;
import org.apache.james.mailboxmanager.MessageResult;
-import org.apache.james.mailboxmanager.SearchParameters;
-import org.apache.james.mailboxmanager.UnsupportedCriteriaException;
+import org.apache.james.mailboxmanager.SearchQuery;
import org.apache.james.mailboxmanager.MessageResult.FetchGroup;
import org.apache.james.mailboxmanager.impl.FetchGroupImpl;
import org.apache.james.mailboxmanager.impl.GeneralMessageSetImpl;
@@ -60,7 +59,6 @@
import org.apache.james.mailboxmanager.tracking.UidRange;
import org.apache.james.mailboxmanager.util.UidToKeyConverter;
import org.apache.james.mailboxmanager.util.UidToKeyConverterImpl;
-import org.apache.mailet.RFC2822Headers;
import org.apache.torque.NoRowsException;
import org.apache.torque.TooManyRowsException;
import org.apache.torque.TorqueException;
@@ -607,109 +605,14 @@
this.mailboxRow = mailboxRow;
}
- public Iterator search(GeneralMessageSet set, SearchParameters parameters,
- FetchGroup fetchGroup, MailboxSession mailboxSession) throws MailboxManagerException {
+ public Iterator search(SearchQuery parameters, FetchGroup fetchGroup,
+ MailboxSession mailboxSession) throws MailboxManagerException {
try {
lock.readLock().acquire();
try {
checkAccess();
- set=toUidSet(set);
- if (!set.isValid() || set.getType()==GeneralMessageSet.TYPE_NOTHING) {
- return IteratorUtils.EMPTY_ITERATOR;
- }
TorqueCriteriaBuilder builder = new TorqueCriteriaBuilder();
-
- final List searchCriteria = parameters.getCriterias();
- for (Iterator it=searchCriteria.iterator();it.hasNext();) {
- SearchParameters.SearchCriteria criterion = (SearchParameters.SearchCriteria) it.next();
- final String name = criterion.getName();
- if (SearchParameters.ALL.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.ANSWERED.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.ANSWERED, true);
- } else if (SearchParameters.BCC.equals(name)) {
- SearchParameters.StringSearchCriteria stringSearchCriteria = (SearchParameters.StringSearchCriteria) criterion;
- final String value = stringSearchCriteria.getValue();
- builder.andHeaderContains(RFC2822Headers.BCC, value);
- } else if (SearchParameters.BEFORE.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.BODY.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.CC.equals(name)) {
- SearchParameters.StringSearchCriteria stringSearchCriteria = (SearchParameters.StringSearchCriteria) criterion;
- final String value = stringSearchCriteria.getValue();
- builder.andHeaderContains(RFC2822Headers.CC, value);
- } else if (SearchParameters.DELETED.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.DELETED, true);
- } else if (SearchParameters.DRAFT.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.DRAFT, true);
- } else if (SearchParameters.FLAGGED.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.FLAGGED, true);
- } else if (SearchParameters.FROM.equals(name)) {
- SearchParameters.StringSearchCriteria stringSearchCriteria = (SearchParameters.StringSearchCriteria) criterion;
- final String value = stringSearchCriteria.getValue();
- builder.andHeaderContains(RFC2822Headers.FROM, value);
- } else if (SearchParameters.HEADER.equals(name)) {
- SearchParameters.HeaderSearchCriteria headerSearchCriteria = (SearchParameters.HeaderSearchCriteria) criterion;
- final String value = headerSearchCriteria.getValue();
- final String fieldName = headerSearchCriteria.getFieldName();
- builder.andHeaderContains(fieldName, value);
- } else if (SearchParameters.KEYWORD.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.LARGER.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.NEW.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.RECENT, true);
- builder.andFlag(javax.mail.Flags.Flag.RECENT, false);
- } else if (SearchParameters.NOT.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.OLD.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.ON.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.OR.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.RECENT.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.RECENT, true);
- } else if (SearchParameters.SEEN.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.SEEN, true);
- } else if (SearchParameters.SENTBEFORE.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.SENTON.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.SENTSINCE.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.SINCE.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.SMALLER.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.SUBJECT.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.TEXT.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.TO.equals(name)) {
- SearchParameters.StringSearchCriteria stringSearchCriteria = (SearchParameters.StringSearchCriteria) criterion;
- final String value = stringSearchCriteria.getValue();
- builder.andHeaderContains(RFC2822Headers.TO, value);
- } else if (SearchParameters.UID.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.UNANSWERED.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.ANSWERED, false);
- } else if (SearchParameters.UNDELETED.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.DELETED, false);
- } else if (SearchParameters.UNDRAFT.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.DRAFT, false);
- } else if (SearchParameters.UNFLAGGED.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.FLAGGED, false);
- } else if (SearchParameters.UNKEYWORD.equals(name)) {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- } else if (SearchParameters.UNSEEN.equals(name)) {
- builder.andFlag(javax.mail.Flags.Flag.SEEN, false);
- } else {
- throw new UnsupportedCriteriaException("Search criterion '" + name + "' is not supported");
- }
- }
final Iterator results = getMessages(fetchGroup, new UidRange(1, -1), builder.getCriteria());
return results;
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org