/* */ package org.jboss.ejb3.interceptor;
/* */
/* */ import java.lang.annotation.Annotation;
/* */ import java.lang.reflect.Method;
/* */ import java.lang.reflect.Modifier;
/* */ import java.rmi.RemoteException;
/* */ import java.util.ArrayList;
/* */ import java.util.Collection;
/* */ import java.util.Collections;
/* */ import java.util.Comparator;
/* */ import java.util.HashMap;
/* */ import java.util.HashSet;
/* */ import java.util.Iterator;
/* */ import java.util.LinkedHashSet;
/* */ import java.util.List;
/* */ import java.util.Set;
/* */ import java.util.concurrent.ConcurrentHashMap;
/* */ import java.util.concurrent.ConcurrentMap;
/* */ import javax.annotation.PostConstruct;
/* */ import javax.annotation.PreDestroy;
/* */ import javax.ejb.CreateException;
/* */ import javax.ejb.PostActivate;
/* */ import javax.ejb.PrePassivate;
/* */ import javax.interceptor.AroundInvoke;
/* */ import javax.interceptor.ExcludeClassInterceptors;
/* */ import javax.interceptor.ExcludeDefaultInterceptors;
/* */ import javax.interceptor.Interceptors;
/* */ import javax.interceptor.InvocationContext;
/* */ import org.jboss.ejb3.EJBContainer;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.metadata.ejb.jboss.JBossAssemblyDescriptorMetaData;
/* */ import org.jboss.metadata.ejb.jboss.JBossMetaData;
/* */ import org.jboss.metadata.ejb.spec.AroundInvokeMetaData;
/* */ import org.jboss.metadata.ejb.spec.AroundInvokesMetaData;
/* */ import org.jboss.metadata.ejb.spec.InterceptorBindingMetaData;
/* */ import org.jboss.metadata.ejb.spec.InterceptorBindingsMetaData;
/* */ import org.jboss.metadata.ejb.spec.InterceptorMetaData;
/* */ import org.jboss.metadata.ejb.spec.InterceptorOrderMetaData;
/* */ import org.jboss.metadata.ejb.spec.InterceptorsMetaData;
/* */ import org.jboss.metadata.ejb.spec.MethodParametersMetaData;
/* */ import org.jboss.metadata.ejb.spec.NamedMethodMetaData;
/* */ import org.jboss.metadata.javaee.spec.LifecycleCallbackMetaData;
/* */ import org.jboss.metadata.javaee.spec.LifecycleCallbacksMetaData;
/* */
/* */ public class InterceptorInfoRepository
/* */ {
/* */ private static Logger log;
/* */ private ClassLoader classLoader;
/* 83 */ private Set<String> beanClasses = new HashSet();
/* */ private InterceptorsMetaData interceptorsXml;
/* */ private InterceptorBindingsMetaData bindingsXml;
/* 89 */ private ConcurrentMap<Class<?>, InterceptorInfo> infos = new ConcurrentHashMap();
/* */
/* 91 */ private ConcurrentMap<String, InterceptorInfo> ejbInfos = new ConcurrentHashMap();
/* */
/* 93 */ private LinkedHashSet<InterceptorInfo> defaultInterceptors = null;
/* */
/* 95 */ private InterceptorSorter sorter = new InterceptorSorter(null);
/* */
/* */ public InterceptorInfoRepository(ClassLoader classLoader)
/* */ {
/* 99 */ assert (classLoader != null) : "classLoader is null";
/* */
/* 101 */ this.classLoader = classLoader;
/* */ }
/* */
/* */ public void initialise(JBossMetaData dd)
/* */ {
/* 106 */ this.interceptorsXml = dd.getInterceptors();
/* */
/* 108 */ if (dd.getAssemblyDescriptor() != null)
/* */ {
/* 110 */ this.bindingsXml = dd.getAssemblyDescriptor().getInterceptorBindings();
/* */ }
/* */
/* 113 */ initialiseInfosFromXml();
/* 114 */ initialiseDefaultInterceptors();
/* */ }
/* */
/* */ public void addBeanClass(String classname)
/* */ {
/* 119 */ this.beanClasses.add(classname);
/* */ }
/* */
/* */ public InterceptorInfo getInterceptorInfo(Class clazz)
/* */ {
/* 124 */ initialiseInfosFromXml();
/* 125 */ return (InterceptorInfo)this.infos.get(clazz);
/* */ }
/* */
/* */ public HashSet<InterceptorInfo> getDefaultInterceptors()
/* */ {
/* 130 */ return this.defaultInterceptors;
/* */ }
/* */
/* */ public boolean hasDefaultInterceptors()
/* */ {
/* 135 */ return this.defaultInterceptors.size() > 0;
/* */ }
/* */
/* */ public ArrayList<InterceptorInfo> getClassInterceptors(EJBContainer container)
/* */ {
/* 140 */ Interceptors interceptors = (Interceptors)container.resolveAnnotation(Interceptors.class);
/* */
/* 142 */ ArrayList infos = getInterceptorsFromAnnotation(container, interceptors);
/* */
/* 144 */ return infos;
/* */ }
/* */
/* */ public ArrayList<InterceptorInfo> getMethodInterceptors(EJBContainer container, Method m)
/* */ {
/* 149 */ Interceptors interceptors = (Interceptors)container.resolveAnnotation(m, Interceptors.class);
/* */
/* 151 */ ArrayList infos = getInterceptorsFromAnnotation(container, interceptors);
/* */
/* 153 */ return infos;
/* */ }
/* */
/* */ public Method[] getBeanClassAroundInvokes(EJBContainer container)
/* */ {
/* 158 */ return getBeanClassInterceptors(container, AroundInvoke.class);
/* */ }
/* */
/* */ public Method[] getBeanClassPostConstructs(EJBContainer container)
/* */ {
/* 163 */ return getBeanClassInterceptors(container, PostConstruct.class);
/* */ }
/* */
/* */ public Method[] getBeanClassPostActivates(EJBContainer container)
/* */ {
/* 168 */ return getBeanClassInterceptors(container, PostActivate.class);
/* */ }
/* */
/* */ public Method[] getBeanClassPrePassivates(EJBContainer container)
/* */ {
/* 173 */ return getBeanClassInterceptors(container, PrePassivate.class);
/* */ }
/* */
/* */ public Method[] getBeanClassPreDestroys(EJBContainer container)
/* */ {
/* 178 */ return getBeanClassInterceptors(container, PreDestroy.class);
/* */ }
/* */
/* */ private Method[] getBeanClassInterceptors(EJBContainer container, Class type)
/* */ {
/* 183 */ InterceptorInfo info = getOrInitialiseFromAnnotations(container);
/* 184 */ return getMethodsForEvent(info, type);
/* */ }
/* */
/* */ public InterceptorInfo[] getBusinessInterceptors(EJBContainer container, Method method)
/* */ {
/* 189 */ return getInterceptors(container, AroundInvoke.class, method);
/* */ }
/* */
/* */ public InterceptorInfo[] getPostConstructInterceptors(EJBContainer container)
/* */ {
/* 194 */ return getInterceptors(container, PostConstruct.class, null);
/* */ }
/* */
/* */ public InterceptorInfo[] getPostActivateInterceptors(EJBContainer container)
/* */ {
/* 199 */ return getInterceptors(container, PostActivate.class, null);
/* */ }
/* */
/* */ public InterceptorInfo[] getPrePassivateInterceptors(EJBContainer container)
/* */ {
/* 204 */ return getInterceptors(container, PrePassivate.class, null);
/* */ }
/* */
/* */ public InterceptorInfo[] getPreDestroyInterceptors(EJBContainer container)
/* */ {
/* 209 */ return getInterceptors(container, PreDestroy.class, null);
/* */ }
/* */
/* */ private InterceptorInfo[] getInterceptors(EJBContainer container, Class type, Method method)
/* */ {
/* 214 */ ArrayList interceptors = new ArrayList();
/* */
/* 216 */ if (!hasAnnotation(container, ExcludeDefaultInterceptors.class, method))
/* */ {
/* 218 */ HashSet infos = getDefaultInterceptors();
/* 219 */ if (infos != null)
/* */ {
/* 221 */ interceptors.addAll(trimUnwanted(infos, type));
/* */ }
/* 223 */ this.sorter.sortDefaultInterceptors(container, interceptors);
/* */ }
/* */
/* 227 */ if (!hasAnnotation(container, ExcludeClassInterceptors.class, method))
/* */ {
/* 229 */ List infos = container.getClassInterceptors();
/* 230 */ if (infos != null)
/* */ {
/* 232 */ interceptors.addAll(trimUnwanted(infos, type));
/* */ }
/* */
/* 235 */ if (type != AroundInvoke.class)
/* */ {
/* 237 */ List methodOnlyInterceptors = getMethodOnlyInterceptorsForLifecycle(container, type, interceptors);
/* 238 */ if (infos != null)
/* 239 */ interceptors.addAll(methodOnlyInterceptors);
/* */ }
/* 241 */ this.sorter.sortClassInterceptors(container, interceptors);
/* */ }
/* */
/* 244 */ if (type == AroundInvoke.class)
/* */ {
/* 246 */ List infos = getMethodInterceptors(container, method);
/* 247 */ if (infos != null)
/* 248 */ interceptors.addAll(trimUnwanted(infos, type));
/* 249 */ this.sorter.sortMethodInterceptors(container, method, interceptors);
/* */ }
/* */
/* 252 */ InterceptorInfo[] ints = (InterceptorInfo[])interceptors.toArray(new InterceptorInfo[interceptors.size()]);
/* 253 */ return ints;
/* */ }
/* */
/* */ private List<InterceptorInfo> getMethodOnlyInterceptorsForLifecycle(EJBContainer container, Class type, List<InterceptorInfo> infos)
/* */ {
/* 258 */ HashSet methodLevelInterceptors = (HashSet)container.getApplicableInterceptors().clone();
/* */
/* 260 */ for (InterceptorInfo info : infos)
/* */ {
/* 262 */ if (methodLevelInterceptors.contains(info))
/* */ {
/* 264 */ methodLevelInterceptors.remove(info);
/* */ }
/* */ }
/* */
/* 268 */ if (this.defaultInterceptors != null)
/* */ {
/* 270 */ for (InterceptorInfo info : this.defaultInterceptors)
/* */ {
/* 272 */ if (methodLevelInterceptors.contains(info))
/* */ {
/* 274 */ methodLevelInterceptors.remove(info);
/* */ }
/* */ }
/* */ }
/* */
/* 279 */ List trimmedInfos = trimUnwanted(methodLevelInterceptors, type);
/* 280 */ return trimmedInfos;
/* */ }
/* */
/* */ private boolean hasAnnotation(EJBContainer container, Class annotation, Method method)
/* */ {
/* 285 */ if (container.resolveAnnotation(annotation) != null)
/* */ {
/* 287 */ return true;
/* */ }
/* */
/* 290 */ if (method != null)
/* */ {
/* 292 */ return container.resolveAnnotation(method, annotation) != null;
/* */ }
/* */
/* 295 */ return false;
/* */ }
/* */
/* */ private List<InterceptorInfo> trimUnwanted(Collection<InterceptorInfo> interceptors, Class type)
/* */ {
/* 300 */ ArrayList ints = new ArrayList(interceptors.size());
/* 301 */ ints.addAll(interceptors);
/* */
/* 303 */ for (Iterator it = ints.iterator(); it.hasNext(); )
/* */ {
/* 305 */ InterceptorInfo info = (InterceptorInfo)it.next();
/* 306 */ if (!hasMethodsForEvent(info, type))
/* */ {
/* 308 */ it.remove();
/* */ }
/* */ }
/* */
/* 312 */ return ints;
/* */ }
/* */
/* */ private boolean hasMethodsForEvent(InterceptorInfo info, Class type)
/* */ {
/* 317 */ return getMethodsForEvent(info, type) != null;
/* */ }
/* */
/* */ private Method[] getMethodsForEvent(InterceptorInfo info, Class type)
/* */ {
/* 322 */ if (type == AroundInvoke.class)
/* 323 */ return info.getAroundInvokes();
/* 324 */ if (type == PostConstruct.class)
/* 325 */ return info.getPostConstructs();
/* 326 */ if (type == PostActivate.class)
/* 327 */ return info.getPostActivates();
/* 328 */ if (type == PrePassivate.class)
/* 329 */ return info.getPrePassivates();
/* 330 */ if (type == PreDestroy.class)
/* 331 */ return info.getPreDestroys();
/* 332 */ return null;
/* */ }
/* */
/* */ private ArrayList<InterceptorInfo> getInterceptorsFromAnnotation(EJBContainer container, Interceptors interceptors)
/* */ {
/* 338 */ ArrayList inters = new ArrayList();
/* 339 */ if (interceptors == null) {
/* 340 */ return inters;
/* */ }
/* 342 */ for (Class clazz : interceptors.value())
/* */ {
/* 344 */ InterceptorInfo info = getOrInitialiseFromAnnotations(clazz);
/* 345 */ validateInterceptorForContainer(container, info.getClazz());
/* 346 */ inters.add(info);
/* */ }
/* */
/* 349 */ return inters;
/* */ }
/* */
/* */ private void validateInterceptorForContainer(EJBContainer container, Class interceptor)
/* */ {
/* 354 */ if (this.beanClasses.contains(interceptor.getName()))
/* */ {
/* 356 */ if (!interceptor.equals(container.getClazz()))
/* */ {
/* 358 */ throw new RuntimeException("Bean class " + interceptor.getName() + " cannot be used as an interceptor for " + container.getEjbName());
/* */ }
/* */ }
/* */ }
/* */
/* */ private void initialiseInfosFromXml()
/* */ {
/* */ HashMap initialisers;
/* 366 */ if (this.interceptorsXml != null)
/* */ {
/* 369 */ initialisers = new HashMap();
/* 370 */ for (InterceptorMetaData xml : this.interceptorsXml)
/* */ {
/* 372 */ XmlInitialiser init = new XmlInitialiser(xml);
/* 373 */ initialisers.put(xml.getInterceptorClass(), init);
/* */ }
/* */
/* 377 */ for (InterceptorMetaData xml : this.interceptorsXml)
/* */ {
/* 379 */ String clazz = xml.getInterceptorClass();
/* 380 */ initialiseSuperClassesFirstFromXmlOrAnnotations(initialisers, clazz);
/* */ }
/* */ }
/* */ }
/* */
/* */ private InterceptorInfo initialiseSuperClassesFirstFromXmlOrAnnotations(HashMap<String, AnnotationInitialiser> initialisers, String superClassName)
/* */ {
/* 389 */ if ("java.lang.Object".equals(superClassName))
/* */ {
/* 391 */ return null;
/* */ }
/* */
/* 394 */ AnnotationInitialiser initialiser = (AnnotationInitialiser)initialisers.get(superClassName);
/* 395 */ if (initialiser == null)
/* */ {
/* 397 */ initialiser = new AnnotationInitialiser(superClassName, InterceptorSignatureValidator.instance);
/* 398 */ initialisers.put(initialiser.getClazz().getName(), initialiser);
/* */ }
/* 400 */ InterceptorInfo superInfo = initialiseSuperClassesFirstFromXmlOrAnnotations(initialisers, initialiser.getClazz().getSuperclass().getName());
/* */
/* 403 */ InterceptorInfo info = initialiser.getInfo();
/* 404 */ info.calculateHierarchy(superInfo);
/* 405 */ this.infos.put(info.getClazz(), info);
/* 406 */ return info;
/* */ }
/* */
/* */ private void initialiseDefaultInterceptors()
/* */ {
/* 414 */ this.defaultInterceptors = new LinkedHashSet();
/* */
/* 416 */ if (this.bindingsXml != null)
/* */ {
/* 418 */ for (InterceptorBindingMetaData bindingXml : this.bindingsXml)
/* */ {
/* 420 */ if ((bindingXml.getEjbName().equals("*")) && (bindingXml.getMethod() == null))
/* */ {
/* 422 */ for (String classname : bindingXml.getInterceptorClasses())
/* */ {
/* 424 */ if (this.beanClasses.contains(classname))
/* */ {
/* 426 */ throw new RuntimeException("Bean class defined in default binding " + classname);
/* */ }
/* 428 */ InterceptorInfo info = getOrInitialiseFromAnnotations(classname);
/* 429 */ this.defaultInterceptors.add(info);
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ private InterceptorInfo getOrInitialiseFromAnnotations(String classname)
/* */ {
/* 438 */ Class clazz = loadClass(classname);
/* 439 */ return getOrInitialiseFromAnnotations(clazz);
/* */ }
/* */
/* */ private InterceptorInfo getOrInitialiseFromAnnotations(Class clazz)
/* */ {
/* 444 */ InterceptorInfo info = (InterceptorInfo)this.infos.get(clazz);
/* */
/* 446 */ if (info == null)
/* */ {
/* 448 */ synchronized (this)
/* */ {
/* 450 */ info = (InterceptorInfo)this.infos.get(clazz);
/* 451 */ if (info == null)
/* */ {
/* 453 */ info = initialiseFromAnnotations(clazz);
/* 454 */ this.infos.put(clazz, info);
/* */ }
/* */ }
/* */ }
/* */
/* 459 */ return info;
/* */ }
/* */
/* */ private InterceptorInfo initialiseFromAnnotations(Class clazz)
/* */ {
/* 464 */ InterceptorInfo superInfo = null;
/* 465 */ if (clazz.getSuperclass() != Object.class)
/* */ {
/* 467 */ superInfo = getOrInitialiseFromAnnotations(clazz.getSuperclass());
/* */ }
/* */
/* 470 */ AnnotationInitialiser init = new AnnotationInitialiser(clazz, InterceptorSignatureValidator.instance);
/* 471 */ InterceptorInfo info = init.getInfo();
/* 472 */ info.calculateHierarchy(superInfo);
/* 473 */ return info;
/* */ }
/* */
/* */ private InterceptorInfo getOrInitialiseFromAnnotations(EJBContainer container)
/* */ {
/* 478 */ InterceptorInfo info = (InterceptorInfo)this.ejbInfos.get(container.getEjbName());
/* */
/* 480 */ if (info == null)
/* */ {
/* 482 */ synchronized (this)
/* */ {
/* 484 */ info = (InterceptorInfo)this.ejbInfos.get(container.getEjbName());
/* 485 */ if (info == null)
/* */ {
/* 487 */ info = initialiseFromAnnotations(container);
/* 488 */ this.ejbInfos.put(container.getEjbName(), info);
/* */ }
/* */ }
/* */ }
/* */
/* 493 */ return info;
/* */ }
/* */
/* */ private InterceptorInfo initialiseFromAnnotations(EJBContainer container)
/* */ {
/* 500 */ InterceptorInfo superInfo = initialiseContainerSuperClassFromAnnotationsOnly(container.getClazz().getSuperclass());
/* 501 */ AnnotationInitialiser init = new ContainerInitialiser(container);
/* 502 */ InterceptorInfo info = init.getInfo();
/* 503 */ info.calculateHierarchy(superInfo);
/* 504 */ return info;
/* */ }
/* */
/* */ private InterceptorInfo initialiseContainerSuperClassFromAnnotationsOnly(Class clazz)
/* */ {
/* 509 */ InterceptorInfo superInfo = null;
/* 510 */ if (clazz != Object.class)
/* */ {
/* 512 */ superInfo = initialiseContainerSuperClassFromAnnotationsOnly(clazz.getSuperclass());
/* */ }
/* */
/* 515 */ AnnotationInitialiser init = new AnnotationInitialiser(clazz, BeanSignatureValidator.instance);
/* 516 */ InterceptorInfo info = init.getInfo();
/* 517 */ info.calculateHierarchy(superInfo);
/* 518 */ return info;
/* */ }
/* */
/* */ private Class<?> loadClass(String name)
/* */ {
/* */ try
/* */ {
/* 526 */ if (log.isTraceEnabled())
/* 527 */ log.trace("Loading interceptor " + name + " from " + this.classLoader);
/* 528 */ return this.classLoader.loadClass(name);
/* */ }
/* */ catch (ClassNotFoundException e) {
/* */ }
/* 532 */ throw new RuntimeException("Interceptor class not found: " + name + " in class loader " + this.classLoader, e);
/* */ }
/* */
/* */ private static boolean checkExceptions(Class<?>[] allowedExceptions, Method method)
/* */ {
/* 538 */ for (Class exception : method.getExceptionTypes())
/* */ {
/* 540 */ boolean isAllowed = false;
/* 541 */ for (Class allowed : allowedExceptions)
/* */ {
/* 543 */ if (allowed.isAssignableFrom(exception))
/* 544 */ isAllowed = true;
/* */ }
/* 546 */ if (isAllowed)
/* */ continue;
/* 548 */ log.warn("Illegal exception '" + exception.getName() + "' in lifecycle signature (EJB3 12.4.2): " + method);
/* 549 */ return false;
/* */ }
/* */
/* 552 */ return true;
/* */ }
/* */
/* */ public static boolean checkValidBusinessSignature(Method method)
/* */ {
/* 557 */ int modifiers = method.getModifiers();
/* */
/* 559 */ if (!Modifier.isStatic(modifiers))
/* */ {
/* 561 */ if (method.getReturnType().equals(Object.class))
/* */ {
/* 563 */ Class[] params = method.getParameterTypes();
/* 564 */ if ((params.length == 1) && (params[0].equals(InvocationContext.class)))
/* */ {
/* 566 */ Class[] exceptions = method.getExceptionTypes();
/* 567 */ if ((exceptions.length == 1) && (exceptions[0].equals(Exception.class)))
/* */ {
/* 569 */ return true;
/* */ }
/* */ }
/* */ }
/* */ }
/* 574 */ return false;
/* */ }
/* */
/* */ public static boolean checkValidLifecycleSignature(Method method)
/* */ {
/* 579 */ int modifiers = method.getModifiers();
/* */
/* 581 */ if (!Modifier.isStatic(modifiers))
/* */ {
/* 583 */ if (method.getReturnType().equals(Void.TYPE))
/* */ {
/* 585 */ Class[] params = method.getParameterTypes();
/* 586 */ if ((params.length == 1) && (params[0].equals(InvocationContext.class)))
/* */ {
/* 588 */ return true;
/* */ }
/* */ }
/* */ }
/* 592 */ return false;
/* */ }
/* */
/* */ public static boolean checkValidBeanLifecycleSignature(Method method)
/* */ {
/* 605 */ int modifiers = method.getModifiers();
/* 606 */ if (method.getName().equals("ejbCreate"))
/* */ {
/* 609 */ if ((!Modifier.isStatic(modifiers)) && (method.getReturnType().equals(Void.TYPE)) && (method.getExceptionTypes().length <= 1))
/* */ {
/* 613 */ return checkExceptions(new Class[] { RuntimeException.class, CreateException.class, RemoteException.class }, method);
/* */ }
/* */
/* */ }
/* 617 */ else if ((!Modifier.isStatic(modifiers)) && (method.getReturnType().equals(Void.TYPE)) && (method.getParameterTypes().length == 0))
/* */ {
/* 621 */ return checkExceptions(new Class[] { RuntimeException.class, RemoteException.class }, method);
/* */ }
/* */
/* 624 */ return false;
/* */ }
/* */
/* */ public static String simpleType(Class type)
/* */ {
/* 629 */ Class ret = type;
/* 630 */ if (ret.isArray())
/* */ {
/* 632 */ Class arr = ret;
/* 633 */ String array = "";
/* 634 */ while (arr.isArray())
/* */ {
/* 636 */ array = array + "[]";
/* 637 */ arr = arr.getComponentType();
/* */ }
/* 639 */ return arr.getName() + array;
/* */ }
/* 641 */ return ret.getName();
/* */ }
/* */
/* */ static
/* */ {
/* 79 */ log = Logger.getLogger(InterceptorInfoRepository.class);
/* */ }
/* */
/* */ private class InterceptorComparator
/* */ implements Comparator<InterceptorInfo>
/* */ {
/* */ List<String> ordered;
/* */
/* */ InterceptorComparator(InterceptorOrderMetaData ordered)
/* */ {
/* 1119 */ assert (ordered != null) : "ordered is null";
/* */
/* 1121 */ this.ordered = new ArrayList(ordered);
/* */ }
/* */
/* */ public int compare(InterceptorInfo o1, InterceptorInfo o2)
/* */ {
/* 1126 */ int pos1 = this.ordered.indexOf(o1.getClazz().getName());
/* 1127 */ int pos2 = this.ordered.indexOf(o2.getClazz().getName());
/* */
/* 1130 */ if (pos1 < 0) pos1 = 2147483647;
/* 1131 */ if (pos2 < 0) pos2 = 2147483647;
/* */
/* 1133 */ if (pos1 < pos2)
/* */ {
/* 1135 */ return -1;
/* */ }
/* 1137 */ if (pos1 > pos2)
/* */ {
/* 1139 */ return 1;
/* */ }
/* */
/* 1143 */ return 0;
/* */ }
/* */ }
/* */
/* */ private class InterceptorSorter
/* */ {
/* */ boolean initialised;
/* */ List<InterceptorBindingMetaData> orderedBindings;
/* */
/* */ private InterceptorSorter()
/* */ {
/* */ }
/* */
/* */ private void initialise()
/* */ {
/* 929 */ if (!this.initialised)
/* */ {
/* 931 */ synchronized (this)
/* */ {
/* 933 */ if (InterceptorInfoRepository.this.bindingsXml != null)
/* */ {
/* 935 */ for (InterceptorBindingMetaData binding : InterceptorInfoRepository.this.bindingsXml)
/* */ {
/* 937 */ if (binding.isTotalOrdering())
/* */ {
/* 940 */ HashSet names = new HashSet();
/* 941 */ for (String className : binding.getInterceptorOrder())
/* */ {
/* 943 */ if (names.contains(className))
/* */ {
/* 945 */ throw new RuntimeException(className + " occurs more than once in ordered binding " + getInterceptorBindingString(binding));
/* */ }
/* */
/* 948 */ names.add(className);
/* */ }
/* */
/* 951 */ if (this.orderedBindings == null)
/* */ {
/* 953 */ this.orderedBindings = new ArrayList();
/* */ }
/* 955 */ this.orderedBindings.add(binding);
/* */ }
/* */ }
/* */ }
/* */ }
/* 960 */ InterceptorInfoRepository.log.trace("orderedBindings = " + this.orderedBindings);
/* 961 */ this.initialised = true;
/* */ }
/* */ }
/* */
/* */ void sortDefaultInterceptors(EJBContainer container, ArrayList<InterceptorInfo> infos)
/* */ {
/* 967 */ initialise();
/* 968 */ if (this.orderedBindings == null) return;
/* 969 */ InterceptorOrderMetaData bindingOrder = null;
/* 970 */ for (InterceptorBindingMetaData binding : this.orderedBindings)
/* */ {
/* 972 */ if (binding.getEjbName().equals("*"))
/* */ {
/* 974 */ if (bindingOrder != null)
/* */ {
/* 976 */ throw new RuntimeException("There should only be one interceptor-binding specifying the order of default interceptors " + getInterceptorBindingString(binding));
/* */ }
/* */
/* 979 */ bindingOrder = binding.getInterceptorOrder();
/* */ }
/* */ }
/* 982 */ sortInterceptors(infos, bindingOrder);
/* */ }
/* */
/* */ void sortClassInterceptors(EJBContainer container, ArrayList<InterceptorInfo> infos)
/* */ {
/* 987 */ initialise();
/* 988 */ if (this.orderedBindings == null) return;
/* 989 */ InterceptorOrderMetaData bindingOrder = null;
/* 990 */ for (InterceptorBindingMetaData binding : this.orderedBindings)
/* */ {
/* 992 */ if (binding.getMethod() != null)
/* */ continue;
/* 994 */ if (binding.getEjbName().equals(container.getEjbName()))
/* */ {
/* 996 */ if (bindingOrder != null)
/* */ {
/* 998 */ throw new RuntimeException("There should only be one interceptor-binding specifying the order of class interceptors: " + getInterceptorBindingString(binding));
/* */ }
/* */
/* 1001 */ bindingOrder = binding.getInterceptorOrder();
/* */ }
/* */ }
/* 1004 */ sortInterceptors(infos, bindingOrder);
/* */ }
/* */
/* */ void sortMethodInterceptors(EJBContainer container, Method method, ArrayList<InterceptorInfo> infos)
/* */ {
/* 1009 */ initialise();
/* 1010 */ if (this.orderedBindings == null) return;
/* 1011 */ InterceptorOrderMetaData methodNoParamsOrder = null;
/* 1012 */ InterceptorOrderMetaData methodParamsOrder = null;
/* 1013 */ for (InterceptorBindingMetaData binding : this.orderedBindings)
/* */ {
/* 1015 */ if (binding.getEjbName().equals(container.getEjbName()))
/* */ {
/* 1017 */ NamedMethodMetaData bindingMethod = binding.getMethod();
/* 1018 */ if (bindingMethod != null)
/* */ {
/* 1020 */ if (bindingMethod.getMethodParams() == null)
/* */ {
/* 1022 */ if (methodNoParamsOrder != null)
/* */ {
/* 1024 */ throw new RuntimeException("There should only be one interceptor-binding specifying the order of method interceptors: " + getInterceptorBindingString(binding));
/* */ }
/* */
/* 1027 */ methodNoParamsOrder = binding.getInterceptorOrder();
/* */ }
/* */ else
/* */ {
/* 1031 */ Class[] params = method.getParameterTypes();
/* 1032 */ List methodParams = bindingMethod.getMethodParams();
/* 1033 */ if (methodParams.size() == params.length)
/* */ {
/* 1035 */ boolean matches = true;
/* 1036 */ for (int i = 0; i < params.length; i++)
/* */ {
/* 1038 */ if (InterceptorInfoRepository.simpleType(params[i]).equals(methodParams.get(i)))
/* */ continue;
/* 1040 */ matches = false;
/* 1041 */ break;
/* */ }
/* */
/* 1045 */ if (matches)
/* */ {
/* 1047 */ if (methodParamsOrder != null)
/* */ {
/* 1049 */ boolean first = false;
/* 1050 */ StringBuffer paramBuf = new StringBuffer();
/* 1051 */ paramBuf.append("(");
/* 1052 */ for (String par : methodParams)
/* */ {
/* 1054 */ if (!first) paramBuf.append(",");
/* 1055 */ paramBuf.append(par);
/* */ }
/* 1057 */ paramBuf.append(")");
/* 1058 */ throw new RuntimeException("There should only be one interceptor-binding specifying the order of method interceptors: " + getInterceptorBindingString(binding));
/* */ }
/* */
/* 1062 */ methodParamsOrder = binding.getInterceptorOrder();
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* 1070 */ if (methodParamsOrder != null)
/* */ {
/* 1072 */ sortInterceptors(infos, methodParamsOrder);
/* */ }
/* */ else
/* */ {
/* 1077 */ sortInterceptors(infos, methodNoParamsOrder);
/* */ }
/* */ }
/* */
/* */ void sortInterceptors(ArrayList<InterceptorInfo> infos, InterceptorOrderMetaData interceptorOrder)
/* */ {
/* 1083 */ if (interceptorOrder == null) return;
/* 1084 */ Collections.sort(infos, new InterceptorInfoRepository.InterceptorComparator(InterceptorInfoRepository.this, interceptorOrder));
/* */ }
/* */
/* */ String getInterceptorBindingString(InterceptorBindingMetaData binding)
/* */ {
/* 1089 */ StringBuffer buf = new StringBuffer();
/* */
/* 1091 */ buf.append(binding.getEjbName());
/* 1092 */ NamedMethodMetaData method = binding.getMethod();
/* 1093 */ if (method != null)
/* */ {
/* 1095 */ buf.append("." + method.getMethodName());
/* 1096 */ MethodParametersMetaData methodParams = method.getMethodParams();
/* 1097 */ if (methodParams != null)
/* */ {
/* 1099 */ buf.append("(");
/* 1100 */ for (int i = 0; i < methodParams.size(); )
/* */ {
/* 1102 */ if (i == 0) buf.append(",");
/* 1103 */ buf.append((String)methodParams.get(i));
/* */ }
/* 1105 */ buf.append(")");
/* */ }
/* */ }
/* */
/* 1109 */ return buf.toString();
/* */ }
/* */ }
/* */
/* */ private class XmlInitialiser extends InterceptorInfoRepository.AnnotationInitialiser
/* */ {
/* */ InterceptorMetaData xml;
/* */
/* */ XmlInitialiser(InterceptorMetaData xml)
/* */ {
/* 820 */ super(xml.getInterceptorClass(), InterceptorInfoRepository.InterceptorSignatureValidator.instance);
/* 821 */ this.xml = xml;
/* */ }
/* */
/* */ InterceptorInfo getInfo()
/* */ {
/* 826 */ this.info.setAroundInvoke(findInterceptorMethodFromXml("around-invoke-method", this.xml.getAroundInvokes()));
/* 827 */ this.info.setPostConstruct(findInterceptorMethodFromXml("post-construct-method", this.xml.getPostConstructs()));
/* 828 */ this.info.setPostActivate(findInterceptorMethodFromXml("post-activate-method", this.xml.getPostActivates()));
/* 829 */ this.info.setPreDestroy(findInterceptorMethodFromXml("pre-destroy-method", this.xml.getPreDestroys()));
/* 830 */ this.info.setPrePassivate(findInterceptorMethodFromXml("pre-passivate-method", this.xml.getPrePassivates()));
/* 831 */ super.getInfo();
/* 832 */ this.info.setXml(this.xml);
/* 833 */ return this.info;
/* */ }
/* */
/* */ Method findInterceptorMethodFromXml(String lookingFor, AroundInvokesMetaData aroundInvokes)
/* */ {
/* 838 */ if (aroundInvokes == null)
/* 839 */ return null;
/* 840 */ if (aroundInvokes.size() != 1) {
/* 841 */ throw new RuntimeException("NYI");
/* */ }
/* 843 */ AroundInvokeMetaData aroundInvoke = (AroundInvokeMetaData)aroundInvokes.get(0);
/* 844 */ return findInterceptorMethodFromXml(lookingFor, aroundInvoke.getClassName(), aroundInvoke.getMethodName());
/* */ }
/* */
/* */ Method findInterceptorMethodFromXml(String lookingFor, LifecycleCallbacksMetaData lifecycleCallbacks)
/* */ {
/* 849 */ if (lifecycleCallbacks == null)
/* 850 */ return null;
/* 851 */ if (lifecycleCallbacks.size() != 1) {
/* 852 */ throw new RuntimeException("NYI");
/* */ }
/* 854 */ LifecycleCallbackMetaData lifecycleCallback = (LifecycleCallbackMetaData)lifecycleCallbacks.get(0);
/* 855 */ return findInterceptorMethodFromXml(lookingFor, lifecycleCallback.getClassName(), lifecycleCallback.getMethodName());
/* */ }
/* */
/* */ Method findInterceptorMethodFromXml(String lookingFor, String className, String methodName)
/* */ {
/* 860 */ if (this.xml == null)
/* 861 */ return null;
/* */ Class cls;
/* */ Class cls;
/* 865 */ if (className == null)
/* 866 */ cls = this.clazz;
/* */ else {
/* 868 */ cls = InterceptorInfoRepository.this.loadClass(className);
/* */ }
/* 870 */ if ((methodName == null) || (methodName.trim().equals("")))
/* */ {
/* 872 */ throw new RuntimeException(lookingFor + " must contain a valid method name for interceptor " + this.clazz.getName());
/* */ }
/* */
/* 876 */ List possible = new ArrayList();
/* 877 */ for (Method method : cls.getDeclaredMethods())
/* */ {
/* 879 */ if (!methodName.equals(method.getName()))
/* */ continue;
/* 881 */ possible.add(method);
/* */ }
/* */
/* 885 */ if (possible.size() == 0)
/* */ {
/* 887 */ throw new RuntimeException(lookingFor + " can't find method " + methodName + " on " + cls.getName());
/* */ }
/* */
/* 890 */ Method found = null;
/* */
/* 892 */ for (Method method : possible)
/* */ {
/* 895 */ if (lookingFor.equals("around-invoke-method"))
/* */ {
/* 897 */ if (this.signatureValidator.checkValidAround(method))
/* */ {
/* 899 */ found = method;
/* */ }
/* */
/* */ }
/* 904 */ else if (this.signatureValidator.checkValidLifecycle(method))
/* */ {
/* 906 */ found = method;
/* */ }
/* */
/* */ }
/* */
/* 911 */ if (found == null)
/* */ {
/* 914 */ throw new RuntimeException(lookingFor + " has the wrong method signature for interceptor " + this.clazz.getName());
/* */ }
/* */
/* 918 */ return found;
/* */ }
/* */ }
/* */
/* */ private class ContainerInitialiser extends InterceptorInfoRepository.AnnotationInitialiser
/* */ {
/* */ EJBContainer container;
/* */
/* */ public ContainerInitialiser(EJBContainer container)
/* */ {
/* 786 */ super(container.getBeanClass(), InterceptorInfoRepository.BeanSignatureValidator.instance);
/* 787 */ this.container = container;
/* */ }
/* */
/* */ Object getAnnotation(Method method, Class annotation)
/* */ {
/* 792 */ return this.container.resolveAnnotation(method, annotation);
/* */ }
/* */
/* */ Method resolveLifecycleMethod(Method method, Annotation ann)
/* */ {
/* 801 */ if (ann != null)
/* */ {
/* 803 */ if (!this.signatureValidator.checkValidLifecycle(method))
/* */ {
/* 805 */ throw new RuntimeException("@" + ann.annotationType().getName() + " annotated method has the wrong signature - " + method + " (EJB3 12.4)");
/* */ }
/* */
/* 808 */ return method;
/* */ }
/* 810 */ return null;
/* */ }
/* */ }
/* */
/* */ private class AnnotationInitialiser
/* */ {
/* */ InterceptorInfoRepository.SignatureValidator signatureValidator;
/* */ Class clazz;
/* */ InterceptorInfo info;
/* */
/* */ AnnotationInitialiser(String classname, InterceptorInfoRepository.SignatureValidator signatureValidator)
/* */ {
/* 689 */ this.clazz = InterceptorInfoRepository.this.loadClass(classname);
/* 690 */ this.signatureValidator = signatureValidator;
/* 691 */ this.info = new InterceptorInfo(this.clazz);
/* */ }
/* */
/* */ AnnotationInitialiser(Class clazz, InterceptorInfoRepository.SignatureValidator signatureValidator)
/* */ {
/* 696 */ this.clazz = clazz;
/* 697 */ this.signatureValidator = signatureValidator;
/* 698 */ this.info = new InterceptorInfo(clazz);
/* */ }
/* */
/* */ public Class getClazz()
/* */ {
/* 703 */ return this.clazz;
/* */ }
/* */
/* */ InterceptorInfo getInfo()
/* */ {
/* 708 */ for (Method method : this.clazz.getDeclaredMethods())
/* */ {
/* 710 */ this.info.setAroundInvoke(resolveAroundInvoke(method));
/* 711 */ this.info.setPostConstruct(resolvePostConstruct(method));
/* 712 */ this.info.setPostActivate(resolvePostActivate(method));
/* 713 */ this.info.setPreDestroy(resolvePreDestroy(method));
/* 714 */ this.info.setPrePassivate(resolvePrePassivate(method));
/* */ }
/* 716 */ return this.info;
/* */ }
/* */
/* */ Method resolveAroundInvoke(Method method)
/* */ {
/* 721 */ AroundInvoke ann = (AroundInvoke)getAnnotation(method, AroundInvoke.class);
/* 722 */ if (ann != null)
/* */ {
/* 724 */ if (!this.signatureValidator.checkValidAround(method))
/* */ {
/* 726 */ throw new RuntimeException("@" + ann.annotationType().getName() + " annotated method in has the wrong signature - " + method);
/* */ }
/* */
/* 729 */ return method;
/* */ }
/* 731 */ return null;
/* */ }
/* */
/* */ Method resolvePostConstruct(Method method)
/* */ {
/* 736 */ PostConstruct ann = (PostConstruct)getAnnotation(method, PostConstruct.class);
/* 737 */ return resolveLifecycleMethod(method, ann);
/* */ }
/* */
/* */ Method resolvePostActivate(Method method)
/* */ {
/* 742 */ PostActivate ann = (PostActivate)getAnnotation(method, PostActivate.class);
/* 743 */ return resolveLifecycleMethod(method, ann);
/* */ }
/* */
/* */ Method resolvePreDestroy(Method method)
/* */ {
/* 748 */ PreDestroy ann = (PreDestroy)getAnnotation(method, PreDestroy.class);
/* 749 */ return resolveLifecycleMethod(method, ann);
/* */ }
/* */
/* */ Method resolvePrePassivate(Method method)
/* */ {
/* 754 */ PrePassivate ann = (PrePassivate)getAnnotation(method, PrePassivate.class);
/* 755 */ return resolveLifecycleMethod(method, ann);
/* */ }
/* */
/* */ Method resolveLifecycleMethod(Method method, Annotation ann)
/* */ {
/* 760 */ if (ann != null)
/* */ {
/* 762 */ if (!this.signatureValidator.checkValidLifecycle(method))
/* */ {
/* 764 */ throw new RuntimeException("@" + ann.annotationType().getName() + " annotated method has the wrong signature - " + method);
/* */ }
/* */
/* 767 */ return method;
/* */ }
/* 769 */ return null;
/* */ }
/* */
/* */ Object getAnnotation(Method method, Class annotation)
/* */ {
/* 774 */ return method.getAnnotation(annotation);
/* */ }
/* */ }
/* */
/* */ private static class BeanSignatureValidator
/* */ implements InterceptorInfoRepository.SignatureValidator
/* */ {
/* 667 */ static InterceptorInfoRepository.SignatureValidator instance = new BeanSignatureValidator();
/* */
/* */ public boolean checkValidAround(Method m) {
/* 670 */ return InterceptorInfoRepository.checkValidBusinessSignature(m);
/* */ }
/* */
/* */ public boolean checkValidLifecycle(Method m)
/* */ {
/* 675 */ return InterceptorInfoRepository.checkValidBeanLifecycleSignature(m);
/* */ }
/* */ }
/* */
/* */ private static class InterceptorSignatureValidator
/* */ implements InterceptorInfoRepository.SignatureValidator
/* */ {
/* 653 */ static InterceptorInfoRepository.SignatureValidator instance = new InterceptorSignatureValidator();
/* */
/* */ public boolean checkValidAround(Method m) {
/* 656 */ return InterceptorInfoRepository.checkValidBusinessSignature(m);
/* */ }
/* */
/* */ public boolean checkValidLifecycle(Method m)
/* */ {
/* 661 */ return InterceptorInfoRepository.checkValidLifecycleSignature(m);
/* */ }
/* */ }
/* */
/* */ private static abstract interface SignatureValidator
/* */ {
/* */ public abstract boolean checkValidLifecycle(Method paramMethod);
/* */
/* */ public abstract boolean checkValidAround(Method paramMethod);
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.ejb3.interceptor.InterceptorInfoRepository
* JD-Core Version: 0.6.0
*/