5 public class ContextParam<T> {
8 private final Object id = new Object();
9 private Map<ThreadContext, T> perctx = new WeakHashMap<ThreadContext, T>();
10 private Map<Thread, T> perthr = new WeakHashMap<Thread, T>();
12 public ContextParam(T def) {
17 public ContextParam() {
21 public synchronized T get() {
22 Thread th = Thread.currentThread();
23 if(perthr.containsKey(th))
24 return(perthr.get(th));
25 ThreadContext ctx = ThreadContext.current();
26 if(perctx.containsKey(ctx))
27 return(perctx.get(ctx));
29 throw(new IllegalStateException("No value is bound to this parameter."));
33 public synchronized T ctxset(T val) {
34 ThreadContext ctx = ThreadContext.current();
35 return(perctx.put(ctx, val));
38 public static Responder let(final Responder next, Object... params) {
39 final Map<ContextParam, Object> values = new HashMap<ContextParam, Object>();
40 if((params.length % 2) != 0)
41 throw(new IllegalArgumentException("SvcConfig.let takes only an even number of parameters"));
42 for(int i = 0; i < params.length; i += 2)
43 values.put((ContextParam)params[i], params[i + 1]);
45 return(new Responder() {
46 /* This can very well actually be set to something
47 * of the wrong type, but since the result would,
48 * obviously, be a ClassCastException either way,
49 * this way is at least the more convenient. */
50 @SuppressWarnings("unchecked")
51 public void respond(Request req) {
52 final Map<ContextParam, Object> old = new HashMap<ContextParam, Object>();
53 Thread th = Thread.currentThread();
54 for(Map.Entry<ContextParam, Object> val : values.entrySet()) {
55 ContextParam p = val.getKey();
57 if(p.perthr.containsKey(th))
58 old.put(p, p.perthr.get(th));
59 p.perthr.put(th, val.getValue());
65 for(Map.Entry<ContextParam, Object> val : values.entrySet()) {
66 ContextParam p = val.getKey();
68 if(old.containsKey(p)) {
69 p.perthr.put(th, old.get(p));