1 8 package org.codehaus.aspectwerkz.connectivity; 9 10 import org.codehaus.aspectwerkz.exception.WrappedRuntimeException; 11 import org.codehaus.aspectwerkz.util.UuidGenerator; 12 13 import java.io.IOException ; 14 import java.io.ObjectInputStream ; 15 import java.io.ObjectOutputStream ; 16 import java.io.Serializable ; 17 import java.lang.reflect.InvocationHandler ; 18 import java.lang.reflect.Method ; 19 import java.lang.reflect.Proxy ; 20 import java.net.InetAddress ; 21 import java.net.Socket ; 22 import java.util.Map ; 23 import java.util.WeakHashMap ; 24 25 32 public class RemoteProxy implements InvocationHandler , Serializable { 33 38 private static final long serialVersionUID = 1L; 39 40 43 private transient static Map s_instances = new WeakHashMap (); 44 45 48 private final String m_address; 49 50 53 private final int m_port; 54 55 58 private String m_handle = null; 59 60 63 private Class [] m_targetInterfaces = null; 64 65 68 private String [] m_targetInterfaceNames = null; 69 70 73 private String m_targetImplName = null; 74 75 78 private transient Socket m_socket; 79 80 83 private transient ObjectInputStream m_in; 84 85 88 private transient ObjectOutputStream m_out; 89 90 93 private transient ClassLoader m_loader; 94 95 98 private transient Object m_context = null; 99 100 103 private transient Object m_proxy = null; 104 105 116 private RemoteProxy(final String [] interfaces, 117 final String impl, 118 final String address, 119 final int port, 120 final Object context, 121 final ClassLoader loader) { 122 if ((interfaces == null) || (interfaces.length == 0)) { 123 throw new IllegalArgumentException ("at least one interface must be specified"); 124 } 125 if (impl == null) { 126 throw new IllegalArgumentException ("implementation class name can not be null"); 127 } 128 if (address == null) { 129 throw new IllegalArgumentException ("address can not be null"); 130 } 131 if (port < 0) { 132 throw new IllegalArgumentException ("port not valid"); 133 } 134 m_targetInterfaceNames = interfaces; 135 m_targetImplName = impl; 136 m_address = address; 137 m_port = port; 138 m_context = context; 139 m_loader = loader; 140 } 141 142 150 private RemoteProxy(final Object targetInstance, final String address, final int port) { 151 if (targetInstance == null) { 152 throw new IllegalArgumentException ("target instance can not be null"); 153 } 154 if (address == null) { 155 throw new IllegalArgumentException ("address can not be null"); 156 } 157 if (port < 0) { 158 throw new IllegalArgumentException ("port not valid"); 159 } 160 m_targetInterfaces = targetInstance.getClass().getInterfaces(); 161 m_address = address; 162 m_port = port; 163 m_handle = wrapInstance(targetInstance); 164 } 165 166 175 public static RemoteProxy createClientProxy(final String [] interfaces, 176 final String impl, 177 final String address, 178 final int port) { 179 return RemoteProxy.createClientProxy( 180 interfaces, impl, address, port, Thread.currentThread() 181 .getContextClassLoader() 182 ); 183 } 184 185 195 public static RemoteProxy createClientProxy(final String [] interfaces, 196 final String impl, 197 final String address, 198 final int port, 199 final Object context) { 200 return RemoteProxy.createClientProxy( 201 interfaces, impl, address, port, context, Thread.currentThread() 202 .getContextClassLoader() 203 ); 204 } 205 206 216 public static RemoteProxy createClientProxy(final String [] interfaces, 217 final String impl, 218 final String address, 219 final int port, 220 final ClassLoader loader) { 221 return RemoteProxy.createClientProxy(interfaces, impl, address, port, null, loader); 222 } 223 224 235 public static RemoteProxy createClientProxy(final String [] interfaces, 236 final String impl, 237 final String address, 238 final int port, 239 final Object context, 240 final ClassLoader loader) { 241 return new RemoteProxy(interfaces, impl, address, port, context, loader); 242 } 243 244 253 public static RemoteProxy createServerProxy(final Object targetlInstance, final String address, final int port) { 254 return new RemoteProxy(targetlInstance, address, port); 255 } 256 257 263 public Object getInstance(final ClassLoader loader) { 264 m_loader = loader; 265 return getInstance(); 266 } 267 268 273 public Object getInstance() { 274 if (m_proxy != null) { 275 return m_proxy; 276 } 277 if (m_loader == null) { 278 m_loader = Thread.currentThread().getContextClassLoader(); 279 } 280 try { 281 m_socket = new Socket (InetAddress.getByName(m_address), m_port); 282 m_socket.setTcpNoDelay(true); 283 m_out = new ObjectOutputStream (m_socket.getOutputStream()); 284 m_in = new ObjectInputStream (m_socket.getInputStream()); 285 } catch (Exception e) { 286 throw new WrappedRuntimeException(e); 287 } 288 if (m_handle == null) { 289 if (m_targetInterfaceNames == null) { 291 throw new IllegalStateException ("interface class name can not be null"); 292 } 293 if (m_targetImplName == null) { 294 throw new IllegalStateException ("implementation class name can not be null"); 295 } 296 try { 297 m_out.write(Command.CREATE); 299 m_out.writeObject(m_targetImplName); 300 m_out.flush(); 301 m_handle = (String ) m_in.readObject(); 302 m_targetInterfaces = new Class [m_targetInterfaceNames.length]; 303 for (int i = 0; i < m_targetInterfaceNames.length; i++) { 304 try { 305 m_targetInterfaces[i] = Class.forName(m_targetInterfaceNames[i], false, m_loader); 306 } catch (ClassNotFoundException e) { 307 throw new WrappedRuntimeException(e); 308 } 309 } 310 } catch (Exception e) { 311 throw new WrappedRuntimeException(e); 312 } 313 } 314 m_proxy = Proxy.newProxyInstance(m_loader, m_targetInterfaces, this); 315 return m_proxy; 316 } 317 318 327 public Object invoke(final Object proxy, final Method method, final Object [] args) { 328 try { 329 m_out.write(Command.INVOKE); 330 m_out.writeObject(m_context); 331 m_out.writeObject(m_handle); 332 m_out.writeObject(method.getName()); 333 m_out.writeObject(method.getParameterTypes()); 334 m_out.writeObject(args); 335 m_out.flush(); 336 final Object response = m_in.readObject(); 337 if (response instanceof Exception ) { 338 throw (Exception ) response; 339 } 340 return response; 341 } catch (Exception e) { 342 throw new WrappedRuntimeException(e); 343 } 344 } 345 346 349 public void close() { 350 try { 351 m_out.write(Command.CLOSE); 352 m_out.flush(); 353 m_out.close(); 354 m_in.close(); 355 m_socket.close(); 356 } catch (IOException e) { 357 throw new WrappedRuntimeException(e); 358 } 359 } 360 361 367 public static Object getWrappedInstance(final String handle) { 368 return s_instances.get(handle); 369 } 370 371 377 public static String wrapInstance(final Object instance) { 378 final String handle = UuidGenerator.generate(instance); 379 s_instances.put(handle, instance); 380 return handle; 381 } 382 } | Popular Tags |