major simplifications to Iterator api
authoradam <adam@megacz.com>
Wed, 28 Feb 2007 11:03:15 +0000 (11:03 +0000)
committeradam <adam@megacz.com>
Wed, 28 Feb 2007 11:03:15 +0000 (11:03 +0000)
darcs-hash:20070228110315-5007d-96c409d8119f77ff27c9646269595587ab400dd0.gz

src/org/ibex/mail/Query.java
src/org/ibex/mail/protocol/GMail.java
src/org/ibex/mail/protocol/IMAP.java
src/org/ibex/mail/protocol/SMTP.java
src/org/ibex/mail/target/FileBasedMailbox.java
src/org/ibex/mail/target/Mailbox.java
src/org/ibex/mail/target/MailmanArchives.java
src/org/ibex/mail/target/MessageArrayMailbox.java
src/org/ibex/mail/target/SqliteJdbcMailbox.java

index 14f3e09..87837f9 100644 (file)
@@ -105,12 +105,12 @@ public class Query {
                                     (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.deleted();
-            case SEEN:       return it.seen();
-            case FLAGGED:    return it.flagged();
-            case DRAFT:      return it.draft();
-            case ANSWERED:   return it.answered();
-            case RECENT:     return it.recent();
+            case DELETED:    return it.getFlag(Mailbox.Flag.DELETED);
+            case SEEN:       return it.getFlag(Mailbox.Flag.SEEN);
+            case FLAGGED:    return it.getFlag(Mailbox.Flag.FLAGGED);
+            case DRAFT:      return it.getFlag(Mailbox.Flag.DRAFT);
+            case ANSWERED:   return it.getFlag(Mailbox.Flag.ANSWERED);
+            case RECENT:     return it.getFlag(Mailbox.Flag.RECENT);
 
             // FIXME: super inefficient
             case BODY:       throw new RuntimeException("BODY searches are not supported because they are slow");
index c43df9f..1a5d4ef 100644 (file)
@@ -127,7 +127,7 @@ public class GMail extends Account {
             for(int i=0; i<summaries.length; i++) try {
                 final Message m = summaries[i].getMessage();
                 final int num = i;
-                if (q.match(new Mailbox.Iterator() {
+                if (q.match(new Mailbox.Default.Iterator() {
                         public Message cur() { return m; }
                         public Headers head() { return m.headers; }
                         public boolean next() { return false; }
index 5b98105..848feb2 100644 (file)
@@ -172,14 +172,14 @@ public class IMAP {
 
         public void copy(Query q, String to) { copy(q, mailbox(to, false)); }
         /*  */ void copy(Query q, Mailbox to) {
-            for(Mailbox.Iterator it=selected().iterator(q);it.next();) to.add(it.cur(), it.flags() | Mailbox.Flag.RECENT); }
+            for(Mailbox.Iterator it=selected().iterator(q);it.next();) to.insert(it.cur(), it.getFlags() | Mailbox.Flag.RECENT); }
 
         public void unselect() { selected = null; }
         public void delete(String m0) { delete(mailbox(m0,false)); }
         public void delete(Mailbox m) { if (!m.equals(inbox)) m.destroy(false); else throw new Bad("can't delete inbox"); }
         public void create(String m) { mailbox(m, true, false); }
         public void append(String m,int f,Date a,String b) { try {
-            mailbox(m,false).add(Message.newMessage(new Fountain.StringFountain(b)),f|Mailbox.Flag.RECENT);
+            mailbox(m,false).insert(Message.newMessage(new Fountain.StringFountain(b)), f | Mailbox.Flag.RECENT);
         } catch (Message.Malformed e) { throw new No(e.getMessage()); } }
         public void check() { }
         public void noop() { }
@@ -208,7 +208,7 @@ public class IMAP {
             Vec.Int vec = new Vec.Int();
             for(Mailbox.Iterator it = selected().iterator(q); it.next();) {
                 vec.addElement(uid ? it.uid() : it.imapNumber());
-                it.recent(false);
+                it.setFlag(Mailbox.Flag.RECENT, false);
             }
             return vec.dump();
         }
@@ -216,18 +216,19 @@ public class IMAP {
         public void setFlags(Query q, int f, boolean uid, boolean silent)    { doFlags(q, f, uid, 0, silent); }
         public void addFlags(Query q, int f, boolean uid, boolean silent)    { doFlags(q, f, uid, 1, silent); }
         public void removeFlags(Query q, int f, boolean uid, boolean silent) { doFlags(q, f, uid, -1, silent); }
-
         private void doFlags(Query q, int flags, boolean uid, int style, boolean silent) {
             for(Mailbox.Iterator it = selected().iterator(q);it.next();) {
-                boolean recent = it.recent();
+                boolean recent = it.getFlag(Mailbox.Flag.RECENT);
                 try { throw new Exception("flags " + flags); } catch (Exception e) { Log.error(this, e); }
-                if (style == -1)     it.removeFlags(flags);
-                else if (style == 0) it.setFlags(flags);
-                else if (style == 1) it.addFlags(flags);
-                it.recent(recent);
-                if (!silent) client.fetch(it.imapNumber(), it.flags(), -1, null, it.uid());
+                for(int flag : Mailbox.Flag.all)
+                    if (style == -1)     { if ((flags & flag)!=0) it.setFlag(flag, false); }
+                    else if (style == 0) { it.setFlag(flag, ((flags & flag)!=0)); }
+                    else if (style == 1) { if ((flags & flag)!=0) it.setFlag(flag, true); }
+                it.setFlag(Mailbox.Flag.RECENT, recent);
+                if (!silent) client.fetch(it.imapNumber(), flags(it), -1, null, it.uid());
             }
-        }            
+        }
+
         public void rename(String from0, String to) {
             Mailbox from = mailbox(from0, false);
             if (from.equals(inbox))                { from.copy(Query.all(), mailbox(to, true)); }
@@ -239,12 +240,19 @@ public class IMAP {
                 Message message = ((spec & (BODYSTRUCTURE | ENVELOPE | INTERNALDATE | FIELDS | FIELDSNOT | RFC822 |
                                             RFC822TEXT | RFC822SIZE | HEADERNOT | HEADER)) != 0) ? it.cur() : null;
                 int size = message == null ? 0 : message.getLength();
-                client.fetch(it.imapNumber(), it.flags(), size, message, it.uid());
-                it.recent(false);
+                client.fetch(it.imapNumber(), flags(it), size, message, it.uid());
+                it.setFlag(Mailbox.Flag.RECENT, false);
             }
         }
     }
 
+    private static int flags(Mailbox.Iterator it) {
+        int ret = 0;
+        for(int flag : Mailbox.Flag.all)
+            if (it.getFlag(flag))
+                ret |= flag;
+        return ret;
+    }
 
     // Single Session Handler //////////////////////////////////////////////////////////////////////////////
 
@@ -782,12 +790,12 @@ public class IMAP {
             }
             static String flags(Mailbox.Iterator it) {
                 return
-                    (it.deleted()  ? "\\Deleted "  : "") +
-                    (it.seen()     ? "\\Seen "     : "") +
-                    (it.flagged()  ? "\\Flagged "  : "") +
-                    (it.draft()    ? "\\Draft "    : "") +
-                    (it.answered() ? "\\Answered " : "") +
-                    (it.recent()   ? "\\Recent "   : "");
+                    (it.getFlag(Mailbox.Flag.DELETED)  ? "\\Deleted "  : "") +
+                    (it.getFlag(Mailbox.Flag.SEEN)     ? "\\Seen "     : "") +
+                    (it.getFlag(Mailbox.Flag.FLAGGED)  ? "\\Flagged "  : "") +
+                    (it.getFlag(Mailbox.Flag.DRAFT)    ? "\\Draft "    : "") +
+                    (it.getFlag(Mailbox.Flag.ANSWERED) ? "\\Answered " : "") +
+                    (it.getFlag(Mailbox.Flag.RECENT)   ? "\\Recent "   : "");
         }
         static String flags(int flags) {
             String ret = "(" +
index af62e21..35855f1 100644 (file)
@@ -217,7 +217,7 @@ public class SMTP {
                 }
             }
             synchronized(Outgoing.class) {
-                spool.add(m);
+                spool.insert(m, Mailbox.Flag.defaultFlags);
                 Outgoing.class.notifyAll();
             }
         }
index 0a8c013..7af0194 100644 (file)
@@ -68,7 +68,15 @@ public class FileBasedMailbox extends Mailbox.Default {
         // acquire lock
         File lockfile = new File(this.path.getAbsolutePath() + slash + ".lock");
         lock = new RandomAccessFile(lockfile, "rw").getChannel().tryLock();
-        if (lock == null) throw new IOException("unable to lock FileBasedMailbox");
+        /*
+        if (lock == null) {
+            Log.warn(this, "warning: blocking waiting for a lock on " + path);
+            lock = new RandomAccessFile(lockfile, "rw").getChannel().lock();
+            if (lock == null) throw new IOException("unable to lock FileBasedMailbox: " + path);
+        }
+        lockfile.deleteOnExit();
+        */
+
         uidValidity = (int)(lockfile.lastModified() & 0xffffffff);
         uidNext = 0;
         String[] files = path.list();
@@ -104,7 +112,6 @@ public class FileBasedMailbox extends Mailbox.Default {
     };
 
     public Mailbox.Iterator  iterator()           { return new Iterator(); }
-    public synchronized void add(Message message) { add(message, Mailbox.Flag.RECENT); }
     public String[] children() {
         Vec vec = new Vec();
         String[] list = sort(path.list());
@@ -117,7 +124,7 @@ public class FileBasedMailbox extends Mailbox.Default {
 
     public int uidValidity() { return uidValidity; }
     public int uidNext() {  return uidNext; }
-    public synchronized void add(Message message, int flags) {
+    public synchronized void insert(Message message, int flags) {
         try {
             String name, fullname; File target, f;
             for(int i = uidNext; ; i++) {
@@ -126,7 +133,7 @@ public class FileBasedMailbox extends Mailbox.Default {
                 target = new File(fullname);
                 f = new File(target.getCanonicalPath() + "-");
                 if (!f.exists() && !target.exists()) break;
-                Log.error(this, "aieeee!!!! target of add() already exists: " + target.getAbsolutePath());
+                Log.error(this, "aieeee!!!! target of insert() already exists: " + target.getAbsolutePath());
             }
             Stream stream = new Stream(new FileOutputStream(f));
             message.getStream().transcribe(stream);
index dbc91bf..8ad3c14 100644 (file)
@@ -28,8 +28,8 @@ public abstract class Mailbox extends JS.Obj implements Target {
     /** phantom mailboxes merely contain others; like the alt.binaries in alt.binaries.warez */
     public abstract boolean          phantom();
     public abstract Mailbox.Iterator iterator(Query q);
-    public abstract void             add(Message message);
-    public abstract void             add(Message message, int flags);
+
+    public abstract void             insert(Message message, int flags);
     public abstract void             move(Query q, Mailbox dest);
     public abstract void             copy(Query q, Mailbox dest);
     public abstract int              count(Query q);
@@ -39,10 +39,9 @@ public abstract class Mailbox extends JS.Obj implements Target {
     public abstract Mailbox          slash(String name, boolean create);
     public abstract String[]         children();
 
-
     // Thunks ////////////////////////////////////////////////////////////////////////////
 
-    public          void             accept(Message m) { add(m); }
+    public          void             accept(Message m) { insert(m, Flag.RECENT); }
     public          Mailbox.Iterator iterator() { return iterator(Query.all()); }
 
 
@@ -55,60 +54,20 @@ public abstract class Mailbox extends JS.Obj implements Target {
     public static abstract class Default extends Mailbox {
         public Mailbox.Iterator iterator(Query q) { return new Mailbox.Iterator.QueryIterator(q, this); }
         public boolean phantom() { return false; }
-        public void copy(Query q, Mailbox dest) { for(Mailbox.Iterator it = iterator(q); it.next();) dest.add(it.cur()); }
+        public void copy(Query q, Mailbox dest) { for(Mailbox.Iterator it = iterator(q); it.next();) dest.insert(it.cur(), it.getFlags()); }
         public int count(Query q) { int count = 0; for(Mailbox.Iterator it = iterator(q); it.next();) count++; return count; }
         public void rename(String newName) { throw new MailException("not supported"); }
         public void  destroy(boolean recursive) { throw new MailException("not supported"); }
         public Mailbox slash(String name, boolean create) { return null; }
         public String[] children() { return new String[] { }; }
         public void move(Query q, Mailbox dest) {
-            for(Mailbox.Iterator it = iterator(q);it.next();) { dest.add(it.cur()); it.delete(); }
+            for(Mailbox.Iterator it = iterator(q);it.next();) { dest.insert(it.cur(), it.getFlags()); it.delete(); }
         }
         public static abstract class Iterator implements Mailbox.Iterator {
-            public boolean seen() { return false; }
-            public boolean deleted() { return false; }
-            public boolean flagged() { return false; }
-            public boolean draft() { return false; }
-            public boolean answered() { return false; }
-            public boolean recent() { return false; }
-            public void    seen(boolean on) { }
-            public void    deleted(boolean on) { }
-            public void    flagged(boolean on) { }
-            public void    draft(boolean on) { }
-            public void    answered(boolean on) { }
-            public void    recent(boolean on) { }
-            public void    set(String key, String val) { throw new MailException("not supported"); }
-            public String  get(String key) { throw new MailException("not supported"); }
             public int     nntpNumber() { throw new MailException("not supported"); }
-            public int flags() {
-                return 
-                    (deleted() ? Flag.DELETED : 0) |
-                    (seen() ? Flag.SEEN : 0) |
-                    (answered() ? Flag.ANSWERED : 0) |
-                    (draft() ? Flag.DRAFT : 0) |
-                    (recent() ? Flag.RECENT : 0);
-            }
-            public void addFlags(int flags) {
-                if ((flags & Flag.DELETED) == Flag.DELETED) deleted(true);
-                if ((flags & Flag.SEEN) == Flag.SEEN) seen(true);
-                if ((flags & Flag.FLAGGED) == Flag.FLAGGED) flagged(true);
-                if ((flags & Flag.DRAFT) == Flag.DRAFT) draft(true);
-                if ((flags & Flag.RECENT) == Flag.RECENT) recent(true);
-            }
-            public void removeFlags(int flags) {
-                if ((flags & Flag.DELETED) == Flag.DELETED) deleted(false);
-                if ((flags & Flag.SEEN) == Flag.SEEN) seen(false);
-                if ((flags & Flag.FLAGGED) == Flag.FLAGGED) flagged(false);
-                if ((flags & Flag.DRAFT) == Flag.DRAFT) draft(false);
-                if ((flags & Flag.RECENT) == Flag.RECENT) recent(false);
-            }
-            public void setFlags(int flags) {
-                if ((flags & Flag.DELETED) == Flag.DELETED) deleted(true); else deleted(false);
-                if ((flags & Flag.SEEN) == Flag.SEEN) seen(true); else seen(false);
-                if ((flags & Flag.FLAGGED) == Flag.FLAGGED) flagged(true); else flagged(false);
-                if ((flags & Flag.DRAFT) == Flag.DRAFT) draft(true); else draft(false);
-                if ((flags & Flag.RECENT) == Flag.RECENT) recent(true); else recent(false);
-            }
+            public int     getFlags() { return 0; }
+            public boolean getFlag(int flag) { return false; }
+            public void    setFlag(int flag, boolean set) { throw new RuntimeException("not implemented"); }
         }
     }
 
@@ -141,27 +100,9 @@ public abstract class Mailbox extends JS.Obj implements Target {
          */
         public abstract int     nntpNumber();
 
-        public abstract void    set(String key, String val);
-        public abstract String  get(String key);
-
-        public abstract boolean seen();
-        public abstract boolean deleted();
-        public abstract boolean flagged();
-        public abstract boolean draft();
-        public abstract boolean answered();
-        public abstract boolean recent();
-
-        public abstract void    seen(boolean on);
-        public abstract void    deleted(boolean on);
-        public abstract void    flagged(boolean on);
-        public abstract void    draft(boolean on);
-        public abstract void    answered(boolean on);
-        public abstract void    recent(boolean on);
-
-        public abstract int     flags();
-        public abstract void    addFlags(int flags);
-        public abstract void    removeFlags(int flags);
-        public abstract void    setFlags(int flags);
+        public abstract int     getFlags();
+        public abstract boolean getFlag(int flag);
+        public abstract void    setFlag(int flag, boolean set);
 
         public static class Wrapper implements Iterator {
             private Iterator it;
@@ -170,27 +111,12 @@ public abstract class Mailbox extends JS.Obj implements Target {
             public Headers head() { return it.head(); }
             public boolean next() { return it.next(); }
             public int     uid() { return it.uid(); }
-            public int     flags() { return it.flags(); }
             public int     nntpNumber() { return it.nntpNumber(); }
             public int     imapNumber() { return it.imapNumber(); }
-            public void    set(String key, String val) { it.set(key, val); }
-            public String  get(String key) { return it.get(key); }
             public void    delete() { it.delete(); }
-            public boolean seen() { return it.seen(); }
-            public boolean deleted() { return it.deleted(); }
-            public boolean flagged() { return it.flagged(); }
-            public boolean draft() { return it.draft(); }
-            public boolean answered() { return it.answered(); }
-            public boolean recent() { return it.recent(); }
-            public void    seen(boolean on) { it.seen(on); }
-            public void    deleted(boolean on) { it.deleted(on); }
-            public void    flagged(boolean on) { it.flagged(on); }
-            public void    draft(boolean on) { it.draft(on); }
-            public void    answered(boolean on) { it.answered(on); }
-            public void    recent(boolean on) { it.recent(on); }
-            public void    addFlags(int flags) { it.addFlags(flags); }
-            public void    removeFlags(int flags) { it.removeFlags(flags); }
-            public void    setFlags(int flags) { it.setFlags(flags); }
+            public int     getFlags() { return it.getFlags(); }
+            public boolean getFlag(int flag) { return it.getFlag(flag); }
+            public void    setFlag(int flag, boolean set) { it.setFlag(flag, set); }
         }
 
         class QueryIterator extends Mailbox.Iterator.Wrapper {
@@ -207,24 +133,9 @@ public abstract class Mailbox extends JS.Obj implements Target {
             public Headers head() { return null; }
             public boolean next() { return false; }
             public int     uid() { return 0; }
-            public int     flags() { return 0; }
+            public void    delete() { }
             public int     imapNumber() { return 0; }
             public int     nntpNumber() { throw new RuntimeException("this mailbox does not keep article numbers"); }
-            public void    set(String key, String val) { }
-            public String  get(String key) { return null; }
-            public void    delete() { }
-            public boolean seen() { return false; }
-            public boolean deleted() { return false; }
-            public boolean flagged() { return false; }
-            public boolean draft() { return false; }
-            public boolean answered() { return false; }
-            public boolean recent() { return false; }
-            public void    seen(boolean on) { }
-            public void    deleted(boolean on) { }
-            public void    flagged(boolean on) { }
-            public void    draft(boolean on) { }
-            public void    answered(boolean on) { }
-            public void    recent(boolean on) { }
         }
     }
 
@@ -236,6 +147,8 @@ public abstract class Mailbox extends JS.Obj implements Target {
         public static final int DRAFT    = 0x0008;
         public static final int ANSWERED = 0x0010;
         public static final int RECENT   = 0x0020;
+        public static final int[] all = new int[] { DELETED, SEEN, FLAGGED, DRAFT, ANSWERED, RECENT };
+        public static final int defaultFlags = RECENT;
     }
 
     public static class MailboxWrapper extends Mailbox {
@@ -245,8 +158,7 @@ public abstract class Mailbox extends JS.Obj implements Target {
 
         public boolean          phantom() { return m.phantom(); }
         public Mailbox.Iterator iterator(Query q) { return m.iterator(q); }
-        public void             add(Message message) { m.add(message); }
-        public void             add(Message message, int flags) { m.add(message, flags); }
+        public void             insert(Message message, int flags) { m.insert(message, flags); }
         public void             move(Query q, Mailbox dest) { m.move(q, dest); }
         public void             copy(Query q, Mailbox dest) { m.copy(q, dest); }
         public int              count(Query q) { return m.count(q); }
index d9c3621..65c874c 100644 (file)
@@ -44,8 +44,7 @@ public class MailmanArchives extends Mailbox.Default {
         }
     }
 
-    public void add(Message m) { throw new RuntimeException("not supported"); }
-    public void add(Message m, int i) { throw new RuntimeException("not supported"); }
+    public void insert(Message m, int i) { throw new RuntimeException("not supported"); }
 
     public Message[] messages;
 
@@ -55,7 +54,6 @@ public class MailmanArchives extends Mailbox.Default {
 
     private class Iterator extends Mailbox.Default.Iterator {
         int num = 0;
-
         public int     uid() { return num; }
         public int     nntpNumber() { return num; }
         public int     imapNumber() { return num; }
@@ -63,22 +61,6 @@ public class MailmanArchives extends Mailbox.Default {
         public Headers head() { return messages[num].headers; }
         public boolean next() { return (++num) < messages.length; }
         public void    delete() { }
-
-        public void    set(String key, String val) { }
-        public String  get(String key) { return null; }
-        public boolean seen() { return false; }
-        public boolean deleted() { return false; }
-        public boolean flagged() { return false; }
-        public boolean draft() { return false; }
-        public boolean answered() { return false; }
-        public boolean recent() { return false; }
-        public void    seen(boolean on) { }
-        public void    deleted(boolean on) { }
-        public void    flagged(boolean on) { }
-        public void    draft(boolean on) { }
-        public void    answered(boolean on) { }
-        public void    recent(boolean on) { }
-        public int     flags() { return 0; }
     }    
 
 }
index e733504..350f54b 100644 (file)
@@ -17,8 +17,7 @@ public class MessageArrayMailbox extends Mailbox.Default {
 
     public MessageArrayMailbox(Message[] messages) { this.messages = messages; }
 
-    public void             add(Message message) { return; }
-    public void             add(Message message, int flags) { return; }
+    public void             insert(Message message, int flags) { return; }
     public int              uidNext() { return messages.length+1; }
     public Mailbox.Iterator iterator() { return new MessageArrayMailbox.Iterator(); }
 
@@ -32,21 +31,5 @@ public class MessageArrayMailbox extends Mailbox.Default {
         public int     imapNumber()  { return position+1; }
         public void    delete() { return; }
 
-        public void    set(String key, String val) { return; }
-        public String  get(String key) { return null; }
-
-        public boolean seen() { return false; }
-        public boolean deleted() { return false; }
-        public boolean flagged() { return false; }
-        public boolean draft() { return false; }
-        public boolean answered() { return false; }
-        public boolean recent() { return true; }
-
-        public void    seen(boolean on) { return; }
-        public void    deleted(boolean on) { return; }
-        public void    flagged(boolean on) { return; }
-        public void    draft(boolean on) { return; }
-        public void    answered(boolean on) { return; }
-        public void    recent(boolean on) { return; }
     }
 }
index ccc9ccc..a0afc8f 100644 (file)
@@ -24,7 +24,9 @@ public class SqliteJdbcMailbox extends Mailbox.Default {
         catch (ClassNotFoundException e) { throw new RuntimeException(e); }
     }
 
-    public void add(Message m) {
+    public Mailbox.Iterator iterator()                      { return new SqliteJdbcIterator(); }
+    public void             insert(Message m, int flags) {
+        // FIXME: flags
         try {
             PreparedStatement add = conn.prepareStatement("insert into 'mail' values (?,?,?,?,?,?,?)");
             add.setString(1, m.messageid+"");
@@ -37,9 +39,6 @@ public class SqliteJdbcMailbox extends Mailbox.Default {
             add.executeUpdate();
         } catch (Exception e) { throw new RuntimeException(e); }
     }
-
-    public Mailbox.Iterator iterator()                      { return new SqliteJdbcIterator(); }
-    public void             add(Message message, int flags) { add(message); }
     public int              uidNext()                       { throw new RuntimeException("not supported"); }
 
     private class SqliteJdbcIterator extends Mailbox.Default.Iterator {