X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fmail%2FIMAP.java;h=27e66435f993e55d26108ab11f7b5a5a79e28693;hb=0af90c1a1f14e24e1eb6790228be021b3e8e65b4;hp=4f60d0dc1194cc3ced59e3b035a68764d9bfffba;hpb=bea75eed0419e5888bda70d9cb1f3951a1a6d510;p=org.ibex.mail.git diff --git a/src/org/ibex/mail/IMAP.java b/src/org/ibex/mail/IMAP.java index 4f60d0d..27e6643 100644 --- a/src/org/ibex/mail/IMAP.java +++ b/src/org/ibex/mail/IMAP.java @@ -102,7 +102,7 @@ public class IMAP { Mailbox inbox = null; Mailbox selected = null; - MailboxTree root = null; + MailTree root = null; Mailbox selected() { if (selected == null) throw new Bad("no mailbox selected"); return selected; } final Login auth; final Client client; @@ -110,16 +110,28 @@ public class IMAP { public MailboxWrapper(Login auth, Client c) { this.auth=auth; this.client=c;} public void setClient(IMAP.Client client) { } + private String dirname(String name) { return name.substring(0, name.lastIndexOf(sep)); } + private String basename(String name) { return name.substring(name.lastIndexOf(sep)+1); } private Mailbox mailbox(String name, boolean create) { return mailbox(name, create, true); } private Mailbox mailbox(String name, boolean create, boolean throwexn) { if (name.equalsIgnoreCase("inbox")) return inbox; - MailboxTree m = root; + if (name.equalsIgnoreCase("trash")) name = "trash"; + MailTree mt = mailboxTree(name, create, throwexn); + /* FIXME: throw throwexn here + if (mt==null || mt.getMailbox()==null) + Log.error("mt==null", name); + */ + return mt==null ? null : mt.getMailbox(); + } + private MailTree mailboxTree(String name, boolean create) { return mailboxTree(name, create, true); } + private MailTree mailboxTree(String name, boolean create, boolean throwexn) { + MailTree m = root; for(StringTokenizer st = new StringTokenizer(name, sep + ""); st.hasMoreTokens();) if ((m = m.slash(st.nextToken(), create)) == null) { if (throwexn) throw new Server.No("no such mailbox " + name); return null; } - return m.getMailbox(); + return m; } // FEATURE: not accurate when a wildcard and subsequent non-wildcards both match a single component @@ -133,13 +145,13 @@ public class IMAP { if (ref.length() == 0) { client.list(sep, start, lsub, false); return; } while (start.endsWith(""+sep)) start = start.substring(0, start.length() - 1); if (ref.endsWith("%")) ref = ref + sep; - String[] children = (start.length() == 0 ? root : mailbox(start, false)).children(); + String[] children = (start.length() == 0 ? root : mailboxTree(start, false)).children(); for(int i=0; i 0 ? sep+"" : "") + s; if (mailbox(kid, false) == null) continue; - Mailbox phant = mailbox(kid, false, false); + MailTree phant = mailboxTree(kid, false, false); if (phant != null) { - boolean phantom = phant.phantom(); + boolean phantom = phant.getMailbox()==null; while(true) { if (pre.length() == 0) { if (s.length() == 0) client.list(sep, kid, lsub, phantom); @@ -174,8 +186,20 @@ public class IMAP { 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 delete(String m0) { mailboxTree(dirname(m0),false).rmdir(basename(m0)); } + + public void rename(String from0, String to) { + Mailbox from = mailbox(from0, false); + if (from.equals(inbox)) { from.copy(Query.all(), mailbox(to, true)); } + else if (to.equalsIgnoreCase("inbox")) { from.copy(Query.all(), mailbox(to, true)); delete(from0); } + else mailboxTree(dirname(from0), false) + .rename(dirname(from0), + mailboxTree(dirname(to), + true /* required by IMAP */), + basename(to)); + } + public void create(String m) { mailbox(m, true, false); } public void append(String m,int f,Date a,String b) { try { // FIXME: more efficient streaming here? @@ -229,15 +253,10 @@ public class IMAP { } } - public void rename(String from0, String to) { - Mailbox from = mailbox(from0, false); - if (from.equals(inbox)) { from.copy(Query.all(), mailbox(to, true)); } - else if (to.equalsIgnoreCase("inbox")) { from.copy(Query.all(), mailbox(to, true)); from.destroy(false); } - else from.rename(to); - } public void fetch(Query q, int spec, String[] headers, int start, int end, boolean uid) { for(Mailbox.Iterator it = selected().iterator(q); it.next(); ) { - Message message = ((spec & (BODYSTRUCTURE | ENVELOPE | INTERNALDATE | FIELDS | FIELDSNOT | RFC822 | + Message message = + ((spec & (BODYSTRUCTURE | ENVELOPE | INTERNALDATE | FIELDS | FIELDSNOT | RFC822 | RFC822TEXT | RFC822SIZE | HEADERNOT | HEADER)) != 0) ? it.cur() : null; long size = message == null ? 0 : message.getLength(); client.fetch(it.imapNumber(), it.getFlags(), (int)size, message, it.uid()); @@ -252,7 +271,7 @@ public class IMAP { public static class Listener implements Client { String selectedName = null; Mailbox inbox = null; - MailboxTree root = null; + MailTree root = null; Server api; Parser parser = null; Connection conn = null; @@ -276,8 +295,9 @@ public class IMAP { } else { Account account = (Account)ret; ((MailboxWrapper)api).root = root = account.getMailbox(IMAP.class); - ((MailboxWrapper)api).inbox = inbox = root.slash("INBOX", false).getMailbox(); - if (inbox == null) ((MailboxWrapper)api).inbox = inbox = root.getMailbox(); + MailTree ibt = root.slash("INBOX", false); + Mailbox ib = ibt==null ? null : ibt.getMailbox(); + ((MailboxWrapper)api).inbox = inbox = ib; } }