Added a configuration manager with support for LET-like constructs.
authorFredrik Tolf <fredrik@dolda2000.com>
Mon, 12 Oct 2009 23:36:16 +0000 (01:36 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Mon, 12 Oct 2009 23:36:16 +0000 (01:36 +0200)
src/dolda/jsvc/Request.java
src/dolda/jsvc/SvcConfig.java [new file with mode: 0644]
src/dolda/jsvc/j2ee/J2eeRequest.java

index 6c779ac..8de008a 100644 (file)
@@ -21,7 +21,7 @@ public interface Request {
     public MultiMap<String, String> outheaders();
     
     /* Misc. */
-    public Map<?, ?> props();
+    public Map<Object, Object> props();
     public ServerContext ctx();
     public SocketAddress remoteaddr();
     public SocketAddress localaddr();
diff --git a/src/dolda/jsvc/SvcConfig.java b/src/dolda/jsvc/SvcConfig.java
new file mode 100644 (file)
index 0000000..d200aa3
--- /dev/null
@@ -0,0 +1,64 @@
+package dolda.jsvc;
+
+import java.util.*;
+
+public class SvcConfig {
+    public static class Param<T> {
+       private T value;
+       private final Object id = new Object();
+       
+       public Param(T def) {
+           this.value = def;
+       }
+       
+       @SuppressWarnings("unchecked")
+       public T get() {
+           if(Thread.currentThread() instanceof RequestThread) {
+               Map<Object, Object> props = RequestThread.request().props();
+               if(props.containsKey(id)) {
+                   /* This can very well actually be set to something
+                    * of the wrong type, but since the result would,
+                    * obviously, be a ClassCastException either way,
+                    * this way is at least the more convenient. */
+                   return((T)props.get(id));
+               }
+           }
+           return(value);
+       }
+    }
+    
+    public static Responder let(final Responder next, Object... params) {
+       final Map<Param, Object> values = new HashMap<Param, Object>();
+       if((params.length % 2) != 0)
+           throw(new IllegalArgumentException("SvcConfig.let takes only an even number of parameters"));
+       for(int i = 0; i < params.length; i += 2)
+           values.put((Param)params[i], params[i + 1]);
+       return(new Responder() {
+               public void respond(Request req) {
+                   final Map<Param, Object> old = new HashMap<Param, Object>();
+                   {
+                       Map<Object, Object> props = req.props();
+                       for(Map.Entry<Param, Object> val : values.entrySet()) {
+                           Param p = val.getKey();
+                           if(props.containsKey(p.id))
+                               old.put(p, props.get(p.id));
+                           props.put(p.id, val.getValue());
+                       }
+                   }
+                   try {
+                       next.respond(req);
+                   } finally {
+                       Map<Object, Object> props = req.props();
+                       for(Map.Entry<Param, Object> val : values.entrySet()) {
+                           Param p = val.getKey();
+                           if(old.containsKey(p)) {
+                               props.put(p.id, old.get(p));
+                           } else {
+                               props.remove(p.id);
+                           }
+                       }
+                   }
+               }
+           });
+    }
+}
index f394653..9beddf5 100644 (file)
@@ -14,7 +14,7 @@ public class J2eeRequest extends ResponseBuffer {
     private HttpServletResponse resp;
     private String method, path;
     private URL url;
-    private Map<?, ?> props = new HashMap();
+    private Map<Object, Object> props = new HashMap<Object, Object>();
     
     public J2eeRequest(ServletConfig cfg, HttpServletRequest req, HttpServletResponse resp) {
        this.cfg = cfg;
@@ -69,7 +69,7 @@ public class J2eeRequest extends ResponseBuffer {
            path = path.substring(1);
     }
     
-    public Map<?, ?> props() {
+    public Map<Object, Object> props() {
        return(props);
     }