d200aa3026aae454a0f9c290c8782c78a2440467
[jsvc.git] / src / dolda / jsvc / SvcConfig.java
1 package dolda.jsvc;
2
3 import java.util.*;
4
5 public class SvcConfig {
6     public static class Param<T> {
7         private T value;
8         private final Object id = new Object();
9         
10         public Param(T def) {
11             this.value = def;
12         }
13         
14         @SuppressWarnings("unchecked")
15         public T get() {
16             if(Thread.currentThread() instanceof RequestThread) {
17                 Map<Object, Object> props = RequestThread.request().props();
18                 if(props.containsKey(id)) {
19                     /* This can very well actually be set to something
20                      * of the wrong type, but since the result would,
21                      * obviously, be a ClassCastException either way,
22                      * this way is at least the more convenient. */
23                     return((T)props.get(id));
24                 }
25             }
26             return(value);
27         }
28     }
29     
30     public static Responder let(final Responder next, Object... params) {
31         final Map<Param, Object> values = new HashMap<Param, Object>();
32         if((params.length % 2) != 0)
33             throw(new IllegalArgumentException("SvcConfig.let takes only an even number of parameters"));
34         for(int i = 0; i < params.length; i += 2)
35             values.put((Param)params[i], params[i + 1]);
36         return(new Responder() {
37                 public void respond(Request req) {
38                     final Map<Param, Object> old = new HashMap<Param, Object>();
39                     {
40                         Map<Object, Object> props = req.props();
41                         for(Map.Entry<Param, Object> val : values.entrySet()) {
42                             Param p = val.getKey();
43                             if(props.containsKey(p.id))
44                                 old.put(p, props.get(p.id));
45                             props.put(p.id, val.getValue());
46                         }
47                     }
48                     try {
49                         next.respond(req);
50                     } finally {
51                         Map<Object, Object> props = req.props();
52                         for(Map.Entry<Param, Object> val : values.entrySet()) {
53                             Param p = val.getKey();
54                             if(old.containsKey(p)) {
55                                 props.put(p.id, old.get(p));
56                             } else {
57                                 props.remove(p.id);
58                             }
59                         }
60                     }
61                 }
62             });
63     }
64 }