james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rdon...@apache.org
Subject svn commit: r633313 - in /james/server/trunk: core-library/src/main/java/org/apache/james/mailboxmanager/ imap-api/src/main/java/org/apache/james/api/imap/message/request/ imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev...
Date Mon, 03 Mar 2008 22:47:53 GMT
Author: rdonkin
Date: Mon Mar  3 14:47:49 2008
New Revision: 633313

URL: http://svn.apache.org/viewvc?rev=633313&view=rev
Log:
Completed SearchProcessor

Added:
    james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessorTest.java
Modified:
    james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.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/main/java/org/apache/james/imap/message/response/imap4rev1/server/SearchResponse.java
    james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessor.java

Modified: james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java
URL: http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java?rev=633313&r1=633312&r2=633313&view=diff
==============================================================================
--- james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java (original)
+++ james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/SearchQuery.java Mon Mar  3 14:47:49 2008
@@ -20,6 +20,7 @@
 package org.apache.james.mailboxmanager;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import javax.mail.Flags.Flag;
@@ -216,6 +217,15 @@
     }
     
     /**
+     * Creates a filter composing the listed criteria.
+     * @param criteria <code>List</code> of {@link Criterion}
+     * @return <code>Criterion</code>, not null
+     */
+    public static final Criterion and(List criteria) {
+        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
@@ -325,6 +335,38 @@
 	}
     
     /**
+     * @see java.lang.Object#hashCode()
+     */
+    //@Override
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + ((criterias == null) ? 0 : criterias.hashCode());
+        return result;
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    //@Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final SearchQuery other = (SearchQuery) obj;
+        if (criterias == null) {
+            if (other.criterias != null)
+                return false;
+        } else if (!criterias.equals(other.criterias))
+            return false;
+        return true;
+    }
+    
+    
+    /**
      * Numbers within a particular range.
      * Range includes both high and low boundaries.
      * May be a single value.
@@ -354,9 +396,51 @@
             return lowValue;
         }
         
-        public String toString() {
-            return "[" + lowValue + "->" + highValue + "]";
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + (int) (highValue ^ (highValue >>> 32));
+            result = PRIME * result + (int) (lowValue ^ (lowValue >>> 32));
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final NumericRange other = (NumericRange) obj;
+            if (highValue != other.highValue)
+                return false;
+            if (lowValue != other.lowValue)
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            return new StringBuffer().append(this.lowValue)
+                .append("->").append(this.highValue).toString();
         }
+        
+        
     }
     
     /**
@@ -401,6 +485,61 @@
         public final int getType() {
             return type;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((criteria == null) ? 0 : criteria.hashCode());
+            result = PRIME * result + type;
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final ConjunctionCriterion other = (ConjunctionCriterion) obj;
+            if (criteria == null) {
+                if (other.criteria != null)
+                    return false;
+            } else if (!criteria.equals(other.criteria))
+                return false;
+            if (type != other.type)
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("ConjunctionCriterion ( ")
+                .append("criteria = ").append(this.criteria).append(TAB)
+                .append("type = ").append(this.type).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
         
         
     }
@@ -414,6 +553,26 @@
         private static final Criterion all() {
             return ALL;
         }
+        
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            return obj instanceof AllCriterion;
+        }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            return 1729;
+        }
+
+        public String toString() {
+            return "AllCriterion";
+        }
     }
     
     /**
@@ -453,6 +612,61 @@
         public final ContainsOperator getOperator() {
             return operator;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((operator == null) ? 0 : operator.hashCode());
+            result = PRIME * result + type;
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final TextCriterion other = (TextCriterion) obj;
+            if (operator == null) {
+                if (other.operator != null)
+                    return false;
+            } else if (!operator.equals(other.operator))
+                return false;
+            if (type != other.type)
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("TextCriterion ( ")
+                .append("operator = ").append(this.operator).append(TAB)
+                .append("type = ").append(this.type).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
     }
     
     /**
@@ -483,6 +697,66 @@
         public final HeaderOperator getOperator() {
             return operator;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((headerName == null) ? 0 : headerName.hashCode());
+            result = PRIME * result + ((operator == null) ? 0 : operator.hashCode());
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final HeaderCriterion other = (HeaderCriterion) obj;
+            if (headerName == null) {
+                if (other.headerName != null)
+                    return false;
+            } else if (!headerName.equals(other.headerName))
+                return false;
+            if (operator == null) {
+                if (other.operator != null)
+                    return false;
+            } else if (!operator.equals(other.operator))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("HeaderCriterion ( ")
+                .append("headerName = ").append(this.headerName).append(TAB)
+                .append("operator = ").append(this.operator).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
+        
+        
     }
     
     /**
@@ -503,6 +777,57 @@
         public final DateOperator getOperator() {
             return operator;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((operator == null) ? 0 : operator.hashCode());
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final InternalDateCriterion other = (InternalDateCriterion) obj;
+            if (operator == null) {
+                if (other.operator != null)
+                    return false;
+            } else if (!operator.equals(other.operator))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("InternalDateCriterion ( ")
+                .append("operator = ").append(this.operator).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
     }
     
     /**
@@ -522,6 +847,57 @@
         public final NumericOperator getOperator() {
             return operator;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((operator == null) ? 0 : operator.hashCode());
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final SizeCriterion other = (SizeCriterion) obj;
+            if (operator == null) {
+                if (other.operator != null)
+                    return false;
+            } else if (!operator.equals(other.operator))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("SizeCriterion ( ")
+                .append("operator = ").append(this.operator).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
     }
     
     /**
@@ -552,8 +928,64 @@
         public final BooleanOperator getOperator() {
             return operator;
         }
-        
-        
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((flag == null) ? 0 : flag.hashCode());
+            result = PRIME * result + ((operator == null) ? 0 : operator.hashCode());
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final CustomFlagCriterion other = (CustomFlagCriterion) obj;
+            if (flag == null) {
+                if (other.flag != null)
+                    return false;
+            } else if (!flag.equals(other.flag))
+                return false;
+            if (operator == null) {
+                if (other.operator != null)
+                    return false;
+            } else if (!operator.equals(other.operator))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("CustomFlagCriterion ( ")
+                .append("flag = ").append(this.flag).append(TAB)
+                .append("operator = ").append(this.operator).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
     }
     
     /**
@@ -584,6 +1016,66 @@
         public final BooleanOperator getOperator() {
             return operator;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((flag == null) ? 0 : flag.hashCode());
+            result = PRIME * result + ((operator == null) ? 0 : operator.hashCode());
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final FlagCriterion other = (FlagCriterion) obj;
+            if (flag == null) {
+                if (other.flag != null)
+                    return false;
+            } else if (!flag.equals(other.flag))
+                return false;
+            if (operator == null) {
+                if (other.operator != null)
+                    return false;
+            } else if (!operator.equals(other.operator))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("FlagCriterion ( ")
+                .append("flag = ").append(this.flag).append(TAB)
+                .append("operator = ").append(this.operator).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
+        
+        
     }
     
     /**
@@ -604,22 +1096,74 @@
         public final InOperator getOperator() {
             return operator;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((operator == null) ? 0 : operator.hashCode());
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final UidCriterion other = (UidCriterion) obj;
+            if (operator == null) {
+                if (other.operator != null)
+                    return false;
+            } else if (!operator.equals(other.operator))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("UidCriterion ( ")
+                .append("operator = ").append(this.operator).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
+        
     }
     
     /**
      * Search operator.
      */
