1 package org.ibex.mail.store;
2 import org.ibex.util.*;
3 import org.ibex.mail.*;
9 // FIXME: appallingly inefficient
10 public class MessageStore {
12 private static final String STORAGE_ROOT = System.getProperty("ibex.mail.root",
13 File.separatorChar + "var" + File.separatorChar + "org.ibex.mail");
15 //public final FileBased root = new FileBased(STORAGE_ROOT + File.separatorChar);
16 public static FileBased transcript = null;
19 transcript = new FileBased(STORAGE_ROOT + File.separatorChar + "transcript");
20 } catch (Exception e) {
25 public MessageStore slash(String name) throws IOException {
26 throw new Error(this.getClass().getName() + " does not support the slash() method"); }
27 public int[] list() { throw new Error(this.getClass().getName() + " does not support the list() method"); }
28 public int add(Message.StoredMessage message) throws IOException {
29 throw new Error(this.getClass().getName() + " does not support the add() method"); }
30 public Message.StoredMessage get(int messagenum) throws IOException {
31 throw new Error(this.getClass().getName() + " does not support the get() method"); }
32 public Message.StoredMessage[] query(int maxResults) {
33 throw new Error(this.getClass().getName() + " does not support the query() method"); }
35 /** a fast-write, slow-read place to stash all messages we touch -- in case of a major f*ckup */
36 public static class Transcript {
38 public Transcript(String path) throws IOException { new File(this.path = path).mkdirs(); }
39 private static String lastTime = null;
40 private static int lastCounter = 0;
42 /** returns a message identifier */
43 public synchronized int add(Message.StoredMessage message) throws IOException {
44 File today = new File(path + File.separatorChar + (new SimpleDateFormat("yyyyy.MMMMM.dd").format(new Date())));
47 String time = new SimpleDateFormat("").format(new Date("hh.mm.ss"));
48 synchronized (Transcript.class) {
49 if (lastTime != null && lastTime.equals(time)) {
50 time += "." + (++lastCounter);
56 File target = new File(today.getPath() + File.separatorChar + time + ".txt");
57 String msg = message.dumpStoredForm();
58 OutputStream os = new FileOutputStream(target);
59 os.write(msg.getBytes("UTF-8")); // FIXME: right?
65 public static class FileBased extends MessageStore {
67 private FileBased(String path) throws IOException { new File(this.path = path).mkdirs(); }
68 public MessageStore slash(String name) throws IOException { return new FileBased(path + "/" + name); }
71 String[] names = new File(path).list();
72 int[] ret = new int[names.length];
73 for(int i=0, j=0; j<ret.length; i++, j++) {
75 ret[j] = Integer.parseInt(names[i].substring(0, names[i].length() - 1));
76 } catch (NumberFormatException nfe) {
77 Log.warn(FileBased.class, "NumberFormatException: " + names[i].substring(0, names[i].length() - 1));
79 int[] newret = new int[ret.length - 1];
80 System.arraycopy(ret, 0, newret, 0, newret.length);
87 /** returns a message identifier */
88 public synchronized int add(Message.StoredMessage message) throws IOException {
91 for(int i=0; i<all.length; i++) max = Math.max(max, all[i]);
93 File f = new File(path + File.separatorChar + max + ".-");
94 FileOutputStream fo = new FileOutputStream(f);
97 f.renameTo(new File(path + File.separatorChar + max + "."));
101 public Message.StoredMessage get(int messagenum) throws IOException {
102 File f = new File(path + File.separatorChar + messagenum + ".");
103 if (!f.exists()) throw new FileNotFoundException(f.toString());
104 return Message.StoredMessage.undump(new FileInputStream(f));
107 // query types: stringmatch (headers, body), header element, deletion status, date range, message size
108 public Message.StoredMessage[] query(int maxResults) {
109 throw new RuntimeException("FileBased.query() not implemented yet");