it compiles
[org.ibex.mail.git] / src / org / ibex / mail / protocol / IMAP.java
index 0db26a2..2806811 100644 (file)
@@ -76,46 +76,58 @@ public class IMAP extends MessageProtocol {
         public void list(Mailbox m, String s) { star("LIST () \".\" INBOX"); ok("LIST completed"); } // FIXME
 
         private boolean auth(String user, String pass) { /* FEATURE */ return user.equals("megacz") && pass.equals(""); }
-        public void copy(int[] set, Mailbox target) { for(int i=0; i<set.length; i++) target.add(selected.get(set[i])); }
+        public void copy(final Query q, final Mailbox target) {
+            for(Mailbox.Iterator it = selected.iterator(q); it.next(); ) { target.add(it.cur()); } }
         public void login(String user, String password) {if (!auth(user,password))throw new Exn.No("Liar, liar, pants on fire."); }
         public void capability() { star("CAPABILITY IMAP4rev1"); ok("Completed"); }
         public void noop() { ok("Completed"); }
         public void logout() { star("BYE LOGOUT received"); ok("Completed"); }
-        public void delete(Mailbox m) { if (!m.getName().toLowerCase().equals("inbox")) m.destroy(); ok("Completed"); }
+
+        // FIXME
+        public void delete(Mailbox m) { /*if (!m.getName().toLowerCase().equals("inbox")) m.destroy(); ok("Completed");*/ }
+
         public void subscribe(String[] args) { ok("SUBSCRIBE ignored"); }
         public void unsubscribe(String[] args) { ok("UNSUBSCRIBE ignored"); }
         public void check() { ok("CHECK ignored"); }
-        public void create(String mailbox){if(!mailbox.endsWith(".")&&!mailbox.equalsIgnoreCase("inbox"))getMailbox(mailbox,true);}
+
+        // FIXME
+        public void create(String mailbox){/*if(!mailbox.endsWith(".")&&!mailbox.equalsIgnoreCase("inbox"))getMailbox(mailbox,true);*/}
+
+        // FIXME
         public void rename(Mailbox from, String to) {
+            /*
             if (from.getName().equalsIgnoreCase("inbox")) from.moveAllMessagesTo(getMailbox(to, true));
             else if (to.equalsIgnoreCase("inbox"))      { from.moveAllMessagesTo(getMailbox(to, true)); from.destroy(); }
-            else from.rename(to);
+            else*/ from.rename(to);
         }
 
-        public void status(Mailbox m, Token[] attrs) {
-            int[] list = m.list();
-            int recent = 0, unseen = 0;
-            for(int i=0; i<list.length; i++) { if (!m.seen(i)) unseen++; if (m.recent(i)) recent++; }
+        public void status(final Mailbox m, Token[] attrs) {
+            int count0 = 0, count1 = 0, count2 = 0;
+            for(Mailbox.Iterator it = m.iterator(); it.next(); ) {
+                if (!it.seen()) count0++;
+                if (it.recent()) count1++;
+                count2++;
+            }
             String response = "";
             for(int i=0; i<attrs.length; i++) {
                 String s = attrs[i].atom();
-                if (s.equals("MESSAGES"))    response += "MESSAGES "    + list.length;
-                if (s.equals("RECENT"))      response += "RECENT "      + recent;
-                if (s.equals("UIDNEXT"))     response += "UNSEEN "      + unseen;
-                if (s.equals("UIDVALIDITY")) response += "UIDVALIDITY " + m.uidvalidity;
-                if (s.equals("UNSEEN"))      response += "UIDNEXT "     + m.uidnext;
+                if (s.equals("MESSAGES"))    response += "MESSAGES "    + count2;
+                if (s.equals("RECENT"))      response += "RECENT "      + count0;
+                if (s.equals("UIDNEXT"))     response += "UNSEEN "      + count1;
+                if (s.equals("UIDVALIDITY")) response += "UIDVALIDITY " + m.uidValidity();
+                if (s.equals("UNSEEN"))      response += "UIDNEXT "     + m.uidNext();
             }
             star("STATUS " + m.getName() + " (" + response + ")");
         }
 
         public void select(String mailbox, boolean examineOnly) {
             selected = getMailbox(mailbox, false);
-            star(selected.list().length + " EXISTS");
+            star(selected.count(Query.all()) + " EXISTS");
             int recent = 0;
-            int[] list = selected.list(); for(int i=0; i<list.length; i++) if (selected.recent(list[i])) recent++;
+            for(Mailbox.Iterator it = selected.iterator(); it.next(); ) { if (it.recent()) recent++; }
             star(recent + " RECENT");
             //star("OK [UNSEEN 12] Message 12 is first unseen");    FEATURE
-            star("OK [UIDVALIDITY " + selected.uidvalidity + "] UIDs valid");
+            star("OK [UIDVALIDITY " + selected.uidValidity() + "] UIDs valid");
             star("FLAGS (\\Answered \\Flagged \\Deleted \\Seen \\Draft)");
             // FEATURE: READ-WRITE / READ-ONLY
             ok((examineOnly ? "EXAMINE" : "SELECT") + " completed");
@@ -128,15 +140,12 @@ public class IMAP extends MessageProtocol {
             ok("CLOSE completed");
         }
 
-        public void expunge(boolean examineOnly, boolean silent) {
+        public void expunge(final boolean examineOnly, final boolean silent) {
             if (selected == null) throw new Exn.Bad("no mailbox selected");
-            int[] messages = selected.list();
-            for(int i=0; i<messages.length; i++) {
-                Message m = selected.get(messages[i]);
-                if (selected.deleted(messages[i])) {
-                    if (!silent) star(selected.uid(m) + " EXPUNGE");
-                    if (!examineOnly) selected.delete(m);
-                }
+            for(Mailbox.Iterator it = selected.iterator(); it.next();) {
+                if (!it.deleted()) return;
+                if (!silent) star(it.uid() + " EXPUNGE");
+                if (!examineOnly) it.delete();
             }
             if (!silent) ok("EXPUNGE completed");
         }
@@ -156,7 +165,7 @@ public class IMAP extends MessageProtocol {
             }
         }
 
-        public void fetch(int[] set, Token t) {
+        public void fetch(Query q, Token t) {
             Token[] tl = null;
             int start = -1, end = -1;
             boolean peek = false, fast = false, all = false, full = false;
@@ -166,8 +175,8 @@ public class IMAP extends MessageProtocol {
             else if (t.atom().equals("FAST")) fast = true;
             // FEATURE: range requests
             StringBuffer reply = new StringBuffer();
-            for(int j=0; j<set.length; j++) {
-                Message m = selected.get(set[j]);
+            for(Mailbox.Iterator it = selected.iterator(q); it.next(); ) {
+                Message m = it.cur();
                 for (int i=0; i<tl.length; i++) {
                     String s = tl[i].atom();
                     if (s.startsWith("BODY.PEEK"))                 { peek = true; s = "BODY" + s.substring(9); }
@@ -183,14 +192,14 @@ public class IMAP extends MessageProtocol {
                         start = Integer.parseInt(range);
                     }
                     if (s.equals("ENVELOPE") || all || full)          reply.append("ENVELOPE " + envelope(m) + " ");
-                    if (s.equals("FLAGS") || full || all || fast)  reply.append("FLAGS (" + flags(selected, set[j]) + ") ");
+                    if (s.equals("FLAGS") || full || all || fast)  reply.append("FLAGS (" + flags(it) + ") ");
                     if (s.equals("INTERNALDATE") || full || all || fast) reply.append("INTERNALDATE "+quotify(m.arrival)+" ");
                     if (s.equals("RFC822.SIZE") || full || all || fast) reply.append("RFC822.SIZE " + m.rfc822size() + " ");
                     if (s.equals("RFC822.HEADER") || s.equals("BODY[HEADER]"))
                         { reply.append("BODY[HEADER] {" + m.allHeaders.length() + "}\r\n"); reply.append(m.allHeaders); }
                     if (s.equals("RFC822")||s.equals("RFC822.TEXT")||s.equals("BODY")||s.equals("BODY[]")||s.equals("TEXT")||full)
                         { reply.append("BODY[TEXT] {" + m.body.length() + "}\r\n"); reply.append(m.body); }
-                    if (s.equals("UID"))                        reply.append("UID " + selected.uid(set[j]));
+                    if (s.equals("UID"))                        reply.append("UID " + it.uid());
                     if (s.equals("MIME"))                       throw new Exn.No("FETCH BODY.MIME not supported");
                     if (s.startsWith("BODY[HEADER.FIELDS"))     throw new Exn.No("partial headers not supported");
                     if (s.startsWith("BODY[HEADER.FIELDS.NOT")) throw new Exn.No("partial headers not supported");
@@ -198,32 +207,26 @@ public class IMAP extends MessageProtocol {
                         reply.append("(\"TEXT\" \"PLAIN\" (\"CHARSET\" \"US-ASCII\") NIL NIL \"7BIT\" " +
                                      m.rfc822size()+" "+ m.lines +")");
                 }
-                star(set[j] + " FETCH (" + reply.toString() + ")");
+                star(it.num() + " FETCH (" + reply.toString() + ")");
                 // FEATURE set seen flag if not BODY.PEEK
             }
         }
 
-        public void store(int[] messages, String what, Token[] flags) {
-            for(int i=0; i<messages.length; i++) {
-                Message m = selected.get(messages[i]);
+        public void store(Query q, String what, Token[] flags) {
+            for(Mailbox.Iterator it = selected.iterator(q); it.next(); ) {
+                Message m = it.cur();
                 if (what.charAt(0) == 'F') {
-                    selected.setDeleted(messages[i], false);
-                    selected.setSeen(messages[i], false);
-                    selected.setFlagged(messages[i], false);
-                    selected.setDraft(messages[i], false);
-                    selected.setAnswered(messages[i], false);
-                    selected.setRecent(messages[i], false);
-                }
+                    it.deleted(false); it.seen(false); it.flagged(false); it.draft(false); it.answered(false); it.recent(false); }
                 for(int j=0; j<flags.length; j++) {
                     String flag = flags[j].flag();
-                    if (flag.equals("Deleted"))  selected.setDeleted(messages[i], what.charAt(0) != '-');
-                    if (flag.equals("Seen"))     selected.setSeen(messages[i], what.charAt(0) != '-');
-                    if (flag.equals("Flagged"))  selected.setFlagged(messages[i], what.charAt(0) != '-');
-                    if (flag.equals("Draft"))    selected.setDraft(messages[i], what.charAt(0) != '-');
-                    if (flag.equals("Answered")) selected.setAnswered(messages[i], what.charAt(0) != '-');
-                    if (flag.equals("Recent"))   selected.setRecent(messages[i],  what.charAt(0) != '-');
+                    if (flag.equals("Deleted"))  it.deleted(what.charAt(0) != '-');
+                    if (flag.equals("Seen"))     it.seen(what.charAt(0) != '-');
+                    if (flag.equals("Flagged"))  it.flagged(what.charAt(0) != '-');
+                    if (flag.equals("Draft"))    it.draft(what.charAt(0) != '-');
+                    if (flag.equals("Answered")) it.answered(what.charAt(0) != '-');
+                    if (flag.equals("Recent"))   it.recent( what.charAt(0) != '-');
                 }
-                selected.add(m);  // re-add
+                selected.add(m);  // re-add (?)
             }
         }
 
@@ -247,12 +250,12 @@ public class IMAP extends MessageProtocol {
                 else if (command.equals("APPEND"))       append(mailbox(), token()); 
                 else if (command.equals("EXAMINE"))      select(astring(), true);
                 else if (command.equals("SELECT"))       select(astring(), false);
-                else if (command.equals("COPY"))         copy(set(), mailbox());
+                else if (command.equals("COPY"))         copy(Query.set(set()), mailbox());
                 else if (command.equals("DELETE"))       delete(mailbox());
                 else if (command.equals("CHECK"))        check();
                 else if (command.equals("CREATE"))       create(astring());
-                else if (command.equals("STORE"))        store(set(), atom(), l());
-                else if (command.equals("FETCH"))        fetch(set(), token());
+                else if (command.equals("STORE"))        store(Query.set(set()), atom(), l());
+                else if (command.equals("FETCH"))        fetch(Query.set(set()), token());
                 else if (command.equals("STATUS"))       status(mailbox(), l());
                 else                                     throw new Exn.Bad("unrecognized command \"" + command + "\"");
             }
@@ -271,14 +274,14 @@ public class IMAP extends MessageProtocol {
             ret.append(")");
             return ret.toString();
         }
-        static String flags(Mailbox s, int i) {
+        static String flags(Mailbox.Iterator it) {
             return 
-                (s.deleted(i)  ? "\\Deleted "  : "") +
-                (s.seen(i)     ? "\\Seen "     : "") +
-                (s.flagged(i)  ? "\\Flagged "  : "") +
-                (s.draft(i)    ? "\\Draft "    : "") +
-                (s.answered(i) ? "\\Answered " : "") +
-                (s.recent(i)   ? "\\Recent "   : "");
+                (it.deleted()  ? "\\Deleted "  : "") +
+                (it.seen()     ? "\\Seen "     : "") +
+                (it.flagged()  ? "\\Flagged "  : "") +
+                (it.draft()    ? "\\Draft "    : "") +
+                (it.answered() ? "\\Answered " : "") +
+                (it.recent()   ? "\\Recent "   : "");
         }
         static String envelope(Message m) {
             return
@@ -317,7 +320,7 @@ public class IMAP extends MessageProtocol {
             else if (s.equals("RECENT"))     q = Query.flags(Flag.RECENT);
             else if (s.equals("SEEN"))       q = Query.flags(Flag.SEEN);
             else if (s.equals("OLD"))      { not = true; q = Query.flags(Flag.RECENT); }
-            else if (s.equals("NEW"))        q = Query.and(Query.Flag.RECENT, Query.not(Query.Flag.SEEN));
+            else if (s.equals("NEW"))        q = Query.and(Query.flags(Flag.RECENT), Query.not(Query.flags(Flag.SEEN)));
             else if (s.equals("KEYWORD"))    q = Query.header("keyword", flag());
             else if (s.equals("HEADER"))     q = Query.header(astring(), astring());
             else if (s.equals("BCC"))        q = Query.header("bcc", astring());
@@ -325,17 +328,18 @@ public class IMAP extends MessageProtocol {
             else if (s.equals("FROM"))       q = Query.header("from", astring());
             else if (s.equals("TO"))         q = Query.header("to", astring());
             else if (s.equals("SUBJECT"))    q = Query.header("subject", astring());
-            else if (s.equals("LARGER"))     q = Query.size(n(), true);
-            else if (s.equals("SMALLER"))    q = Query.size(n(), false);
-            else if (s.equals("BODY"))       q = Query.body(astring(), true, false);
-            else if (s.equals("TEXT"))       q = Query.fullText(astring(), true, true);
+            else if (s.equals("LARGER"))     q = Query.size(n(), Integer.MAX_VALUE);
+            else if (s.equals("SMALLER"))    q = Query.size(Integer.MIN_VALUE, n());
+            else if (s.equals("BODY"))       q = Query.body(astring());
+            else if (s.equals("TEXT"))       q = Query.full(astring());
             else if (s.equals("BEFORE"))     q = Query.arrival(new Date(0), date());
             else if (s.equals("SINCE"))      q = Query.arrival(date(), new Date(Long.MAX_VALUE));
             else if (s.equals("ON"))         q = null; // FIXME
             else if (s.equals("SENTBEFORE")) q = Query.sent(new Date(0), date());
             else if (s.equals("SENTSINCE"))  q = Query.sent(date(), new Date(Long.MAX_VALUE));
             else if (s.equals("SENTON"))     q = null; // FIXME
-            else if (s.equals("UID"))        q = Query.uid(set());
+            //else if (s.equals("UID"))        q = Query.uid(set());
+            // FIXME
             return q;
         }