1 /**
2 *
3 * Copyright 2003-2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.security.remoting.jmx;
19
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.ObjectOutputStream;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.Method;
27
28 import org.activeio.Packet;
29 import org.activeio.RequestChannel;
30 import org.activeio.Service;
31 import org.activeio.SyncChannel;
32 import org.activeio.adapter.AsyncChannelToClientRequestChannel;
33 import org.activeio.adapter.PacketToInputStream;
34 import org.activeio.filter.PacketAggregatingSyncChannel;
35 import org.activeio.net.SocketMetadata;
36 import org.activeio.net.SocketSyncChannelFactory;
37 import org.activeio.packet.ByteArrayPacket;
38
39 import org.apache.geronimo.interceptor.Interceptor;
40 import org.apache.geronimo.interceptor.Invocation;
41 import org.apache.geronimo.interceptor.InvocationResult;
42 import org.apache.geronimo.kernel.ObjectInputStreamExt;
43
44 /**
45 * @version $Rev: 417891 $ $Date: 2006-06-28 15:45:07 -0700 (Wed, 28 Jun 2006) $
46 */
47 public class RequestChannelInterceptor implements Interceptor, InvocationHandler {
48
49 private final ClassLoader cl;
50 private final URI target;
51
52 public RequestChannelInterceptor(URI target, ClassLoader cl) {
53 this.target = target;
54 this.cl = cl;
55 }
56
57
58 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
59 Invocation invocation = new SerializableInvocation(method, args, proxy);
60 InvocationResult result = invoke(invocation);
61 if( result.isException() ) {
62 throw result.getException();
63 }
64 return result.getResult();
65 }
66
67 public InvocationResult invoke(Invocation invocation) throws Throwable {
68
69 ClassLoader originalLoader = Thread.currentThread().getContextClassLoader();
70 try {
71
72 RequestChannel channel = createRequestChannel(target);
73 Packet response;
74 try {
75 channel.start();
76 Packet request = serialize(invocation);
77 response = channel.request(request, Service.WAIT_FOREVER_TIMEOUT);
78 } finally {
79 channel.dispose();
80 }
81
82 Object obj;
83 try {
84 obj = deserialize(response, cl);
85 } catch ( ClassNotFoundException e ) {
86
87 Thread.currentThread().setContextClassLoader(RequestChannelInterceptor.class.getClassLoader());
88 response.clear();
89 obj = deserialize(response, cl);
90 }
91
92
93 if (obj instanceof RequestChannelInterceptorInvoker.ThrowableWrapper) {
94 throw ((RequestChannelInterceptorInvoker.ThrowableWrapper) obj).exception;
95 }
96 return (InvocationResult)obj;
97
98 } finally {
99 Thread.currentThread().setContextClassLoader(originalLoader);
100 }
101 }
102
103 private static RequestChannel createRequestChannel(URI target) throws IOException, URISyntaxException {
104 SocketSyncChannelFactory factory = new SocketSyncChannelFactory();
105 SyncChannel channel = factory.openSyncChannel(target);
106 SocketMetadata socket = (SocketMetadata) channel.narrow(SocketMetadata.class);
107 socket.setTcpNoDelay(true);
108 return new AsyncChannelToClientRequestChannel(
109 new PacketAggregatingSyncChannel(
110 channel));
111 }
112
113 /**
114 * @param response
115 * @param cl
116 * @return
117 * @throws IOException
118 * @throws ClassNotFoundException
119 */
120 static public Object deserialize(Packet response, ClassLoader cl) throws IOException, ClassNotFoundException {
121 ObjectInputStreamExt is = new ObjectInputStreamExt(new PacketToInputStream(response), cl);
122 Object rc = is.readObject();
123 is.close();
124 return rc;
125 }
126
127 static public Packet serialize(Object object) throws IOException {
128 ByteArrayOutputStream baos = new ByteArrayOutputStream();
129 ObjectOutputStream oos = new ObjectOutputStream(baos);
130 oos.writeObject(object);
131 oos.close();
132 return new ByteArrayPacket(baos.toByteArray());
133 }
134 }