1 45 package org.openejb.core.ivm; 46 47 import java.io.IOException ; 48 import java.io.ObjectStreamException ; 49 import java.io.Serializable ; 50 import java.io.ByteArrayOutputStream ; 51 import java.io.ObjectOutputStream ; 52 import java.io.ByteArrayInputStream ; 53 import java.io.ObjectInputStream ; 54 import java.lang.reflect.Method ; 55 import java.lang.reflect.UndeclaredThrowableException ; 56 import java.rmi.MarshalledObject ; 57 import java.rmi.NoSuchObjectException ; 58 import java.rmi.RemoteException ; 59 import java.util.HashSet ; 60 import java.util.Hashtable ; 61 import java.util.Iterator ; 62 63 import javax.ejb.EJBException ; 64 65 import org.openejb.OpenEJB; 66 import org.openejb.RpcContainer; 67 import org.openejb.core.DeploymentInfo; 68 import org.openejb.core.ThreadContext; 69 import org.openejb.util.proxy.InvocationHandler; 70 import org.openejb.util.proxy.ProxyManager; 71 72 81 public abstract class BaseEjbProxyHandler implements InvocationHandler, Serializable { 82 105 protected static final Hashtable liveHandleRegistry = new Hashtable (); 106 107 110 public final Object deploymentID; 111 112 115 public final Object primaryKey; 116 117 119 public boolean inProxyMap = false; 120 121 124 public transient DeploymentInfo deploymentInfo; 125 126 129 public transient RpcContainer container; 130 131 protected boolean isInvalidReference = false; 132 133 146 protected boolean doIntraVmCopy; 147 private boolean isLocal; 148 149 156 public BaseEjbProxyHandler(RpcContainer container, Object pk, Object depID){ 157 this.container = container; 158 this.primaryKey = pk; 159 this.deploymentID = depID; 160 this.deploymentInfo = (org.openejb.core.DeploymentInfo)container.getDeploymentInfo(depID); 161 162 String value = org.openejb.OpenEJB.getInitProps().getProperty("openejb.localcopy"); 163 if ( value == null ) { 164 value = org.openejb.OpenEJB.getInitProps().getProperty(org.openejb.core.EnvProps.INTRA_VM_COPY); 165 } 166 if(value == null){ 167 value = System.getProperty("openejb.localcopy"); 168 } 169 if(value == null){ 170 value = System.getProperty(org.openejb.core.EnvProps.INTRA_VM_COPY); 171 } 172 doIntraVmCopy = value==null || !value.equalsIgnoreCase("FALSE"); 173 } 174 184 private void readObject(java.io.ObjectInputStream in) 185 throws java.io.IOException ,ClassNotFoundException , NoSuchMethodException { 186 187 in.defaultReadObject(); 188 189 deploymentInfo = (org.openejb.core.DeploymentInfo)OpenEJB.getDeploymentInfo(deploymentID); 190 container = (RpcContainer)deploymentInfo.getContainer(); 191 } 192 201 protected void checkAuthorization(Method method) throws org.openejb.OpenEJBException{ 202 Object caller = getThreadSpecificSecurityIdentity(); 203 boolean authorized = OpenEJB.getSecurityService().isCallerAuthorized(caller, deploymentInfo.getAuthorizedRoles(method)); 204 if(!authorized) 205 throw new org.openejb.ApplicationException(new RemoteException ("Unauthorized Access by Principal Denied")); 206 } 207 208 protected Object getThreadSpecificSecurityIdentity(){ 209 ThreadContext context = ThreadContext.getThreadContext(); 210 if(context.valid()){ 211 return context.getSecurityIdentity(); 212 }else{ 213 return OpenEJB.getSecurityService().getSecurityIdentity(); 214 } 215 } 216 217 222 public void setIntraVmCopyMode(boolean on) { 223 doIntraVmCopy=on; 224 } 225 226 240 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 241 if (isInvalidReference) throw new NoSuchObjectException ("reference is invalid"); 242 243 244 if (method.getDeclaringClass() == Object .class ) { 245 final String methodName = method.getName(); 246 247 if ( methodName.equals( "toString" )) return toString(); 248 else if (methodName.equals( "equals" )) return equals(args[0])?Boolean.TRUE: Boolean.FALSE; 249 else if (methodName.equals("hashCode")) return new Integer (hashCode()); 250 else throw new UnsupportedOperationException ("Unkown method: "+method); 251 } else if (method.getDeclaringClass() == IntraVmProxy.class ) { 252 final String methodName = method.getName(); 253 254 if (methodName.equals("writeReplace")) return _writeReplace( proxy ); 255 else throw new UnsupportedOperationException ("Unkown method: "+method); 256 } 257 269 270 ThreadContext cntext = null; 271 DeploymentInfo depInfo = null; 272 Object prmryKey = null; 273 byte crrntOperation = (byte)0; 274 Object scrtyIdentity = null; 275 boolean cntextValid = false; 276 cntext = ThreadContext.getThreadContext(); 277 if(cntext.valid()){ 278 depInfo = cntext.getDeploymentInfo(); 279 prmryKey = cntext.getPrimaryKey(); 280 crrntOperation = cntext.getCurrentOperation(); 281 scrtyIdentity = cntext.getSecurityIdentity(); 282 cntextValid = true; 283 } 284 285 String jndiEnc = System.getProperty(javax.naming.Context.URL_PKG_PREFIXES); 286 try{ 290 if(doIntraVmCopy==true){ if(args!=null && args.length > 0) { 293 IntraVmCopyMonitor.preCopyOperation(); 295 args = copyArgs(args); 296 IntraVmCopyMonitor.postCopyOperation(); 298 } 299 Object returnObj = _invoke(proxy,method,args); 300 301 IntraVmCopyMonitor.preCopyOperation(); 303 returnObj = copyObj(returnObj); 304 return returnObj; 305 } else { 307 try { 308 319 320 return _invoke(proxy,method,args); 321 } catch (RemoteException e) { 322 if (this.isLocal()){ 323 throw new EJBException (e.getMessage()).initCause(e.getCause()); 324 } else { 325 throw e; 326 } 327 } catch (Throwable t) { 328 t.printStackTrace(); 329 Class [] etypes = method.getExceptionTypes(); 330 for (int i = 0; i < etypes.length; i++) { 331 332 if (etypes[i].isAssignableFrom(t.getClass())){ 333 throw t; 334 } 335 } 336 while (t.getCause() != null && !(t instanceof RuntimeException )){ 339 t = t.getCause(); 340 } 341 throw t; 342 } 343 } 344 } finally { 345 if(cntextValid){ 348 cntext.set(depInfo, prmryKey, scrtyIdentity); 349 cntext.setCurrentOperation(crrntOperation); 350 } 351 if(doIntraVmCopy==true){ 352 IntraVmCopyMonitor.postCopyOperation(); 355 } 356 } 357 } 358 359 public String toString() { 360 return "proxy="+getProxyInfo().getInterface().getName()+";deployment="+this.deploymentID+";pk="+this.primaryKey; 361 } 362 363 public int hashCode() { 364 if(primaryKey==null) { 365 return deploymentID.hashCode(); 367 }else { 368 return primaryKey.hashCode(); 369 } 370 } 371 372 public boolean equals(Object obj) { 373 try{ 374 obj = ProxyManager.getInvocationHandler(obj); 375 }catch(IllegalArgumentException e) { 376 return false; 377 } 378 BaseEjbProxyHandler other = (BaseEjbProxyHandler) obj; 379 if(primaryKey==null) { 380 return other.primaryKey==null && deploymentID.equals(other.deploymentID); 381 } else { 382 return primaryKey.equals(other.primaryKey) && deploymentID.equals(other.deploymentID); 383 } 384 } 385 386 395 protected abstract Object _invoke(Object proxy, Method method, Object [] args) throws Throwable ; 396 397 398 403 404 protected Object [] copyArgs(Object [] objects) throws IOException , ClassNotFoundException { 405 411 412 for (int i=0; i < objects.length; i++){ 413 objects[i] = copyObj(objects[i]); 414 } 415 416 return objects; 417 } 418 419 424 425 protected Object copyObj(Object object) throws IOException , ClassNotFoundException { 426 ByteArrayOutputStream baos = new ByteArrayOutputStream (128); 427 ObjectOutputStream out = new ObjectOutputStream (baos); 428 out.writeObject(object); 429 out.close(); 430 431 ByteArrayInputStream bais = new ByteArrayInputStream (baos.toByteArray()); 432 ObjectInputStream in = new ObjectInputStream (bais); 433 Object obj = in.readObject(); 434 return obj; 435 } 436 437 443 public void invalidateReference(){ 444 this.container = null; 445 this.deploymentInfo = null; 446 this.isInvalidReference = true; 447 } 448 449 protected static void invalidateAllHandlers(Object key){ 450 HashSet set = (HashSet )liveHandleRegistry.remove(key); 451 if(set==null)return; 452 synchronized(set){ 453 Iterator handlers = set.iterator(); 454 while(handlers.hasNext()){ 455 BaseEjbProxyHandler aHandler = (BaseEjbProxyHandler)handlers.next(); 456 aHandler.invalidateReference(); 457 } 458 } 459 } 460 461 protected abstract Object _writeReplace(Object proxy) throws ObjectStreamException ; 462 463 464 protected static void registerHandler(Object key, BaseEjbProxyHandler handler){ 465 HashSet set = (HashSet )liveHandleRegistry.get(key); 466 if(set!=null){ 467 synchronized(set){ 468 set.add(handler); 469 } 470 }else{ 471 set = new HashSet (); 472 set.add(handler); 473 liveHandleRegistry.put(key, set); 474 } 475 } 476 477 public abstract org.openejb.ProxyInfo getProxyInfo(); 478 479 public boolean isLocal() { 480 return isLocal; 481 } 482 public void setLocal(boolean isLocal) { 483 this.isLocal = isLocal; 484 this.doIntraVmCopy = !isLocal; 485 } 486 } 487 | Popular Tags |