1 22 package org.jboss.ejb3; 23 24 import java.lang.reflect.Method ; 25 import java.util.HashMap ; 26 import java.util.Hashtable ; 27 import java.util.Map ; 28 29 import javax.ejb.EJBObject ; 30 import javax.ejb.Handle ; 31 import javax.ejb.LocalHome ; 32 import javax.ejb.RemoteHome ; 33 import org.jboss.aop.AspectManager; 34 import org.jboss.aop.Dispatcher; 35 import org.jboss.aop.MethodInfo; 36 import org.jboss.aop.advice.Interceptor; 37 import org.jboss.aop.joinpoint.Invocation; 38 import org.jboss.aop.joinpoint.InvocationResponse; 39 import org.jboss.aop.util.MethodHashing; 40 import org.jboss.aspects.asynch.FutureHolder; 41 import org.jboss.ejb3.interceptor.InterceptorInfoRepository; 42 import org.jboss.ejb3.remoting.IsLocalInterceptor; 43 import org.jboss.ejb3.stateful.StatefulContainerInvocation; 44 import org.jboss.logging.Logger; 45 import org.jboss.serial.io.MarshalledObjectForLocalCalls; 46 47 53 public abstract class SessionContainer extends EJBContainer 54 { 55 @SuppressWarnings ("unused") 56 private static final Logger log = Logger.getLogger(SessionContainer.class); 57 58 protected ProxyDeployer proxyDeployer; 59 protected Map clusterFamilies = new HashMap (); 60 61 public class InvokedMethod 62 { 63 public InvokedMethod(boolean localInterface, Method method) 64 { 65 isLocalInterface = localInterface; 66 this.method = method; 67 } 68 69 public boolean isLocalInterface; 70 public Method method; 71 } 72 73 protected ThreadLocalStack<InvokedMethod> invokedMethod = new ThreadLocalStack<InvokedMethod>(); 74 75 public SessionContainer(ClassLoader cl, String beanClassName, String ejbName, AspectManager manager, 76 Hashtable ctxProperties, InterceptorInfoRepository interceptorRepository, 77 Ejb3Deployment deployment) 78 { 79 super(Ejb3Module.BASE_EJB3_JMX_NAME + ",name=" + ejbName, manager, cl, beanClassName, ejbName, ctxProperties, interceptorRepository, deployment); 80 proxyDeployer = new ProxyDeployer(this); 81 } 82 83 public Class getInvokedBusinessInterface() 84 { 85 InvokedMethod method = invokedMethod.get(); 86 if (method == null) throw new IllegalStateException ("getInvokedBusinessInterface() being invoked outside of a business invocation"); 87 if (method.method == null) throw new IllegalStateException ("getInvokedBusinessInterface() being invoked outside of a business invocation"); 88 if (method.isLocalInterface) return method.method.getDeclaringClass(); 89 Class [] remoteInterfaces = ProxyFactoryHelper.getRemoteInterfaces(this); 90 for (Class intf : remoteInterfaces) 91 { 92 try 93 { 94 intf.getMethod(method.method.getName(), method.method.getParameterTypes()); 95 return intf; 96 } 97 catch (NoSuchMethodException ignored) 98 { 99 } 101 } 102 throw new IllegalStateException ("Unable to find geInvokedBusinessInterface()"); 103 } 104 105 @Override 106 public void instantiated() 107 { 108 super.instantiated(); 109 proxyDeployer.initializeRemoteBindingMetadata(); 110 proxyDeployer.initializeLocalBindingMetadata(); 111 } 112 113 @Override 114 public void processMetadata(DependencyPolicy dependencyPolicy) 115 { 116 super.processMetadata(dependencyPolicy); 117 } 118 119 public void start() throws Exception 120 { 121 super.start(); 122 Dispatcher.singleton.registerTarget(getObjectName().getCanonicalName(), this); 124 proxyDeployer.start(); 125 } 126 127 public Map getClusterFamilies() 128 { 129 return clusterFamilies; 130 } 131 132 public void stop() throws Exception 133 { 134 try 135 { 136 proxyDeployer.stop(); 137 } 138 catch (Exception ignore) 139 { 140 } 141 try 142 { 143 Dispatcher.singleton.unregisterTarget(getObjectName().getCanonicalName()); 144 } 145 catch (Exception ignore) 146 { 147 } 148 } 149 150 protected void createMethodMap() 151 { 152 super.createMethodMap(); 153 try 154 { 155 RemoteHome home = (RemoteHome ) resolveAnnotation(RemoteHome .class); 156 if (home != null) 157 { 158 Method [] declaredMethods = home.value().getMethods(); 159 for (int i = 0; i < declaredMethods.length; i++) 160 { 161 long hash = MethodHashing.methodHash(declaredMethods[i]); 162 advisedMethods.put(hash, declaredMethods[i]); 163 } 164 165 declaredMethods = javax.ejb.EJBObject .class.getMethods(); 166 for (int i = 0; i < declaredMethods.length; i++) 167 { 168 long hash = MethodHashing.methodHash(declaredMethods[i]); 169 advisedMethods.put(hash, declaredMethods[i]); 170 } 171 } 172 173 LocalHome localHome = (LocalHome ) resolveAnnotation(LocalHome .class); 174 if (localHome != null) 175 { 176 Method [] declaredMethods = localHome.value().getMethods(); 177 for (int i = 0; i < declaredMethods.length; i++) 178 { 179 long hash = MethodHashing.methodHash(declaredMethods[i]); 180 advisedMethods.put(hash, declaredMethods[i]); 181 } 182 183 declaredMethods = javax.ejb.EJBLocalObject .class.getMethods(); 184 for (int i = 0; i < declaredMethods.length; i++) 185 { 186 long hash = MethodHashing.methodHash(declaredMethods[i]); 187 advisedMethods.put(hash, declaredMethods[i]); 188 } 189 } 190 } 191 catch (Exception e) 192 { 193 throw new RuntimeException (e); 194 } 195 } 196 197 protected boolean isHomeMethod(Method method) 198 { 199 if (javax.ejb.EJBHome .class.isAssignableFrom(method.getDeclaringClass())) return true; 200 if (javax.ejb.EJBLocalHome .class.isAssignableFrom(method.getDeclaringClass())) return true; 201 return false; 202 } 203 204 protected boolean isEJBObjectMethod(Method method) 205 { 206 if (method.getDeclaringClass().getName().equals("javax.ejb.EJBObject")) 207 return true; 208 209 if (method.getDeclaringClass().getName().equals("javax.ejb.EJBLocalObject")) 210 return true; 211 212 return false; 213 } 214 215 protected boolean isHandleMethod(Method method) 216 { 217 if (method.getDeclaringClass().getName().equals("javax.ejb.Handle")) 218 return true; 219 220 return false; 221 } 222 223 public static InvocationResponse marshallException(Invocation invocation, Throwable exception, Map responseContext) throws Throwable 224 { 225 if (!invocation.getMetaData().hasTag(IsLocalInterceptor.IS_LOCAL)) throw exception; 226 227 InvocationResponse response = new InvocationResponse(); 228 response.setContextInfo(responseContext); 229 230 response.addAttachment(IsLocalInterceptor.IS_LOCAL_EXCEPTION, new MarshalledObjectForLocalCalls(exception)); 231 232 return response; 233 } 234 235 public static InvocationResponse marshallResponse(Invocation invocation, Object rtn, Map responseContext) 236 throws java.io.IOException 237 { 238 InvocationResponse response; 239 if (rtn != null && invocation.getMetaData().hasTag(IsLocalInterceptor.IS_LOCAL)) 241 { 242 response = new InvocationResponse(new MarshalledObjectForLocalCalls(rtn)); 243 } 244 else 245 { 246 response = new InvocationResponse(rtn); 247 } 248 response.setContextInfo(responseContext); 249 return response; 250 } 251 252 264 public Object invoke(ProxyFactory factory, Object id, Method method, Object args[], FutureHolder provider) throws Throwable 265 { 266 ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); 267 ThreadLocalENCFactory.push(enc); 268 try 269 { 270 long hash = MethodHashing.calculateHash(method); 271 MethodInfo info = (MethodInfo) methodInterceptors.get(hash); 272 if (info == null) 273 { 274 throw new RuntimeException ( 275 "Could not resolve beanClass method from proxy call: " 276 + method.toString()); 277 } 278 279 Method unadvisedMethod = info.getUnadvisedMethod(); 280 281 if (unadvisedMethod != null && isHomeMethod(unadvisedMethod)) 282 { 283 return invokeHomeMethod(factory, info, args); 284 } 285 else if (unadvisedMethod != null && isEJBObjectMethod(unadvisedMethod)) 286 { 287 return invokeEJBObjectMethod(factory, id, info, args); 288 } 289 290 Interceptor[] aspects = info.getInterceptors(); 291 EJBContainerInvocation nextInvocation = new StatefulContainerInvocation(info, aspects, id); 293 nextInvocation.setAdvisor(this); 294 nextInvocation.setArguments(args); 295 296 nextInvocation = populateInvocation(nextInvocation); 298 299 ProxyUtils.addLocalAsynchronousInfo(nextInvocation, provider); 300 try 301 { 302 invokedMethod.push(new InvokedMethod(true, method)); 303 return nextInvocation.invokeNext(); 304 } 305 finally 306 { 307 invokedMethod.pop(); 308 } 309 } 310 finally 311 { 312 Thread.currentThread().setContextClassLoader(oldLoader); 313 ThreadLocalENCFactory.pop(); 314 } 315 } 316 317 320 private Object invokeHomeMethod(ProxyFactory factory, MethodInfo info, Object args[]) throws Exception 321 { 322 Method unadvisedMethod = info.getUnadvisedMethod(); 323 if (unadvisedMethod.getName().equals("create")) 324 { 325 Class [] initParameterTypes = {}; 326 Object [] initParameterValues = {}; 327 if (unadvisedMethod.getParameterTypes().length > 0) 328 { 329 initParameterTypes = unadvisedMethod.getParameterTypes(); 330 initParameterValues = args; 331 } 332 333 Object id = createSession(initParameterTypes, initParameterValues); 334 335 Object proxy = factory.createProxy(id); 336 337 return proxy; 338 } 339 else if (unadvisedMethod.getName().equals("remove")) 340 { 341 if(args[0] instanceof Handle ) 342 removeHandle((Handle ) args[0]); 343 else 344 destroySession(args[0]); 345 346 return null; 347 } 348 else 349 { 350 throw new IllegalArgumentException ("illegal home method " + unadvisedMethod); 351 } 352 } 353 354 361 abstract protected Object createSession(Class initParameterTypes[], Object initParameterValues[]); 362 363 368 protected void destroySession(Object id) 369 { 370 throw new RuntimeException ("NYI"); 371 } 372 373 protected Object invokeEJBObjectMethod(ProxyFactory factory, Object id, MethodInfo info, Object args[]) throws Exception 374 { 375 Method unadvisedMethod = info.getUnadvisedMethod(); 376 if(unadvisedMethod.getName().equals("getEJBHome")) 377 { 378 return factory.createHomeProxy(); 379 } 380 if(unadvisedMethod.getName().equals("getPrimaryKey")) 381 { 382 return id; 383 } 384 if(unadvisedMethod.getName().equals("isIdentical")) 385 { 386 if(id == null) 388 return false; 389 390 EJBObject bean = (EJBObject ) args[0]; 391 392 Object primaryKey = bean.getPrimaryKey(); 393 if(primaryKey == null) 394 return false; 395 396 boolean isIdentical = id.equals(primaryKey); 397 398 return isIdentical; 399 } 400 if (unadvisedMethod.getName().equals("remove")) 401 { 402 destroySession(id); 403 404 return null; 405 } 406 throw new RuntimeException ("NYI"); 407 } 408 409 415 protected EJBContainerInvocation populateInvocation(EJBContainerInvocation invocation) 416 { 417 return invocation; 418 } 419 420 abstract protected void removeHandle(Handle handle) throws Exception ; 421 } | Popular Tags |