1 package org.ibex.mail.store;
2 import org.ibex.util.*;
6 // FIXME: appallingly inefficient
7 public class MessageStore {
9 private final String STORAGE_ROOT = System.getProperty("ibex.mail.root",
10 File.separatorChar + "var" + File.separatorChar + "org.ibex.mail");
12 //public final FileBased root = new FileBased(STORAGE_ROOT + File.separatorChar);
13 public final FileBased transcript = new FileBased(STORAGE_ROOT + File.separatorChar + "transcript");
15 public MessageStore slash(String name) {
16 throw new Error(this.getClass().getName() + " does not support the slash() method"); }
17 public int[] list() { throw new Error(this.getClass().getName() + " does not support the list() method"); }
18 public int add(StoredMessage message) throws IOException {
19 throw new Error(this.getClass().getName() + " does not support the add() method"); }
20 public StoredMessage get(int messagenum) throws IOException {
21 throw new Error(this.getClass().getName() + " does not support the get() method"); }
22 public StoredMessage[] query(int maxResults) {
23 throw new Error(this.getClass().getName() + " does not support the query() method"); }
25 /** a fast-write, slow-read place to stash all messages we touch -- in case of a major f*ckup */
26 public static class Transcript {
28 public Transcript(String path) throws IOException { new File(this.path = path).mkdirs(); }
29 private static String lastTime = null;
30 private static int lastCounter = 0;
32 /** returns a message identifier */
33 public synchronized int add(StoredMessage message) throws IOException {
34 File today = new File(path + File.separatorChar + (new SimpleDateFormat("yyyyy.MMMMM.dd").format(new Date())));
37 String time = new SimpleDateFormat("").format(new Date("hh.mm.ss"));
38 synchronized (Transcript.class) {
39 if (lastTime != null && lastTime.equals(time)) {
40 time += "." + (++lastCounter);
46 File target = new File(today.getPath() + File.separatorChar() + time + ".txt");
47 String msg = message.dumpStoredForm();
48 OutputStream os = new FileOutputStream(target);
49 os.write(msg.getBytes("UTF-8")); // FIXME: right?
55 public static FileBased extends MessageStore {
57 private FileBased(String path) throws IOException { new File(this.path = path).mkdirs(); }
58 public FileBased slash(String name) { return new FileBased(path + "/" + name); }
61 String[] names = new File(path).list();
62 int[] ret = new int[names.length];
63 for(int i=0, j=0; j<ret.length; i++, j++) {
65 ret[j] = Integer.parseInt(names[i].substring(0, names[i].length - 1));
66 } catch (NumberFormatException nfe) {
67 Log.warn(FileBased.class, "NumberFormatException: " + names[i].substring(0, names[i].length - 1));
69 int[] newret = new int[ret.length - 1];
70 System.arrayCopy(ret, 0, newret, 0, newret.length);
77 /** returns a message identifier */
78 public synchronized int add(StoredMessage message) throws IOException {
81 for(int i=0; i<all.length; i++) max = Math.max(max, all[i]);
83 File f = new File(path + File.separatorChar + max + ".-");
84 FileOutputStream fo = new FileOutputStream(f);
87 f.renameTo(path + File.separatorChar + max + ".");
91 public StoredMessage get(int messagenum) throws IOException {
92 File f = new File(path + File.separatorChar + messagenum + ".");
93 if (!f.exists()) throw new FileNotFoundException(f);
94 return StoredMessage.undump(new FileInputStream(f));
97 // query types: stringmatch (headers, body), header element, deletion status, date range, message size
98 public StoredMessage[] query(int maxResults) {
99 throw new RuntimeException("FileBased.query() not implemented yet");