KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > remoting > UserRequest


1 package hudson.remoting;
2
3 import hudson.remoting.RemoteClassLoader.IClassLoader;
4
5 import java.io.ByteArrayInputStream JavaDoc;
6 import java.io.ByteArrayOutputStream JavaDoc;
7 import java.io.IOException JavaDoc;
8 import java.io.ObjectOutputStream JavaDoc;
9 import java.io.Serializable JavaDoc;
10 import java.io.NotSerializableException JavaDoc;
11
12 /**
13  * {@link Request} that can take {@link Callable} whose actual implementation
14  * may not be known to the remote system in advance.
15  *
16  * <p>
17  * This code assumes that the {@link Callable} object and all reachable code
18  * are loaded by a single classloader.
19  *
20  * @author Kohsuke Kawaguchi
21  */

22 final class UserRequest<RSP,EXC extends Throwable JavaDoc> extends Request<UserResponse<RSP,EXC>,EXC> {
23
24     private final byte[] request;
25     private final IClassLoader classLoaderProxy;
26     private final String JavaDoc toString;
27
28     public UserRequest(Channel local, Callable<?,EXC> c) throws IOException JavaDoc {
29         request = serialize(c,local);
30         this.toString = c.toString();
31         ClassLoader JavaDoc cl = getClassLoader(c);
32         classLoaderProxy = RemoteClassLoader.export(cl,local);
33     }
34
35     /*package*/ static ClassLoader JavaDoc getClassLoader(Callable<?,?> c) {
36         ClassLoader JavaDoc cl = c.getClass().getClassLoader();
37         if(c instanceof DelegatingCallable)
38             cl = ((DelegatingCallable)c).getClassLoader();
39         return cl;
40     }
41
42     protected UserResponse<RSP,EXC> perform(Channel channel) throws EXC {
43         try {
44             ClassLoader JavaDoc cl = channel.importedClassLoaders.get(classLoaderProxy);
45
46             RSP r = null;
47             Channel oldc = Channel.setCurrent(channel);
48             try {
49                 Object JavaDoc o = new ObjectInputStreamEx(new ByteArrayInputStream JavaDoc(request), cl).readObject();
50
51                 Callable<RSP,EXC> callable = (Callable<RSP,EXC>)o;
52
53                 ClassLoader JavaDoc old = Thread.currentThread().getContextClassLoader();
54                 Thread.currentThread().setContextClassLoader(cl);
55                 // execute the service
56
try {
57                     r = callable.call();
58                 } finally {
59                     Thread.currentThread().setContextClassLoader(old);
60                 }
61             } finally {
62                 Channel.setCurrent(oldc);
63             }
64
65             return new UserResponse<RSP,EXC>(serialize(r,channel),false);
66         } catch (Throwable JavaDoc e) {
67             // propagate this to the calling process
68
try {
69                 return new UserResponse<RSP,EXC>(serialize(e,channel),true);
70             } catch (IOException JavaDoc x) {
71                 // throw it as a lower-level exception
72
throw (EXC)x;
73             }
74         }
75     }
76
77     private byte[] serialize(Object JavaDoc o, Channel localChannel) throws IOException JavaDoc {
78         Channel old = Channel.setCurrent(localChannel);
79         try {
80             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
81             new ObjectOutputStream JavaDoc(baos).writeObject(o);
82             return baos.toByteArray();
83         } catch( NotSerializableException JavaDoc e ) {
84             IOException JavaDoc x = new IOException JavaDoc("Unable to serialize " + o);
85             x.initCause(e);
86             throw x;
87         } finally {
88             Channel.setCurrent(old);
89         }
90     }
91
92     public String JavaDoc toString() {
93         return "UserRequest:"+toString;
94     }
95 }
96
97 final class UserResponse<RSP,EXC extends Throwable JavaDoc> implements Serializable JavaDoc {
98     private final byte[] response;
99     private final boolean isException;
100
101     public UserResponse(byte[] response, boolean isException) {
102         this.response = response;
103         this.isException = isException;
104     }
105
106     public RSP retrieve(Channel channel, ClassLoader JavaDoc cl) throws IOException JavaDoc, ClassNotFoundException JavaDoc, EXC {
107         Channel old = Channel.setCurrent(channel);
108         try {
109             Object JavaDoc o = new ObjectInputStreamEx(new ByteArrayInputStream JavaDoc(response), cl).readObject();
110
111             if(isException)
112                 throw (EXC)o;
113             else
114                 return (RSP) o;
115         } finally {
116             Channel.setCurrent(old);
117         }
118     }
119
120     private static final long serialVersionUID = 1L;
121 }
122
Popular Tags