added tons of stuff, including js support
[org.ibex.mail.git] / src / org / ibex / mail / target / Script.java
1 // Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
2 package org.ibex.mail;
3 import org.ibex.js.*;
4
5 public class Script {
6
7     public static final JS root =
8         new Script(System.getProperty("ibex.mail.conf", File.separatorChar + "etc" + File.separatorChar + "org.ibex.mail.conf"));
9
10     final JS js;
11     public Script(String filePath) { js = JS.fromReader(CONF, 0, new InputStreamReader(new FileInputStream(CONF))); }
12
13     public void accept(Message m) throws IOException {
14         // currently, we write all inbound messages to the transcript
15         MessageStore.transcript.add(m);
16         Object ret = js.call(m);
17         if (ret instanceof Target) {
18             ((Target)ret).accept(m);
19         } else if (ret instanceof Filter) {
20             ((Filter)f).accept
21         } else {
22             throw new IOException("configuration script returned a " + ret.getClass().getName());
23         }
24     }
25
26     // FIXME: this should extend org.ibex.core.Ibex
27     public static class ScriptEnvironment extends JS {
28
29         // FIXME: duplicated code with org.ibex.core.Ibex; lift?
30         /** lets us put multi-level get/put/call keys all in the same method */
31         private class Sub extends JS {
32             String key;
33             Sub(String key) { this.key = key; }
34             public void put(Object key, Object val) throws JSExn { ScriptEnv.this.put(this.key + "." + key, val); }
35             public Object get(Object key) throws JSExn { return ScriptEnv.this.get(this.key + "." + key); }
36             public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
37                 return ScriptEnv.this.callMethod(this.key, a0, a1, a2, rest, nargs);
38             }
39             public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
40                 return ScriptEnv.this.callMethod(this.key + "." + method, a0, a1, a2, rest, nargs);
41             }
42         }
43         private Cache subCache = new Cache(20);
44         private Sub getSub(String s) {
45             Sub ret = (Sub)subCache.get(s);
46             if (ret == null) subCache.put(s, ret = new Sub(s));
47             return ret;
48         }
49
50         public Object get(Object name) throws JSExn {
51             if (name instanceof String && ((String)name).length() == 0) return rr;
52             //#switch(name)
53             case "math": return ibexMath;
54             case "string": return ibexString;
55             case "date": return METHOD;
56             case "regexp": return METHOD;
57             case "log": return getSub("log");
58             case "log.debug": return METHOD;
59             case "log.info": return METHOD;
60             case "log.warn": return METHOD;
61             case "log.error": return METHOD;
62             //#end
63             return super.get(name);
64         }
65
66         public Object callMethod(Object name, Object a, Object b, Object c, Object[] rest, int nargs) throws JSExn {
67             try {
68                 //#switch(name)
69                 case "date": return new JSDate(a, b, c, rest, nargs);
70                 case "log.debug":    JS.debug(a== null ? "**null**" : a.toString()); return null;
71                 case "log.info":     JS.info(a== null ? "**null**" : a.toString()); return null;
72                 case "log.warn":     JS.warn(a== null ? "**null**" : a.toString()); return null;
73                 case "log.error":    JS.error(a== null ? "**null**" : a.toString()); return null;
74                 //#end
75                 switch (nargs) {
76                 case 1:
77                     //#switch(name)
78                     case "regexp": return new JSRegexp(a, null);
79                     //#end
80                     break;
81                 case 2:
82                     //#switch(name)
83                     case "regexp": return new JSRegexp(a, b);
84                     //#end
85                 }
86             } catch (RuntimeException e) {
87                 // FIXME: maybe JSExn should take a second argument, Exception
88                 Log.warn(this, "ibex."+name+"() threw: " + e);
89                 throw new JSExn("invalid argument for ibex object method "+name+"()");
90             }
91             throw new JSExn("invalid number of arguments ("+nargs+") for ibex object method "+name+"()");
92         }
93
94         public static final JSMath ibexMath = new JSMath() {
95                 private JS gs = new JSScope.Global();
96                 public Object get(Object key) throws JSExn {
97                     //#switch(key)
98                     case "isNaN": return gs.get("isNaN");
99                     case "isFinite": return gs.get("isFinite");
100                     case "NaN": return gs.get("NaN");
101                     case "Infinity": return gs.get("Infinity");
102                     //#end
103                    return super.get(key);
104                 }
105             };
106         
107         public static final JS ibexString = new JS() {
108                 private JS gs = new JSScope.Global();
109                 public void put(Object key, Object val) { }
110                 public Object get(Object key) throws JSExn {
111                     //#switch(key)
112                     case "parseInt": return gs.get("parseInt");
113                     case "parseFloat": return gs.get("parseFloat");
114                     case "decodeURI": return gs.get("decodeURI");
115                     case "decodeURIComponent": return gs.get("decodeURIComponent");
116                     case "encodeURI": return gs.get("encodeURI");
117                     case "encodeURIComponent": return gs.get("encodeURIComponent");
118                     case "escape": return gs.get("escape");
119                     case "unescape": return gs.get("unescape");
120                     case "fromCharCode": return gs.get("stringFromCharCode");
121                     //#end
122                     return null;
123                 }
124             };
125     }
126 }