From b5f270350bfadea58c6b14516422df00202e9d46 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Tue, 13 Oct 2009 20:05:46 +0200 Subject: [PATCH] Improved on the SvcConfig and renamed it. --- src/dolda/jsvc/ContextParam.java | 87 ++++++++++++++++++++++++++++++++++++++++ src/dolda/jsvc/SvcConfig.java | 64 ----------------------------- 2 files changed, 87 insertions(+), 64 deletions(-) create mode 100644 src/dolda/jsvc/ContextParam.java delete mode 100644 src/dolda/jsvc/SvcConfig.java diff --git a/src/dolda/jsvc/ContextParam.java b/src/dolda/jsvc/ContextParam.java new file mode 100644 index 0000000..f146dc3 --- /dev/null +++ b/src/dolda/jsvc/ContextParam.java @@ -0,0 +1,87 @@ +package dolda.jsvc; + +import java.util.*; + +public class ContextParam { + private boolean bound; + private T value; + private final Object id = new Object(); + private Map perctx = new WeakHashMap(); + private Map perthr = new WeakHashMap(); + + public ContextParam(T def) { + this.value = def; + this.bound = true; + } + + public ContextParam() { + this.bound = false; + } + + public synchronized T get() { + Thread th = Thread.currentThread(); + if(perthr.containsKey(th)) + return(perthr.get(th)); + ThreadContext ctx = getctx(); + if(perctx.containsKey(ctx)) + return(perctx.get(ctx)); + if(!bound) + throw(new IllegalStateException("No value is bound to this parameter.")); + return(value); + } + + public synchronized T ctxset(T val) { + ThreadContext ctx = getctx(); + return(perctx.put(ctx, val)); + } + + private static ThreadContext getctx() { + for(ThreadGroup tg = Thread.currentThread().getThreadGroup(); tg != null; tg = tg.getParent()) { + if(tg instanceof ThreadContext) + return((ThreadContext)tg); + } + return(null); + } + + public static Responder let(final Responder next, Object... params) { + final Map values = new HashMap(); + 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((ContextParam)params[i], params[i + 1]); + + return(new Responder() { + /* 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. */ + @SuppressWarnings("unchecked") + public void respond(Request req) { + final Map old = new HashMap(); + Thread th = Thread.currentThread(); + for(Map.Entry val : values.entrySet()) { + ContextParam p = val.getKey(); + synchronized(p) { + if(p.perthr.containsKey(th)) + old.put(p, p.perthr.get(th)); + p.perthr.put(th, val.getValue()); + } + } + try { + next.respond(req); + } finally { + for(Map.Entry val : values.entrySet()) { + ContextParam p = val.getKey(); + synchronized(p) { + if(old.containsKey(p)) { + p.perthr.put(th, old.get(p)); + } else { + p.perthr.remove(th); + } + } + } + } + } + }); + } +} diff --git a/src/dolda/jsvc/SvcConfig.java b/src/dolda/jsvc/SvcConfig.java deleted file mode 100644 index d200aa3..0000000 --- a/src/dolda/jsvc/SvcConfig.java +++ /dev/null @@ -1,64 +0,0 @@ -package dolda.jsvc; - -import java.util.*; - -public class SvcConfig { - public static class Param { - 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 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 values = new HashMap(); - 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 old = new HashMap(); - { - Map props = req.props(); - for(Map.Entry 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 props = req.props(); - for(Map.Entry val : values.entrySet()) { - Param p = val.getKey(); - if(old.containsKey(p)) { - props.put(p.id, old.get(p)); - } else { - props.remove(p.id); - } - } - } - } - }); - } -} -- 2.11.0