(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");
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; }
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() { }
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();
}
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)); }
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 //////////////////////////////////////////////////////////////////////////////
}
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 = "(" +
}
}
synchronized(Outgoing.class) {
- spool.add(m);
+ spool.insert(m, Mailbox.Flag.defaultFlags);
Outgoing.class.notifyAll();
}
}
// 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();
};
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());
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++) {
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);
/** 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);
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()); }
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"); }
}
}
*/
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;
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 {
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) { }
}
}
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 {
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); }
}
}
- 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;
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; }
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; }
}
}
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(); }
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; }
}
}
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+"");
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 {