Replaced ContextResponder with a more generic Destroyable interface.
[jsvc.git] / src / dolda / jsvc / util / PerSession.java
CommitLineData
c04f28ae
FT
1package dolda.jsvc.util;
2
3import dolda.jsvc.*;
4import java.lang.reflect.*;
5
6public class PerSession implements Responder {
7 private final Class<?> rcl;
8 private final Class<?> dcl;
9
10 public PerSession(Class<?> rcl, Class<?> dcl) {
11 this.rcl = rcl;
12 this.dcl = dcl;
13 }
14
15 public PerSession(Class<?> rcl) {
16 this(rcl, null);
17 }
18
19 private Object makedata(Session sess) {
20 try {
21 try {
8eafb5c6 22 return(dcl.getConstructor(Session.class).newInstance(sess));
c04f28ae
FT
23 } catch(NoSuchMethodException e) {
24 }
25 try {
8eafb5c6 26 return(dcl.getConstructor().newInstance());
c04f28ae
FT
27 } catch(NoSuchMethodException e) {
28 }
29 } catch(InstantiationException e) {
30 throw(new RuntimeException(e));
31 } catch(IllegalAccessException e) {
32 throw(new RuntimeException(e));
33 } catch(InvocationTargetException e) {
34 throw(new RuntimeException(e));
35 }
36 throw(new RuntimeException("Found no way to create an instance of " + dcl.getName()));
37 }
38
39 private Object getdata(Session sess) {
40 Object d = sess.get(dcl, null);
41 if(d == null) {
42 d = makedata(sess);
43 sess.put(dcl, d);
44 }
45 return(d);
46 }
47
48 private Responder create(Session sess) {
49 try {
50 if(dcl != null) {
51 try {
52 return((Responder)rcl.getMethod("responder", dcl).invoke(null, getdata(sess)));
53 } catch(NoSuchMethodException e) {
54 }
55 }
56 try {
57 return((Responder)rcl.getMethod("responder", Session.class).invoke(null, sess));
58 } catch(NoSuchMethodException e) {
59 }
60 try {
61 return((Responder)rcl.getMethod("responder").invoke(null));
62 } catch(NoSuchMethodException e) {
63 }
64 if(dcl != null) {
65 try {
66 return((Responder)rcl.getConstructor(dcl).newInstance(getdata(sess)));
67 } catch(NoSuchMethodException e) {
68 }
69 }
70 try {
71 return((Responder)rcl.getConstructor(Session.class).newInstance(sess));
72 } catch(NoSuchMethodException e) {
73 }
74 try {
75 return((Responder)rcl.getConstructor().newInstance());
76 } catch(NoSuchMethodException e) {
77 }
78 } catch(InstantiationException e) {
79 throw(new RuntimeException(e));
80 } catch(IllegalAccessException e) {
81 throw(new RuntimeException(e));
82 } catch(InvocationTargetException e) {
83 throw(new RuntimeException(e));
84 }
85 throw(new RuntimeException("Found no way to create a responder from the class " + rcl.getName()));
86 }
87
88 public void respond(Request req) {
89 Session sess = Session.get(req);
90 Responder resp;
48ea770f 91 synchronized(this) {
c04f28ae
FT
92 resp = (Responder)sess.get(rcl, null);
93 if(resp == null) {
94 resp = create(sess);
95 sess.put(rcl, resp);
0fc245df
FT
96 if(resp instanceof Destroyable) {
97 final Destroyable cr = (Destroyable)resp;
1927b264 98 sess.listen(new Session.Listener() {
f0f0cfd1 99 public void destroy(Session sess) {
1927b264
FT
100 cr.destroy();
101 }
102 });
103 }
c04f28ae
FT
104 }
105 }
106 resp.respond(req);
107 }
108}