53ce9458719e80044c7bbfa2973621968f5a63ab
[org.ibex.mail.git] / src / org / ibex / mail / target / Mailbox.java
1 package org.ibex.mail.target;
2 import org.ibex.mail.*;
3 import org.ibex.util.*;
4 import org.ibex.mail.*;
5 import java.io.*;
6 import java.net.*;
7 import java.util.*;
8 import java.text.*;
9
10 // FIXME: appallingly inefficient
11 public class Mailbox extends Target {
12
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;
17     static {
18         try {
19             root = new FileBased(STORAGE_ROOT + File.separatorChar);
20             transcript = new Transcript(STORAGE_ROOT + File.separatorChar + "transcript");
21         } catch (Exception e) {
22             e.printStackTrace();
23         }
24     }
25
26     public int uidvalidity;
27     public int uidnext;
28
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; }
43
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"); }
61     /*
62     public static class Mailbox extends Mailbox {
63         String user;
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);
68             return ret;
69         }
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);
77             pw.flush();
78             message.dump(fos);
79             fos.close();
80             return -1;
81         }
82     }
83     */
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 {
86         private String path;
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;
90
91         /** returns a message identifier */
92         public synchronized int add(Message message) throws MailException {
93             try {
94                 File today = new File(path + File.separatorChar + (new SimpleDateFormat("yy-MMM-dd").format(new Date())));
95                 today.mkdirs();
96                 
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);
101                     } else {
102                         lastTime = time;
103                     }
104                 }
105                 
106                 File target = new File(today.getPath() + File.separatorChar + time + ".txt");
107                 OutputStream os = new FileOutputStream(target);
108                 message.dump(os);
109                 os.close();
110                 return -1;
111             } catch (IOException e) { throw new MailException.IOException(e); }
112         }
113     }
114
115     public static class FileBased extends Mailbox {
116         private String path;
117         private FileBased(String path) throws MailException { new File(this.path = path).mkdirs(); }
118         public Mailbox slash(String name, boolean create) throws MailException {
119             // FIXME: create
120             return new FileBased(path + "/" + name);
121         }
122
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++) {
127                 try {
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));
131                     j--;
132                     int[] newret = new int[ret.length - 1];
133                     System.arraycopy(ret, 0, newret, 0, newret.length);
134                     ret = newret;
135                 }
136             }
137             return ret;
138         }
139
140         /** returns a message identifier */
141         public synchronized int add(Message message) throws MailException {
142             try {
143                 int[] all = list();
144                 int max = 0;
145                 for(int i=0; i<all.length; i++) max = Math.max(max, all[i]);
146                 int target = max++;
147                 File f = new File(path + File.separatorChar + max + ".-");
148                 FileOutputStream fo = new FileOutputStream(f);
149                 message.dump(fo);
150                 fo.close();
151                 f.renameTo(new File(path + File.separatorChar + max + "."));
152                 return target;
153             } catch (IOException e) { throw new MailException.IOException(e); }
154         }
155
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()));
159             //try {
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
163                 //return ret;
164             //return null;
165                 /*
166             } catch (MailException.Malformed malf) {
167                 Log.error(this, "This should never happen");
168                 Log.error(this, malf);
169                 return null;
170             }
171                 */
172             return null;
173         }
174
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");
178         }
179
180     }
181
182 }