-    public static abstract class Operator {}
+    public interface Operator {}
     
     /**
      * Marks operator as suitable for header value searching.
      */
-    public interface HeaderOperator {}
+    public interface HeaderOperator extends Operator {}
     
     /**
      * Contained value search.
      */
-    public static final class ContainsOperator extends Operator implements HeaderOperator {
+    public static final class ContainsOperator implements HeaderOperator{
         private final String value;
 
         public ContainsOperator(final String value) {
@@ -634,23 +1178,99 @@
         public final String getValue() {
             return value;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + ((value == null) ? 0 : value.hashCode());
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final ContainsOperator other = (ContainsOperator) obj;
+            if (value == null) {
+                if (other.value != null)
+                    return false;
+            } else if (!value.equals(other.value))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("ContainsOperator ( ")
+                .append("value = ").append(this.value).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
     }
     
     /**
      * Existance search.
      */
-    public static final class ExistsOperator extends Operator implements HeaderOperator  {
+    public static final class ExistsOperator implements HeaderOperator  {
         private static final ExistsOperator EXISTS = new ExistsOperator();
         
         public static final ExistsOperator exists() {
             return EXISTS;
         }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            return obj instanceof ExistsOperator;
+        }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            return 42;
+        }
+
+        /**
+         * @see java.lang.Object#toString()
+         */
+        //@Override
+        public String toString() {
+            return "ExistsCriterion";
+        }
+        
     }
         
     /**
      * Boolean value search.
      */
-    public static final class BooleanOperator extends Operator {
+    public static final class BooleanOperator implements Operator {
         
         private static final BooleanOperator SET = new BooleanOperator(true);
         private static final BooleanOperator UNSET = new BooleanOperator(false);
@@ -679,12 +1299,62 @@
         public final boolean isSet() {
             return set;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + (set ? 1231 : 1237);
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final BooleanOperator other = (BooleanOperator) obj;
+            if (set != other.set)
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("BooleanOperator ( ")
+                .append("set = ").append(this.set).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
+        
+        
     }
     
     /**
      * Searches numberic values.
      */
-    public static final class NumericOperator extends Operator {
+    public static final class NumericOperator implements Operator {
         public static final int EQUALS = 1;
         public static final int LESS_THAN = 2;
         public static final int GREATER_THAN = 3;
@@ -713,12 +1383,64 @@
         public final long getValue() {
             return value;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + type;
+            result = PRIME * result + (int) (value ^ (value >>> 32));
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final NumericOperator other = (NumericOperator) obj;
+            if (type != other.type)
+                return false;
+            if (value != other.value)
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("NumericOperator ( ")
+                .append("type = ").append(this.type).append(TAB)
+                .append("value = ").append(this.value).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
     }
     
     /**
      * Operates on a date.
      */
-    public static final class DateOperator extends Operator implements HeaderOperator  {
+    public static final class DateOperator implements HeaderOperator  {
         public static final int BEFORE = 1;
         public static final int AFTER = 2;
         public static final int ON = 3;
@@ -767,12 +1489,73 @@
         public final int getYear() {
             return year;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + day;
+            result = PRIME * result + month;
+            result = PRIME * result + type;
+            result = PRIME * result + year;
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final DateOperator other = (DateOperator) obj;
+            if (day != other.day)
+                return false;
+            if (month != other.month)
+                return false;
+            if (type != other.type)
+                return false;
+            if (year != other.year)
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("DateOperator ( ")
+                .append("day = ").append(this.day).append(TAB)
+                .append("month = ").append(this.month).append(TAB)
+                .append("type = ").append(this.type).append(TAB)
+                .append("year = ").append(this.year).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
+        
     }
     
     /**
      * Search for numbers within set of ranges.
      */
-    public static final class InOperator extends Operator {
+    public static final class InOperator implements Operator {
         private final NumericRange[] range;
 
         public InOperator(final NumericRange[] range) {
@@ -788,5 +1571,55 @@
         public final NumericRange[] getRange() {
             return range;
         }
+
+        /**
+         * @see java.lang.Object#hashCode()
+         */
+        //@Override
+        public int hashCode() {
+            final int PRIME = 31;
+            int result = 1;
+            result = PRIME * result + Arrays.hashCode(range);
+            return result;
+        }
+
+        /**
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        //@Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            final InOperator other = (InOperator) obj;
+            if (!Arrays.equals(range, other.range))
+                return false;
+            return true;
+        }
+
+        /**
+         * Constructs a <code>String</code> with all attributes
+         * in name = value format.
+         *
+         * @return a <code>String</code> representation 
+         * of this object.
+         */
+        public String toString()
+        {
+            final String TAB = " ";
+            
+            StringBuffer retValue = new StringBuffer();
+            
+            retValue.append("InOperator ( ")
+                .append("range = ").append(this.range).append(TAB)
+                .append(" )");
+            
+            return retValue.toString();
+        }
+        
+        
     }
 }

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=633313&r1=633312&r2=633313&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 Mon Mar  3 14:47:49 2008
@@ -57,7 +57,7 @@
     // OR
     public static final int TYPE_OR = 36;
     // AND
-    public static final int TYPE_AND = 36;
+    public static final int TYPE_AND = 37;
     
     private static final SearchKey UNSEEN = new SearchKey(TYPE_UNSEEN,
             null, null, 0, null, null, null);

Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/server/SearchResponse.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/server/SearchResponse.java?rev=633313&r1=633312&r2=633313&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/server/SearchResponse.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/server/SearchResponse.java Mon Mar  3 14:47:49 2008
@@ -19,6 +19,8 @@
 
 package org.apache.james.imap.message.response.imap4rev1.server;
 
+import java.util.Arrays;
+
 import org.apache.james.api.imap.message.response.ImapResponseMessage;
 
 /**
@@ -43,5 +45,52 @@
     public final long[] getIds() {
         return ids;
     }
-    
+
+    /**
+     * @see java.lang.Object#hashCode()
+     */
+    //@Override
+    public int hashCode() {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + Arrays.hashCode(ids);
+        return result;
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    //@Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final SearchResponse other = (SearchResponse) obj;
+        if (!Arrays.equals(ids, other.ids))
+            return false;
+        return true;
+    }
+
+    /**
+     * Constructs a <code>String</code> with all attributes
+     * in name = value format.
+     *
+     * @return a <code>String</code> representation 
+     * of this object.
+     */
+    public String toString()
+    {
+        final String TAB = " ";
+        
+        StringBuffer retValue = new StringBuffer();
+        
+        retValue.append("SearchResponse ( ")
+            .append("ids = ").append(this.ids).append(TAB)
+            .append(" )");
+        
+        return retValue.toString();
+    }
 }

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=633313&r1=633312&r2=633313&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 Mon Mar  3 14:47:49 2008
@@ -23,16 +23,19 @@
 import java.util.Iterator;
 import java.util.List;
 
-import javax.mail.search.SearchTerm;
+import javax.mail.Flags.Flag;
 
 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.message.IdRange;
+import org.apache.james.api.imap.message.request.DayMonthYear;
 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;
+import org.apache.james.api.imap.process.SelectedImapMailbox;
 import org.apache.james.imap.message.request.imap4rev1.SearchRequest;
 import org.apache.james.imap.message.response.imap4rev1.server.SearchResponse;
 import org.apache.james.imapserver.processor.base.AbstractImapRequestProcessor;
@@ -43,8 +46,10 @@
 import org.apache.james.mailboxmanager.MessageResult;
 import org.apache.james.mailboxmanager.SearchQuery;
 import org.apache.james.mailboxmanager.MessageResult.FetchGroup;
+import org.apache.james.mailboxmanager.SearchQuery.Criterion;
 import org.apache.james.mailboxmanager.impl.FetchGroupImpl;
 import org.apache.james.mailboxmanager.mailbox.ImapMailbox;
+import org.apache.mailet.RFC2822Headers;
 
 public class SearchProcessor extends AbstractImapRequestProcessor {
 
@@ -70,13 +75,14 @@
             final ImapCommand command, final Responder responder) throws MailboxException,
             AuthorizationException, ProtocolException {
         ImapMailbox mailbox = ImapSessionUtils.getMailbox(session);
-        final FetchGroup resultCode = FetchGroupImpl.MINIMAL;
+        final FetchGroup fetchGroup = FetchGroupImpl.MINIMAL;
 
+        final SearchQuery query = toQuery(searchKey, session);
+        
         final Iterator it;
         try {
-            // TODO: implementation
-            it = mailbox.search(new SearchQuery(),
-                    resultCode, ImapSessionUtils.getMailboxSession(session));
+            
+            it = mailbox.search(query, fetchGroup, ImapSessionUtils.getMailboxSession(session));
         } catch (MailboxManagerException e) {
             throw new MailboxException(e);
         }
@@ -105,5 +111,119 @@
         boolean omitExpunged = (!useUids);
         unsolicitedResponses(session, responder, omitExpunged, useUids);
         okComplete(command, tag, responder);
+    }
+
+    private SearchQuery toQuery(final SearchKey key, final ImapSession session) {
+        final SearchQuery result = new SearchQuery();
+        final SearchQuery.Criterion criterion = toCriterion(key, session);
+        result.andCriteria(criterion);
+        return result;
+    }
+    
+    private SearchQuery.Criterion toCriterion(final SearchKey key, final ImapSession session) {
+        final int type = key.getType();
+        final DayMonthYear date = key.getDate();
+        switch(type) {
+            case SearchKey.TYPE_ALL: return SearchQuery.all();
+            case SearchKey.TYPE_AND: return and(key.getKeys(), session);
+            case SearchKey.TYPE_ANSWERED: return SearchQuery.flagIsSet(Flag.ANSWERED);
+            case SearchKey.TYPE_BCC: return SearchQuery.headerContains(RFC2822Headers.BCC, key.getValue());
+            case SearchKey.TYPE_BEFORE: return SearchQuery.internalDateBefore(date.getDay(), date.getMonth(), date.getYear());
+            case SearchKey.TYPE_BODY: return SearchQuery.bodyContains(key.getValue());
+            case SearchKey.TYPE_CC: return SearchQuery.headerContains(RFC2822Headers.CC, key.getValue());
+            case SearchKey.TYPE_DELETED: return SearchQuery.flagIsSet(Flag.DELETED);
+            case SearchKey.TYPE_DRAFT: return SearchQuery.flagIsSet(Flag.DRAFT);
+            case SearchKey.TYPE_FLAGGED: return SearchQuery.flagIsSet(Flag.FLAGGED);
+            case SearchKey.TYPE_FROM: return SearchQuery.headerContains(RFC2822Headers.FROM, key.getValue());
+            case SearchKey.TYPE_HEADER: return SearchQuery.headerContains(key.getName(), key.getValue());
+            case SearchKey.TYPE_KEYWORD: return SearchQuery.flagIsSet(key.getValue());
+            case SearchKey.TYPE_LARGER: return SearchQuery.sizeGreaterThan(key.getSize());
+            case SearchKey.TYPE_NEW: return SearchQuery.and(SearchQuery.flagIsSet(Flag.RECENT), SearchQuery.flagIsUnSet(Flag.SEEN));
+            case SearchKey.TYPE_NOT: return not(key.getKeys(), session);
+            case SearchKey.TYPE_OLD: return SearchQuery.flagIsUnSet(Flag.RECENT);
+            case SearchKey.TYPE_ON: return SearchQuery.internalDateOn(date.getDay(), date.getMonth(), date.getYear());
+            case SearchKey.TYPE_OR: return or(key.getKeys(), session);
+            case SearchKey.TYPE_RECENT: return SearchQuery.flagIsSet(Flag.RECENT);
+            case SearchKey.TYPE_SEEN: return SearchQuery.flagIsSet(Flag.SEEN);
+            case SearchKey.TYPE_SENTBEFORE: return SearchQuery.headerDateBefore(RFC2822Headers.DATE, date.getDay(), date.getMonth(), date.getYear());
+            case SearchKey.TYPE_SENTON: return SearchQuery.headerDateOn(RFC2822Headers.DATE, date.getDay(), date.getMonth(), date.getYear());
+            case SearchKey.TYPE_SENTSINCE: return SearchQuery.headerDateAfter(RFC2822Headers.DATE, date.getDay(), date.getMonth(), date.getYear());
+            case SearchKey.TYPE_SEQUENCE_SET: return sequence(key.getSequenceNumbers(), session, true);
+            case SearchKey.TYPE_SINCE: return SearchQuery.internalDateAfter(date.getDay(), date.getMonth(), date.getYear());
+            case SearchKey.TYPE_SMALLER: return SearchQuery.sizeLessThan(key.getSize());
+            case SearchKey.TYPE_SUBJECT: return SearchQuery.headerContains(RFC2822Headers.SUBJECT, key.getValue());
+            case SearchKey.TYPE_TEXT: return SearchQuery.mailContains(key.getValue());
+            case SearchKey.TYPE_TO: return SearchQuery.headerContains(RFC2822Headers.TO, key.getValue());
+            case SearchKey.TYPE_UID: return sequence(key.getSequenceNumbers(), session, false);
+            case SearchKey.TYPE_UNANSWERED: return SearchQuery.flagIsUnSet(Flag.ANSWERED);
+            case SearchKey.TYPE_UNDELETED: return SearchQuery.flagIsUnSet(Flag.DELETED);
+            case SearchKey.TYPE_UNDRAFT: return SearchQuery.flagIsUnSet(Flag.DRAFT);
+            case SearchKey.TYPE_UNFLAGGED: return SearchQuery.flagIsUnSet(Flag.FLAGGED);
+            case SearchKey.TYPE_UNKEYWORD: return SearchQuery.flagIsUnSet(key.getValue());
+            case SearchKey.TYPE_UNSEEN: return SearchQuery.flagIsUnSet(Flag.SEEN);
+            default:
+                getLogger().warn("Ignoring unknown search key.");
+                return SearchQuery.all();
+        }
+    }
+
+    private Criterion sequence(IdRange[] sequenceNumbers, final ImapSession session, boolean msn) {
+        final int length = sequenceNumbers.length;
+        final SearchQuery.NumericRange[] ranges = new SearchQuery.NumericRange[length];
+        for (int i = 0; i < length; i++) {
+            final IdRange range = sequenceNumbers[i];
+            final long highVal = range.getHighVal();
+            final long lowVal = range.getLowVal();
+            final long lowUid;
+            final long highUid;
+            if (msn) {
+                final SelectedImapMailbox selected = session.getSelected();
+                if (highVal == Long.MAX_VALUE) {
+                    highUid = Long.MAX_VALUE;
+                } else {
+                    final int highMsn = (int) highVal;
+                    highUid = selected.uid(highMsn);
+                }
+                if (lowVal == Long.MAX_VALUE) {
+                    lowUid = Long.MAX_VALUE;
+                } else {
+                    final int lowMsn = (int) lowVal;
+                    lowUid = selected.uid(lowMsn);
+                }                
+            } else {
+                lowUid = lowVal;
+                highUid = highVal;
+            }
+            ranges[i] = new SearchQuery.NumericRange(lowUid, highUid);
+        }
+        return SearchQuery.uid(ranges);
+    }
+
+    private Criterion or(List keys, final ImapSession session) {
+        final SearchKey keyOne = (SearchKey) keys.get(0);
+        final SearchKey keyTwo = (SearchKey) keys.get(1);
+        final Criterion criterionOne = toCriterion(keyOne, session);
+        final Criterion criterionTwo = toCriterion(keyTwo, session);
+        final Criterion result = SearchQuery.or(criterionOne, criterionTwo);
+        return result;
+    }
+    
+    private Criterion not(List keys, final ImapSession session) {
+        final SearchKey key = (SearchKey) keys.get(0);
+        final Criterion criterion = toCriterion(key, session);
+        final Criterion result = SearchQuery.not(criterion);
+        return result;
+    }
+    
+    private Criterion and(List keys, final ImapSession session) {
+        final int size = keys.size();
+        final List criteria = new ArrayList(size);
+        for (Iterator iter = keys.iterator(); iter.hasNext();) {
+            final SearchKey key = (SearchKey) iter.next();
+            final Criterion criterion = toCriterion(key, session);
+            criteria.add(criterion);
+        }
+        final Criterion result = SearchQuery.and(criteria);
+        return result;
     }
 }

Added: james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessorTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessorTest.java?rev=633313&view=auto
==============================================================================
--- james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessorTest.java (added)
+++ james/server/trunk/imap-mailbox-processor-function/src/test/java/org/apache/james/imapserver/processor/imap4rev1/SearchProcessorTest.java Mon Mar  3 14:47:49 2008
@@ -0,0 +1,319 @@
+/****************************************************************
+ * 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.processor.imap4rev1;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.Flags.Flag;
+
+import org.apache.james.api.imap.ImapCommand;
+import org.apache.james.api.imap.display.HumanReadableTextKey;
+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.api.imap.message.response.imap4rev1.StatusResponse;
+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;
+import org.apache.james.api.imap.process.SelectedImapMailbox;
+import org.apache.james.api.imap.process.ImapProcessor.Responder;
+import org.apache.james.imap.message.request.imap4rev1.SearchRequest;
+import org.apache.james.imap.message.response.imap4rev1.server.SearchResponse;
+import org.apache.james.imapserver.processor.base.ImapSessionUtils;
+import org.apache.james.mailboxmanager.MailboxSession;
+import org.apache.james.mailboxmanager.SearchQuery;
+import org.apache.james.mailboxmanager.impl.FetchGroupImpl;
+import org.apache.james.mailboxmanager.mailbox.ImapMailbox;
+import org.apache.mailet.RFC2822Headers;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+public class SearchProcessorTest extends MockObjectTestCase {
+    private static final int DAY = 6;
+    private static final int MONTH = 6;
+    private static final int YEAR = 1944;
+    private static final DayMonthYear DAY_MONTH_YEAR = new DayMonthYear(DAY, MONTH, YEAR);
+    private static final long SIZE = 1729;
+    private static final String KEYWORD = "BD3";
+    private static final long[] EMPTY = {};
+    private static final String TAG = "TAG";
+    private static final String ADDRESS = "John Smith <john@example.org>";
+    private static final String SUBJECT = "Myriad Harbour";
+    private static final IdRange[] IDS = {new IdRange(1), new IdRange(42, 1048)};
+    private static final SearchQuery.NumericRange[] RANGES = {new SearchQuery.NumericRange(1), new SearchQuery.NumericRange(42, 1048)};
+    
+    SearchProcessor processor;
+    Mock next;
+    Mock responder;
+    Mock result;
+    Mock session;
+    Mock command;
+    Mock serverResponseFactory;
+    Mock statusResponse;
+    Mock mailbox;
+    ImapCommand imapCommand;
+    ImapProcessor.Responder responderImpl;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        serverResponseFactory = mock(StatusResponseFactory.class);
+        session = mock(ImapSession.class);
+        command = mock(ImapCommand.class);
+        imapCommand = (ImapCommand) command.proxy();
+        next = mock(ImapProcessor.class);
+        responder = mock(ImapProcessor.Responder.class);
+        statusResponse = mock(StatusResponse.class);
+        responderImpl = (ImapProcessor.Responder) responder.proxy();
+        mailbox = mock(ImapMailbox.class);
+        processor = new SearchProcessor((ImapProcessor) next.proxy(),
+                (StatusResponseFactory) serverResponseFactory.proxy());
+        expectOk();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+    
+    public void testSequenceSetLowerUnlimited() throws Exception {
+        final IdRange[] ids = {new IdRange(Long.MAX_VALUE, 1729)};
+        final SearchQuery.NumericRange[] ranges = {new SearchQuery.NumericRange(Long.MAX_VALUE, 1729L)};
+        Mock selectedMailbox = mock(SelectedImapMailbox.class);
+        selectedMailbox.expects(once()).method("uid").with(eq(1729)).will(returnValue(1729L));
+        session.expects(once()).method("getSelected").will(returnValue(selectedMailbox.proxy()));
+        check(SearchKey.buildSequenceSet(ids), SearchQuery.uid(ranges));
+    }
+    
+    public void testSequenceSetUpperUnlimited() throws Exception {
+        final IdRange[] ids = {new IdRange(1, Long.MAX_VALUE)};
+        final SearchQuery.NumericRange[] ranges = {new SearchQuery.NumericRange(42, Long.MAX_VALUE)};
+        Mock selectedMailbox = mock(SelectedImapMailbox.class);
+        selectedMailbox.expects(once()).method("uid").with(eq(1)).will(returnValue(42L));
+        session.expects(once()).method("getSelected").will(returnValue(selectedMailbox.proxy()));
+        check(SearchKey.buildSequenceSet(ids), SearchQuery.uid(ranges));
+    }
+
+    public void testSequenceSetMsnRange() throws Exception {
+        final IdRange[] ids = {new IdRange(1, 5)};
+        final SearchQuery.NumericRange[] ranges = {new SearchQuery.NumericRange(42, 1729)};
+        Mock selectedMailbox = mock(SelectedImapMailbox.class);
+        selectedMailbox.expects(once()).method("uid").with(eq(1)).will(returnValue(42L));
+        selectedMailbox.expects(once()).method("uid").with(eq(5)).will(returnValue(1729L));
+        session.expects(once()).method("getSelected").will(returnValue(selectedMailbox.proxy()));
+        check(SearchKey.buildSequenceSet(ids), SearchQuery.uid(ranges));
+    }
+    
+    public void testSequenceSetSingleMsn() throws Exception {
+        final IdRange[] ids = {new IdRange(1)};
+        final SearchQuery.NumericRange[] ranges = {new SearchQuery.NumericRange(42)};
+        Mock selectedMailbox = mock(SelectedImapMailbox.class);
+        selectedMailbox.expects(exactly(2)).method("uid").with(eq(1)).will(returnValue(42L));
+        session.expects(once()).method("getSelected").will(returnValue(selectedMailbox.proxy()));
+        check(SearchKey.buildSequenceSet(ids), SearchQuery.uid(ranges));
+    }
+
+    public void testALL() throws Exception {
+        check(SearchKey.buildAll(), SearchQuery.all());
+    }
+
+    public void testANSWERED() throws Exception {
+        check(SearchKey.buildAnswered(), SearchQuery.flagIsSet(Flag.ANSWERED));
+    }
+
+    public void testBCC() throws Exception {
+        check(SearchKey.buildBcc(ADDRESS), SearchQuery.headerContains(RFC2822Headers.BCC, ADDRESS));
+    }
+
+    public void testBEFORE() throws Exception {
+        check(SearchKey.buildBefore(DAY_MONTH_YEAR), SearchQuery.internalDateBefore(DAY, MONTH, YEAR));
+    }
+
+    public void testBODY() throws Exception {
+        check(SearchKey.buildBody(SUBJECT), SearchQuery.bodyContains(SUBJECT));
+    }
+
+    public void testCC() throws Exception {
+        check(SearchKey.buildCc(ADDRESS), SearchQuery.headerContains(RFC2822Headers.CC, ADDRESS));
+    }
+
+    public void testDELETED() throws Exception {
+        check(SearchKey.buildDeleted(), SearchQuery.flagIsSet(Flag.DELETED));
+    }
+
+    public void testDRAFT() throws Exception {
+        check(SearchKey.buildDraft(), SearchQuery.flagIsSet(Flag.DRAFT));
+    }
+
+    public void testFLAGGED() throws Exception {
+        check(SearchKey.buildFlagged(), SearchQuery.flagIsSet(Flag.FLAGGED));
+    }
+    
+
+    public void testFROM() throws Exception {
+        check(SearchKey.buildFrom(ADDRESS), SearchQuery.headerContains(RFC2822Headers.FROM, ADDRESS));
+    }
+
+    public void testHEADER () throws Exception {
+        check(SearchKey.buildHeader(RFC2822Headers.IN_REPLY_TO, ADDRESS), SearchQuery.headerContains(RFC2822Headers.IN_REPLY_TO, ADDRESS));
+    }
+
+    public void testKEYWORD() throws Exception {
+        check(SearchKey.buildKeyword(KEYWORD), SearchQuery.flagIsSet(KEYWORD));
+    }
+
+    public void testLARGER() throws Exception {
+        check(SearchKey.buildLarger(SIZE), SearchQuery.sizeGreaterThan(SIZE));
+    }
+
+    public void testNEW() throws Exception {
+        check(SearchKey.buildNew(), 
+                SearchQuery.and(SearchQuery.flagIsSet(Flag.RECENT), SearchQuery.flagIsUnSet(Flag.SEEN)));
+    }
+
+    public void testNOT() throws Exception {
+        check(SearchKey.buildNot(SearchKey.buildOn(DAY_MONTH_YEAR)), 
+                SearchQuery.not(SearchQuery.internalDateOn(DAY, MONTH, YEAR)));   
+    }
+
+    public void testOLD() throws Exception {
+        check(SearchKey.buildOld(), SearchQuery.flagIsUnSet(Flag.RECENT));
+    }
+
+    public void testON() throws Exception {
+        check(SearchKey.buildOn(DAY_MONTH_YEAR), SearchQuery.internalDateOn(DAY, MONTH, YEAR));
+    }
+
+    public void testAND() throws Exception {
+        List keys = new ArrayList();
+        keys.add(SearchKey.buildOn(DAY_MONTH_YEAR));
+        keys.add(SearchKey.buildOld());
+        keys.add(SearchKey.buildLarger(SIZE));
+        List criteria = new ArrayList();
+        criteria.add(SearchQuery.internalDateOn(DAY, MONTH, YEAR));
+        criteria.add(SearchQuery.flagIsUnSet(Flag.RECENT));
+        criteria.add(SearchQuery.sizeGreaterThan(SIZE));
+        check(SearchKey.buildAnd(keys), SearchQuery.and(criteria));
+    }
+    
+    public void testOR() throws Exception {
+        check(SearchKey.buildOr(SearchKey.buildOn(DAY_MONTH_YEAR), SearchKey.buildOld()), 
+                SearchQuery.or(SearchQuery.internalDateOn(DAY, MONTH, YEAR), SearchQuery.flagIsUnSet(Flag.RECENT)));
+    }
+
+    public void testRECENT() throws Exception {
+        check(SearchKey.buildRecent(), SearchQuery.flagIsSet(Flag.RECENT));
+    }
+
+    public void testSEEN() throws Exception {
+        check(SearchKey.buildSeen(), SearchQuery.flagIsSet(Flag.SEEN));
+    }
+
+    public void testSENTBEFORE() throws Exception {
+        check(SearchKey.buildSentBefore(DAY_MONTH_YEAR), SearchQuery.headerDateBefore(RFC2822Headers.DATE, DAY, MONTH, YEAR));
+    }
+
+    public void testSENTON() throws Exception {
+        check(SearchKey.buildSentOn(DAY_MONTH_YEAR), SearchQuery.headerDateOn(RFC2822Headers.DATE, DAY, MONTH, YEAR));
+    }
+
+    public void testSENTSINCE() throws Exception {
+        check(SearchKey.buildSentSince(DAY_MONTH_YEAR), SearchQuery.headerDateAfter(RFC2822Headers.DATE, DAY, MONTH, YEAR));
+    }
+
+    public void testSINCE() throws Exception {
+        check(SearchKey.buildSince(DAY_MONTH_YEAR), SearchQuery.internalDateAfter(DAY, MONTH, YEAR));
+    }
+
+    public void testSMALLER() throws Exception {
+        check(SearchKey.buildSmaller(SIZE), SearchQuery.sizeLessThan(SIZE));        
+    }
+
+    public void testSUBJECT() throws Exception {
+        check(SearchKey.buildSubject(SUBJECT), SearchQuery.headerContains(RFC2822Headers.SUBJECT, SUBJECT));
+    }
+
+    public void testTEXT() throws Exception {
+        check(SearchKey.buildText(SUBJECT), SearchQuery.mailContains(SUBJECT));
+    }
+
+    public void testTO () throws Exception {
+        check(SearchKey.buildTo(ADDRESS), SearchQuery.headerContains(RFC2822Headers.TO, ADDRESS));
+    }
+
+    public void testUID() throws Exception {
+        check(SearchKey.buildUidSet(IDS), SearchQuery.uid(RANGES));
+    }
+
+    public void testUNANSWERED() throws Exception {
+        check(SearchKey.buildUnanswered(), SearchQuery.flagIsUnSet(Flag.ANSWERED));
+    }
+
+    public void testUNDELETED() throws Exception {
+        check(SearchKey.buildUndeleted(), SearchQuery.flagIsUnSet(Flag.DELETED));
+    }
+
+    public void testUNDRAFT() throws Exception {
+        check(SearchKey.buildUndraft(), SearchQuery.flagIsUnSet(Flag.DRAFT));
+    }
+
+    public void testUNFLAGGED() throws Exception {
+        check(SearchKey.buildUnflagged(), SearchQuery.flagIsUnSet(Flag.FLAGGED));
+    }
+
+    public void testUNKEYWORD() throws Exception {
+        check(SearchKey.buildUnkeyword(KEYWORD), SearchQuery.flagIsUnSet(KEYWORD));
+    }
+
+    public void testUNSEEN() throws Exception {
+        check(SearchKey.buildUnseen(), SearchQuery.flagIsUnSet(Flag.SEEN));
+    }
+    
+    private void check(SearchKey key, SearchQuery.Criterion criterion) throws Exception {
+        SearchQuery query = new SearchQuery();
+        query.andCriteria(criterion);
+        check(key, query);
+    }
+    
+    private void check(SearchKey key, SearchQuery query) throws Exception {
+        MailboxSession mailboxSession = (MailboxSession) mock(MailboxSession.class).proxy();
+        session.expects(once()).method("getAttribute")
+            .with(eq(ImapSessionUtils.MAILBOX_SESSION_ATTRIBUTE_SESSION_KEY))
+            .will(returnValue((MailboxSession) mailboxSession));
+        session.expects(once()).method("getAttribute")
+            .with(eq(ImapSessionUtils.SELECTED_MAILBOX_ATTRIBUTE_SESSION_KEY))
+            .will(returnValue((ImapMailbox) mailbox.proxy()));
+        session.expects(once()).method("unsolicitedResponses").with(eq(true), eq(false)).will(returnValue(new ArrayList()));
+        mailbox.expects(once()).method("search")
+            .with(eq(query), eq(FetchGroupImpl.MINIMAL), eq(mailboxSession))
+            .will(returnValue(new ArrayList().iterator()));
+        responder.expects(once()).method("respond").with(eq(new SearchResponse(EMPTY)));
+        SearchRequest message = new SearchRequest(imapCommand, key, false, TAG);
+        processor.doProcess(message, (ImapSession) session.proxy(), TAG, (ImapCommand) command.proxy(), 
+                (Responder) responder.proxy());
+    }
+    
+    private void expectOk() {
+        StatusResponse response = (StatusResponse) statusResponse.proxy();
+        serverResponseFactory.expects(once()).method("taggedOk")
+            .with(eq(TAG), same(imapCommand), eq(HumanReadableTextKey.COMPLETED))
+                .will(returnValue(response));
+        responder.expects(once()).method("respond").with(same(response));
+    }
+}



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


Mime
View raw message