1 package org.ibex.mail.target;
2 import org.ibex.mail.*;
3 import org.ibex.util.*;
4 import org.ibex.mail.*;
10 // FIXME: appallingly inefficient
11 public class Mailbox extends Target {
13 private static final String STORAGE_ROOT =
14 System.getProperty("ibex.mail.root", File.separatorChar + "var" + File.separatorChar + "org.ibex.mail");
15 public static FileBased root = null;
16 public static Transcript transcript = null;
19 root = new FileBased(STORAGE_ROOT + File.separatorChar);
20 transcript = new Transcript(STORAGE_ROOT + File.separatorChar + "transcript");
21 } catch (Exception e) {
26 public int uidvalidity;
29 public void setDeleted(int i, boolean b) { }
30 public void setSeen(int i, boolean b) { }
31 public void setFlagged(int i, boolean b) { }
32 public void setDraft(int i, boolean b) { }
33 public void setAnswered(int i, boolean b) { }
34 public void setRecent(int i, boolean b) { }
35 public boolean deleted(int i) { return false; }
36 public boolean seen(int i) { return false; }
37 public boolean flagged(int i) { return false; }
38 public boolean draft(int i) { return false; }
39 public boolean answered(int i) { return false; }
40 public boolean recent(int i) { return false; }
41 public int uid(int i) { return -1; }
42 public int uid(Message m) { return -1; }
44 public void moveAllMessagesTo(Mailbox m) throws MailException { throw new Error("moveAllMessagesTo() not implemented"); }
45 public String getName() throws MailException { throw new Error("Mailbox.getName() not implemented"); }
46 public void rename(String newName) throws MailException { throw new Error("Mailbox.rename() not implemented"); }
47 public void destroy() throws MailException { throw new Error("Mailbox.destroy() not implemented"); }
48 public void accept(Message m) throws MailException { add(m); }
49 public Mailbox slash(String name) throws MailException { return slash(name, false); }
50 public Mailbox slash(String name, boolean create) throws MailException {
51 throw new Error(this.getClass().getName() + " does not support the slash() method"); }
52 public int[] list() { throw new Error(this.getClass().getName() + " does not support the list() method"); }
53 public int add(Message message) throws MailException {
54 throw new Error(this.getClass().getName() + " does not support the add() method"); }
55 public int delete(Message message) throws MailException {
56 throw new Error(this.getClass().getName() + " does not support the delete() method"); }
57 public Message get(int messagenum) throws MailException {
58 throw new Error(this.getClass().getName() + " does not support the get() method"); }
59 public Message[] query(int maxResults) {
60 throw new Error(this.getClass().getName() + " does not support the query() method"); }
62 public static class Mailbox extends Mailbox {
64 private static Hashtable cache = new Hashtable();
65 public static Mailbox getForUser(String user) {
66 Mailbox ret = (Mailbox)cache.get(user);
67 if (ret == null) ret = new Mailbox(user);
70 Mailbox(String user) { this.user = user; }
71 public Mailbox slash(String name) throws MailException {
72 throw new Error(this.getClass().getName() + " does not support the slash() method"); }
73 public synchronized int add(Message message) throws MailException {
74 FileOutputStream fos = new FileOutputStream("/var/mail/" + user, true);
75 PrintWriter pw = new PrintWriter(new OutputStreamWriter(fos));
76 pw.println("From " + message.envelopeFrom);
84 /** a fast-write, slow-read place to stash all messages we touch -- in case of a major f*ckup */
85 public static class Transcript extends Mailbox {
87 public Transcript(String path) throws MailException { new File(this.path = path).mkdirs(); }
88 private static String lastTime = null;
89 private static int lastCounter = 0;
91 /** returns a message identifier */
92 public synchronized int add(Message message) throws MailException {
94 File today = new File(path + File.separatorChar + (new SimpleDateFormat("yy-MMM-dd").format(new Date())));
97 String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
98 synchronized (Transcript.class) {
99 if (lastTime != null && lastTime.equals(time)) {
100 time += "." + (++lastCounter);
106 File target = new File(today.getPath() + File.separatorChar + time + ".txt");
107 OutputStream os = new FileOutputStream(target);
111 } catch (IOException e) { throw new MailException.IOException(e); }
115 public static class FileBased extends Mailbox {
117 private FileBased(String path) throws MailException { new File(this.path = path).mkdirs(); }
118 public Mailbox slash(String name, boolean create) throws MailException {
120 return new FileBased(path + "/" + name);
123 public int[] list() {
124 String[] names = new File(path).list();
125 int[] ret = new int[names.length];
126 for(int i=0, j=0; j<ret.length; i++, j++) {
128 ret[j] = Integer.parseInt(names[i].substring(0, names[i].length() - 1));
129 } catch (NumberFormatException nfe) {
130 Log.warn(FileBased.class, "NumberFormatException: " + names[i].substring(0, names[i].length() - 1));
132 int[] newret = new int[ret.length - 1];
133 System.arraycopy(ret, 0, newret, 0, newret.length);
140 /** returns a message identifier */
141 public synchronized int add(Message message) throws MailException {
145 for(int i=0; i<all.length; i++) max = Math.max(max, all[i]);
147 File f = new File(path + File.separatorChar + max + ".-");
148 FileOutputStream fo = new FileOutputStream(f);
151 f.renameTo(new File(path + File.separatorChar + max + "."));
153 } catch (IOException e) { throw new MailException.IOException(e); }
156 public Message get(int messagenum) throws MailException {
157 File f = new File(path + File.separatorChar + messagenum + ".");
158 if (!f.exists()) throw new MailException.IOException(new FileNotFoundException(f.toString()));
160 // FIXME: need to store envelope from/to
161 //Message ret = new Message(new LineReader(new InputStreamReader(new FileInputStream(f))));
162 // FIXME: set answered/read/etc here
166 } catch (MailException.Malformed malf) {
167 Log.error(this, "This should never happen");
168 Log.error(this, malf);
175 // query types: stringmatch (headers, body), header element, deletion status, date range, message size
176 public Message[] query(int maxResults) {
177 throw new RuntimeException("FileBased.query() not implemented yet");