View Javadoc

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                  // Weird.
87                  Thread.currentThread().setContextClassLoader(RequestChannelInterceptor.class.getClassLoader());
88                  response.clear();
89                  obj =  deserialize(response, cl);
90              }
91  
92              // Are we demarshalling a thrown exception.
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 }