+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
package org.ibex.mail;
import java.util.*;
+import org.ibex.mail.target.*;
+import org.ibex.util.*;
+/**
+ * [immutable] This class encapsulates a query against a mailbox.
+ *
+ * The default implementation of Mailbox.query() simply retrieves
+ * each message and calls Query.match() on it to filter out any
+ * messages which do not match.
+ *
+ * Production-quality Mailbox implementations will want to inspect
+ * the Query object passed to Mailbox.query() to perform more
+ * efficient queries.
+ */
public class Query {
- public static Query not(Query q) { return null; }
- public static Query and(Query a1, Query a2) { return null; }
- public static Query or(Query a1, Query a2) { return null; }
- public static Query set(int[] set) { return null; }
- public static Query sent(Date d, boolean foo0, boolean foo) { return null; }
- public static Query arrival(Date d, boolean foo, boolean bar) { return null; }
- public static Query uid(int uid) { return null; }
- public static Query uid(int[] uid) { return null; }
- public static Query header(String name) { return null; }
- public static Query header(String name, String val) { return null; }
- public static Query size(int size, boolean foo) { return null; }
- public static Query fullText(String searchFor, boolean foo, boolean bar) { return null; }
-
- // FIXME
- public static class Flag {
- public static final Query ANSWERED = null;
- public static final Query SEEN = null;
- public static final Query DRAFT = null;
- public static final Query FLAGGED = null;
- public static final Query RECENT = null;
- public static final Query DELETED = null;
- }
+ public static Query not(Query q) { return new Query(NOT, new Query[] { q },0,0,0,null,null,null,null,null); }
+ public static Query and(Query q1, Query q2) { return new Query(AND,new Query[]{q1,q2},0,0,0,null,null,null,null,null); }
+ public static Query and(Query[] q) { return new Query(AND, q,0,0,0,null, null, null, null, null ); }
+ public static Query or(Query q1, Query q2) { return new Query(OR,new Query[] {q1,q2},0,0,0,null,null, null, null, null); }
+ public static Query or(Query[] q) { return new Query(OR, q, 0, 0, 0, null, null, null, null, null); }
+ public static Query uid(int min, int max) { return new Query(UID, null, min, max, 0, null, null, null, null, null); }
+ public static Query imapNumber(int min,int max) { return new Query(IMAPNUM,null,min,max,0,null,null,null,null, null); }
+ public static Query nntpNumber(int min,int max) { return new Query(NNTPNUM,null,min,max,0,null,null,null,null, null); }
+ public static Query sent(Date e, Date l) { return new Query(SENT,null,0,0,0,null,null,e,l,null); }
+ public static Query arrival(Date e, Date l) { return new Query(ARRIVAL,null,0,0,0,null,null, e,l,null);}
+ public static Query header(String k, String v) { return new Query(HEADER, null, 0, 0, 0, k, v, null, null, null);}
+ public static Query size(int min, int max) { return new Query(SIZE, null, min, max, 0, null, null, null, null, null);}
+ public static Query body(String text) { return new Query(BODY, null, 0, 0, 0, null, text, null, null, null);}
+ public static Query full(String text) { return new Query(FULL, null, 0, 0, 0, null, text, null, null, null);}
+ public static Query uid(int[] set) { return new Query(UID, null, 0 ,0 ,0, null, null, null, null, set);}
+ public static Query imapNumber(int[] set) { return new Query(IMAPNUM, null, 0 ,0 ,0, null, null, null, null, set);}
+ public static Query all() { return new Query(ALL, null, 0, 0, 0, null, null, null, null, null); }
+ public static Query deleted() { return new Query(DELETED, null, 0, 0, 0, null, null, null, null, null); }
+ public static Query seen() { return new Query(SEEN, null, 0, 0, 0, null, null, null, null, null); }
+ public static Query flagged() { return new Query(FLAGGED, null, 0, 0, 0, null, null, null, null, null); }
+ public static Query draft() { return new Query(DRAFT, null, 0, 0, 0, null, null, null, null, null); }
+ public static Query answered() { return new Query(ANSWERED, null, 0, 0, 0, null, null, null, null, null); }
+ public static Query recent() { return new Query(RECENT, null, 0, 0, 0, null, null, null, null, null); }
+ //public static Query set(boolean uid, int[] set) { return uid ? uid(set) : imapNumber(set); }
+
+ private Query(int type, Query[] q,int min,int max, int flags, String key, String text, Date earliest, Date latest, int[] set) {
+ this.type = type; this.q = q; this.min = min; this.max = max; this.flags = flags; this.key = key; this.text = text;
+ this.earliest = earliest; this.latest = latest; this.set = set; }
+
+ public static final int ALL = 0;
+ public static final int NOT = 1;
+ public static final int AND = 2;
+ public static final int OR = 3;
+ public static final int UID = 4;
+ public static final int SENT = 5;
+ public static final int ARRIVAL = 6;
+ public static final int HEADER = 7;
+ public static final int SIZE = 8;
+ public static final int BODY = 9;
+ public static final int FULL = 10;
+ public static final int IMAPNUM = 11;
+ public static final int DELETED = 12;
+ public static final int SEEN = 13;
+ public static final int FLAGGED = 14;
+ public static final int DRAFT = 15;
+ public static final int ANSWERED = 16;
+ public static final int RECENT = 17;
+ public static final int NNTPNUM = 18;
+ public final int type;
+ public final Query[] q;
+ public final int min;
+ public final int max;
+ public final int flags;
+ public final String key;
+ public final String text;
+ public final Date earliest;
+ public final Date latest;
+ public final int[] set;
+
+ public boolean match(Mailbox.Iterator it) {
+ switch(type) {
+ case ALL: return true;
+ case NOT: return !q[0].match(it);
+ case OR: for(int i=0; i<q.length; i++) if (q[i].match(it)) return true; return false;
+ case AND: for(int i=0; i<q.length; i++) if (!q[i].match(it)) return false; return true;
+ case UID: if (set != null) {
+ for(int i=0; i<set.length; i+=2)
+ if (set[i] <= it.uid() && set[i+1] >= it.uid()) return true;
+ return false; }
+ else return it.uid() >= min && it.uid() <= max;
+ case IMAPNUM: if (set != null) {
+ for(int i=0; i<set.length; i+=2) if (set[i] <= it.imapNumber() && set[i+1] >= it.imapNumber()) return true;
+ return false; }
+ else return it.imapNumber() >= min && it.imapNumber() <= max;
+ case NNTPNUM: if (set != null) {
+ for(int i=0; i<set.length; i+=2) if (set[i] <= it.nntpNumber() && set[i+1] >= it.nntpNumber()) return true;
+ return false; }
+ else return it.imapNumber() >= min && it.imapNumber() <= max;
+ case SENT: return (latest==null||it.cur().date.before(latest)) &&
+ (earliest==null||it.cur().date.after(earliest));
+ case ARRIVAL: return (latest == null || it.cur().arrival.before(latest)) &&
+ (earliest == null || it.cur().arrival.after(earliest));
+ case HEADER: return it.cur().headers.get(key) != null &&
+ ((String)it.cur().headers.get(key)).toLowerCase().indexOf(text.toLowerCase()) != -1;
+ case DELETED: return (it.getFlags() & Mailbox.Flag.DELETED) !=0;
+ case SEEN: return (it.getFlags() & Mailbox.Flag.SEEN)!=0;
+ case FLAGGED: return (it.getFlags() & Mailbox.Flag.FLAGGED)!=0;
+ case DRAFT: return (it.getFlags() & Mailbox.Flag.DRAFT)!=0;
+ case ANSWERED: return (it.getFlags() & Mailbox.Flag.ANSWERED)!=0;
+ case RECENT: return (it.getFlags() & Mailbox.Flag.RECENT)!=0;
+
+ // FIXME: super inefficient
+ case BODY: throw new RuntimeException("BODY searches are not supported because they are slow");
+ case FULL: throw new RuntimeException("FULL searches are not supported because they are slow");
+ case SIZE: throw new RuntimeException("SIZE searches are not supported because Adam is lame");
+ //return it.cur().size() >= min && it.cur().size() <= max;
+
+ default: throw new Error("this should not happen");
+ }
+ }
}