reshuffling of file locations to make package structure flatter
[org.ibex.mail.git] / src / org / ibex / mail / Script.java
similarity index 73%
rename from src/org/ibex/mail/target/Script.java
rename to src/org/ibex/mail/Script.java
index 616d5ac..d3b118f 100644 (file)
@@ -2,15 +2,15 @@
 // Licensed under the Apache Public Source License 2.0 ("the License").
 // You may not use this file except in compliance with the License.
 
-package org.ibex.mail.target;
+package org.ibex.mail;
 import org.ibex.js.*;
 import org.ibex.io.*;
 import org.ibex.util.*;
-import org.ibex.mail.*;
 import org.ibex.mail.filter.*;
 import org.ibex.mail.target.*;
 import java.io.*;
 import java.util.*;
+import java.text.*;
 
 public class Script extends JS.Obj implements Target {
 
@@ -43,8 +43,8 @@ public class Script extends JS.Obj implements Target {
             case "m": return m;
             case "ibex": return env;
             default: return null;
-            //#end
-            return null;
+                //#end
+                return null;
         }
     }
 
@@ -77,16 +77,16 @@ public class Script extends JS.Obj implements Target {
     public class ScriptEnv extends JS.Obj {
 
         private PropertyFile prefs = null;
-            /*
-        static {
-            try {
-                // FIXME
-                prefs = new PropertyFile(new File("/etc/org.ibex.mail.properties"));
-            } catch (IOException e) {
-                Log.error(ScriptEnv.class, e);
-            }
-        }
-            */
+        /*
+          static {
+          try {
+          // FIXME
+          prefs = new PropertyFile(new File("/etc/org.ibex.mail.properties"));
+          } catch (IOException e) {
+          Log.error(ScriptEnv.class, e);
+          }
+          }
+        */
 
         /** lets us put multi-level get/put/call keys all in the same method */
         private class Sub extends JS.Immutable {
@@ -132,15 +132,15 @@ public class Script extends JS.Obj implements Target {
             case "mail.dir": return METHOD;
             case "mail.shell": return METHOD;
             case "mail.my.prefs": try {
-                    return new org.ibex.js.Directory(new File("/etc/org.ibex.mail.prefs"));
+                return new org.ibex.js.Directory(new File("/etc/org.ibex.mail.prefs"));
             } catch (IOException e) { throw new JSExn(e.toString()); }
-            case "mail.whitelist": return JSReflection.wrap(org.ibex.mail.protocol.SMTP.whitelist);
+            case "mail.whitelist": return JSReflection.wrap(org.ibex.mail.SMTP.whitelist);
             case "mail.my.mailbox":
                 Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true);
                 return root.slash("user", true).slash("megacz", true);
             case "mail.list": return METHOD;
-            //#end
-            return super.get(name);
+                //#end
+                return super.get(name);
         }
 
         public JS call(JS name0, JS[] args) throws JSExn {
@@ -207,9 +207,9 @@ public class Script extends JS.Obj implements Target {
                     boolean ok = false;
                     try {
                         if (attempt) {
-                            org.ibex.mail.protocol.SMTP.Outgoing.attempt(message);
+                            org.ibex.mail.SMTP.Outgoing.attempt(message);
                         } else {
-                            org.ibex.mail.protocol.SMTP.Outgoing.accept(message);
+                            org.ibex.mail.SMTP.Outgoing.accept(message);
                         }
                         ok = true;
                     } catch (Exception ex) {
@@ -239,7 +239,7 @@ public class Script extends JS.Obj implements Target {
                             public void accept(Message m) throws MailException {
                                 try {
                                     Message m2 = m.bounce(JSU.toString(a));
-                                    org.ibex.mail.protocol.SMTP.Outgoing.accept(m2);
+                                    org.ibex.mail.SMTP.Outgoing.accept(m2);
                                     Log.error(this, "BOUNCING! " + m2.summary());
                                 } catch (Exception e) {
                                     Log.warn(this, e);
@@ -251,7 +251,7 @@ public class Script extends JS.Obj implements Target {
                         Message m2 = Message.newMessage(new org.ibex.io.Fountain.StringFountain(m.toString()),
                                                         m.envelopeFrom,
                                                         new Address(JSU.toString(a)));
-                        org.ibex.mail.protocol.SMTP.Outgoing.accept(m2);
+                        org.ibex.mail.SMTP.Outgoing.accept(m2);
                     } catch (Exception e) {
                         Log.warn(this, e);
                         throw new JSExn(e.toString());
@@ -260,7 +260,7 @@ public class Script extends JS.Obj implements Target {
                 }
                 if (name.equals("mail.forward") || name.equals("forward")) {
                     Message m2 = Message.newMessage(Script.this.m, Script.this.m.envelopeFrom, new Address(JSU.toString(a)));
-                    org.ibex.mail.protocol.SMTP.Outgoing.attempt(m2, false);
+                    org.ibex.mail.SMTP.Outgoing.attempt(m2, false);
                     return Drop.instance;
                 }
                 if (name.equals("mail.reject"))
@@ -270,11 +270,11 @@ public class Script extends JS.Obj implements Target {
                 if (name.equals("log.warn") || name.equals("warn")) {     JSU.warn(a== null ? "**null**" : JSU.toString(a)); return null; }
                 if (name.equals("log.error") || name.equals("error")) {    JSU.error(a== null ? "**null**" : JSU.toString(a)); return null; }
                 switch (nargs) {
-                case 1:
-                    if (name.equals("regexp")) {return new JSRegexp(a, null); }
-                    break;
-                case 2:
-                    if (name.equals("regexp")) {return new JSRegexp(a, b); }
+                    case 1:
+                        if (name.equals("regexp")) {return new JSRegexp(a, null); }
+                        break;
+                    case 2:
+                        if (name.equals("regexp")) {return new JSRegexp(a, b); }
                 }
             } catch (MailException e) { throw e;
             } catch (Exception e) {
@@ -290,10 +290,10 @@ public class Script extends JS.Obj implements Target {
                 public JS get(JS name) throws JSExn {
                     // FIXME!!!
                     /*
-                    case "isNaN": return gs.get(name);
-                    case "isFinite": return gs.get(name);
-                    case "NaN": return gs.get(name);
-                    case "Infinity": return gs.get(name);
+                      case "isNaN": return gs.get(name);
+                      case "isFinite": return gs.get(name);
+                      case "NaN": return gs.get(name);
+                      case "Infinity": return gs.get(name);
                     */
                     return null;
                 }
@@ -303,15 +303,15 @@ public class Script extends JS.Obj implements Target {
                 public JS get(JS name) throws JSExn {
                     // FIXME!!!
                     /*
-                    case "parseInt": return gs.get(JSU.S("parseInt"));
-                    case "parseFloat": return gs.get(JSU.S("parseFloat"));
-                    case "decodeURI": return gs.get(JSU.S("decodeURI"));
-                    case "decodeURIComponent": return gs.get(JSU.S("decodeURIComponent"));
-                    case "encodeURI": return gs.get(JSU.S("encodeURI"));
-                    case "encodeURIComponent": return gs.get(JSU.S("encodeURIComponent"));
-                    case "escape": return gs.get(JSU.S("escape"));
-                    case "unescape": return gs.get(JSU.S("unescape"));
-                    case "fromCharCode": return gs.get(JSU.S("stringFromCharCode"));
+                      case "parseInt": return gs.get(JSU.S("parseInt"));
+                      case "parseFloat": return gs.get(JSU.S("parseFloat"));
+                      case "decodeURI": return gs.get(JSU.S("decodeURI"));
+                      case "decodeURIComponent": return gs.get(JSU.S("decodeURIComponent"));
+                      case "encodeURI": return gs.get(JSU.S("encodeURI"));
+                      case "encodeURIComponent": return gs.get(JSU.S("encodeURIComponent"));
+                      case "escape": return gs.get(JSU.S("escape"));
+                      case "unescape": return gs.get(JSU.S("unescape"));
+                      case "fromCharCode": return gs.get(JSU.S("stringFromCharCode"));
                     */
                     return null;
                 }
@@ -319,4 +319,73 @@ public class Script extends JS.Obj implements Target {
     }
 
     private static abstract class JSTarget extends JS.Obj implements Target { }
+
+    public static class Drop extends JS.Obj implements Target {
+        public static final Drop instance = new Drop();
+        public final String reason;
+        public Drop() { this(null); }
+        public Drop(String reason) { this.reason = reason; }
+        public void accept(Message m) throws IOException, MailException {
+            Log.warn(this, "dropping" +(reason==null?"":(" because "+reason))+ ": " + m.summary());
+        }
+    }
+
+    public static class Later extends JS.Obj implements Target {
+        public static final Later instance = new Later();
+        public static class LaterException extends RuntimeException { }
+        public void accept(Message m) throws IOException, MailException {
+            Log.warn(this, "delaying message " + m.summary());
+            throw new LaterException();
+        }
+    }
+
+    /** a fast-write, slow-read place to stash all messages we touch -- in case of a major f*ckup */
+    public static class Transcript implements Target {
+
+        public static final Transcript transcript = new Transcript(Mailbox.STORAGE_ROOT + File.separatorChar + "transcript");
+
+        private String path;
+        public Transcript(String path) { new File(this.path = path).mkdirs(); }
+        private static String lastTime = null;
+        private static int lastCounter = 0;
+
+        public synchronized void accept(Message message) {
+            try {
+                File today = new File(path + File.separatorChar + (new SimpleDateFormat("yy-MMM-dd").format(new Date())));
+                today.mkdirs();
+                
+                String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
+                synchronized (Transcript.class) {
+                    if (lastTime != null && lastTime.equals(time)) {
+                        time += "." + (++lastCounter);
+                    } else {
+                        lastTime = time;
+                        lastCounter = 0;
+                    }
+                }
+                
+                File target = new File(today.getPath() + File.separatorChar + time + ".txt");
+                OutputStream os = new FileOutputStream(target);
+                try {
+                    message.getStream().transcribe(new Stream(os));
+                    os.flush();
+                } finally { os.close(); }
+            } catch (IOException e) { throw new MailException.IOException(e); }
+        }
+    }
+
+    public static class Reject extends JS.Obj implements Target {
+        public final String reason;
+        public Reject(String reason) { this.reason = reason; }
+        public void accept(Message m) throws IOException, MailException {
+            throw new RejectException(m, reason);
+        }
+        public static class RejectException extends RuntimeException {
+            public final Message m;
+            public final String reason;
+            public RejectException(Message m, String reason) { this.m = m; this.reason = reason; }
+        }
+    }
+
+
 }