1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
7 import org.ibex.mail.target.*;
8 import org.ibex.util.*;
11 * [immutable] This class encapsulates a query against a mailbox.
13 * The default implementation of Mailbox.query() simply retrieves
14 * each message and calls Query.match() on it to filter out any
15 * messages which do not match.
17 * Production-quality Mailbox implementations will want to inspect
18 * the Query object passed to Mailbox.query() to perform more
23 public static Query not(Query q) { return new Query(NOT, new Query[] { q },0,0,0,null,null,null,null,null); }
24 public static Query and(Query q1, Query q2) { return new Query(AND,new Query[]{q1,q2},0,0,0,null,null,null,null,null); }
25 public static Query and(Query[] q) { return new Query(AND, q,0,0,0,null, null, null, null, null ); }
26 public static Query or(Query q1, Query q2) { return new Query(OR,new Query[] {q1,q2},0,0,0,null,null, null, null, null); }
27 public static Query or(Query[] q) { return new Query(OR, q, 0, 0, 0, null, null, null, null, null); }
28 public static Query uid(int min, int max) { return new Query(UID, null, min, max, 0, null, null, null, null, null); }
29 public static Query messagenum(int min,int max) { return new Query(NUM,null,min,max,0,null,null,null,null, null); }
30 public static Query sent(Date e, Date l) { return new Query(SENT,null,0,0,0,null,null,e,l,null); }
31 public static Query arrival(Date e, Date l) { return new Query(ARRIVAL,null,0,0,0,null,null, e,l,null);}
32 public static Query header(String k, String v) { return new Query(HEADER, null, 0, 0, 0, k, v, null, null, null);}
33 public static Query size(int min, int max) { return new Query(SIZE, null, min, max, 0, null, null, null, null, null);}
34 public static Query body(String text) { return new Query(BODY, null, 0, 0, 0, null, text, null, null, null);}
35 public static Query full(String text) { return new Query(FULL, null, 0, 0, 0, null, text, null, null, null);}
36 public static Query uid(int[] set) { return new Query(UID, null, 0 ,0 ,0, null, null, null, null, set);}
37 public static Query num(int[] set) { return new Query(NUM, null, 0 ,0 ,0, null, null, null, null, set);}
38 public static Query all() { return new Query(ALL, null, 0, 0, 0, null, null, null, null, null); }
39 public static Query deleted() { return new Query(DELETED, null, 0, 0, 0, null, null, null, null, null); }
40 public static Query seen() { return new Query(SEEN, null, 0, 0, 0, null, null, null, null, null); }
41 public static Query flagged() { return new Query(FLAGGED, null, 0, 0, 0, null, null, null, null, null); }
42 public static Query draft() { return new Query(DRAFT, null, 0, 0, 0, null, null, null, null, null); }
43 public static Query answered() { return new Query(ANSWERED, null, 0, 0, 0, null, null, null, null, null); }
44 public static Query recent() { return new Query(RECENT, null, 0, 0, 0, null, null, null, null, null); }
45 public static Query set(boolean uid, int[] set) { return uid ? uid(set) : num(set); }
47 private Query(int type, Query[] q,int min,int max, int flags, String key, String text, Date earliest, Date latest, int[] set) {
48 this.type = type; this.q = q; this.min = min; this.max = max; this.flags = flags; this.key = key; this.text = text;
49 this.earliest = earliest; this.latest = latest; this.set = set; }
51 public static final int ALL = 0;
52 public static final int NOT = 1;
53 public static final int AND = 2;
54 public static final int OR = 3;
55 public static final int UID = 4;
56 public static final int SENT = 5;
57 public static final int ARRIVAL = 6;
58 public static final int HEADER = 7;
59 public static final int SIZE = 8;
60 public static final int BODY = 9;
61 public static final int FULL = 10;
62 public static final int NUM = 11;
63 public static final int DELETED = 12;
64 public static final int SEEN = 13;
65 public static final int FLAGGED = 14;
66 public static final int DRAFT = 15;
67 public static final int ANSWERED = 16;
68 public static final int RECENT = 17;
70 public final int type;
71 public final Query[] q;
74 public final int flags;
75 public final String key;
76 public final String text;
77 public final Date earliest;
78 public final Date latest;
79 public final int[] set;
81 public boolean match(Mailbox.Iterator it) {
83 case ALL: return true;
84 case NOT: return !q[0].match(it);
85 case OR: for(int i=0; i<q.length; i++) if (q[i].match(it)) return true; return false;
86 case AND: for(int i=0; i<q.length; i++) if (!q[i].match(it)) return false; return true;
87 case UID: if (set != null) {
88 for(int i=0; i<set.length; i+=2)
89 if (set[i] <= it.uid() && set[i+1] >= it.uid()) return true;
91 else return it.uid() >= min && it.uid() <= max;
92 case NUM: if (set != null) {
93 for(int i=0; i<set.length; i+=2) if (set[i] <= it.num() && set[i+1] >= it.num()) return true;
95 else return it.num() >= min && it.num() <= max;
96 case SENT: return (latest==null||it.cur().date.before(latest)) &&
97 (earliest==null||it.cur().date.after(earliest));
98 case ARRIVAL: return (latest == null || it.cur().arrival.before(latest)) &&
99 (earliest == null || it.cur().arrival.after(earliest));
100 case SIZE: return it.cur().size() >= min && it.cur().size() <= max;
101 case HEADER: return it.cur().headers.gets(key) != null &&
102 ((String)it.cur().headers.gets(key)).toLowerCase().indexOf(text.toLowerCase()) != -1;
103 case BODY: return it.cur().body.toLowerCase().indexOf(text.toLowerCase()) != -1;
104 case FULL: return it.cur().body.toLowerCase().indexOf(text.toLowerCase()) != -1 ||
105 it.cur().headers.raw.indexOf(text) != -1;
106 case DELETED: return it.deleted();
107 case SEEN: return it.seen();
108 case FLAGGED: return it.flagged();
109 case DRAFT: return it.draft();
110 case ANSWERED: return it.answered();
111 case RECENT: return it.recent();
112 default: throw new Error("this should not happen");