Source Code Cross Referenced for InterceptorInfoRepository.java in  » EJB-Server-JBoss-4.2.1 » ejb3 » org » jboss » ejb3 » interceptor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server JBoss 4.2.1 » ejb3 » org.jboss.ejb3.interceptor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * JBoss, Home of Professional Open Source.
0003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
0004:         * as indicated by the @author tags. See the copyright.txt file in the
0005:         * distribution for a full listing of individual contributors.
0006:         *
0007:         * This is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU Lesser General Public License as
0009:         * published by the Free Software Foundation; either version 2.1 of
0010:         * the License, or (at your option) any later version.
0011:         *
0012:         * This software is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015:         * Lesser General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU Lesser General Public
0018:         * License along with this software; if not, write to the Free
0019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
0021:         */
0022:        package org.jboss.ejb3.interceptor;
0023:
0024:        import org.jboss.ejb3.EJBContainer;
0025:        import org.jboss.ejb3.metamodel.EjbJarDD;
0026:        import org.jboss.ejb3.metamodel.Interceptor;
0027:        import org.jboss.ejb3.metamodel.InterceptorBinding;
0028:        import org.jboss.ejb3.metamodel.Interceptors;
0029:        import org.jboss.logging.Logger;
0030:
0031:        import javax.annotation.PostConstruct;
0032:        import javax.annotation.PreDestroy;
0033:        import javax.ejb.CreateException;
0034:        import javax.ejb.PostActivate;
0035:        import javax.ejb.PrePassivate;
0036:        import javax.interceptor.AroundInvoke;
0037:        import javax.interceptor.ExcludeClassInterceptors;
0038:        import javax.interceptor.ExcludeDefaultInterceptors;
0039:        import javax.interceptor.InvocationContext;
0040:        import java.lang.annotation.Annotation;
0041:        import java.lang.reflect.Method;
0042:        import java.lang.reflect.Modifier;
0043:        import java.rmi.RemoteException;
0044:        import java.util.*;
0045:        import java.util.concurrent.ConcurrentHashMap;
0046:        import java.util.concurrent.ConcurrentMap;
0047:
0048:        /**
0049:         * A repository of interceptor details shared amongst all containers in this deployment.
0050:         * Interceptors differ from other ejb 3 artifacts in that we can have annotations on the
0051:         * interceptor classes which are not the ejb container, so we cannot use annotation overrides
0052:         * on the interceptors themselves.<BR/>
0053:         * <BR/>
0054:         * The xml structures get added on deployment.<BR/>
0055:         * Interceptors only declared by using @Interceptors on the bean class get added on demand.<BR/>
0056:         * 
0057:         * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
0058:         * @version $Revision: 63298 $
0059:         */
0060:        public class InterceptorInfoRepository {
0061:            private static Logger log = Logger
0062:                    .getLogger(InterceptorInfoRepository.class);
0063:
0064:            private Set<String> beanClasses = new HashSet<String>();
0065:
0066:            private Interceptors interceptorsXml;
0067:
0068:            private List<InterceptorBinding> bindingsXml;
0069:
0070:            private ConcurrentMap<Class, InterceptorInfo> infos = new ConcurrentHashMap<Class, InterceptorInfo>();
0071:
0072:            private ConcurrentMap<String, InterceptorInfo> ejbInfos = new ConcurrentHashMap<String, InterceptorInfo>();
0073:
0074:            private LinkedHashSet<InterceptorInfo> defaultInterceptors = null;
0075:
0076:            private InterceptorSorter sorter = new InterceptorSorter();
0077:
0078:            public InterceptorInfoRepository() {
0079:            }
0080:
0081:            public void initialise(EjbJarDD dd) {
0082:                this .interceptorsXml = dd.getInterceptors();
0083:
0084:                if (dd.getAssemblyDescriptor() != null) {
0085:                    this .bindingsXml = dd.getAssemblyDescriptor()
0086:                            .getInterceptorBindings();
0087:                }
0088:
0089:                initialiseInfosFromXml();
0090:                initialiseDefaultInterceptors();
0091:            }
0092:
0093:            public void addBeanClass(String classname) {
0094:                beanClasses.add(classname);
0095:            }
0096:
0097:            public InterceptorInfo getInterceptorInfo(Class clazz) {
0098:                initialiseInfosFromXml();
0099:                return infos.get(clazz);
0100:            }
0101:
0102:            public HashSet<InterceptorInfo> getDefaultInterceptors() {
0103:                return defaultInterceptors;
0104:            }
0105:
0106:            public boolean hasDefaultInterceptors() {
0107:                return defaultInterceptors.size() > 0;
0108:            }
0109:
0110:            public ArrayList<InterceptorInfo> getClassInterceptors(
0111:                    EJBContainer container) {
0112:                javax.interceptor.Interceptors interceptors = (javax.interceptor.Interceptors) container
0113:                        .resolveAnnotation(javax.interceptor.Interceptors.class);
0114:                ArrayList<InterceptorInfo> infos = getInterceptorsFromAnnotation(
0115:                        container, interceptors);
0116:
0117:                return infos;
0118:            }
0119:
0120:            public ArrayList<InterceptorInfo> getMethodInterceptors(
0121:                    EJBContainer container, Method m) {
0122:                javax.interceptor.Interceptors interceptors = (javax.interceptor.Interceptors) container
0123:                        .resolveAnnotation(m,
0124:                                javax.interceptor.Interceptors.class);
0125:                ArrayList<InterceptorInfo> infos = getInterceptorsFromAnnotation(
0126:                        container, interceptors);
0127:
0128:                return infos;
0129:            }
0130:
0131:            public Method[] getBeanClassAroundInvokes(EJBContainer container) {
0132:                return getBeanClassInterceptors(container, AroundInvoke.class);
0133:            }
0134:
0135:            public Method[] getBeanClassPostConstructs(EJBContainer container) {
0136:                return getBeanClassInterceptors(container, PostConstruct.class);
0137:            }
0138:
0139:            public Method[] getBeanClassPostActivates(EJBContainer container) {
0140:                return getBeanClassInterceptors(container, PostActivate.class);
0141:            }
0142:
0143:            public Method[] getBeanClassPrePassivates(EJBContainer container) {
0144:                return getBeanClassInterceptors(container, PrePassivate.class);
0145:            }
0146:
0147:            public Method[] getBeanClassPreDestroys(EJBContainer container) {
0148:                return getBeanClassInterceptors(container, PreDestroy.class);
0149:            }
0150:
0151:            private Method[] getBeanClassInterceptors(EJBContainer container,
0152:                    Class type) {
0153:                InterceptorInfo info = getOrInitialiseFromAnnotations(container);
0154:                return getMethodsForEvent(info, type);
0155:            }
0156:
0157:            public InterceptorInfo[] getBusinessInterceptors(
0158:                    EJBContainer container, Method method) {
0159:                return getInterceptors(container, AroundInvoke.class, method);
0160:            }
0161:
0162:            public InterceptorInfo[] getPostConstructInterceptors(
0163:                    EJBContainer container) {
0164:                return getInterceptors(container, PostConstruct.class, null);
0165:            }
0166:
0167:            public InterceptorInfo[] getPostActivateInterceptors(
0168:                    EJBContainer container) {
0169:                return getInterceptors(container, PostActivate.class, null);
0170:            }
0171:
0172:            public InterceptorInfo[] getPrePassivateInterceptors(
0173:                    EJBContainer container) {
0174:                return getInterceptors(container, PrePassivate.class, null);
0175:            }
0176:
0177:            public InterceptorInfo[] getPreDestroyInterceptors(
0178:                    EJBContainer container) {
0179:                return getInterceptors(container, PreDestroy.class, null);
0180:            }
0181:
0182:            private InterceptorInfo[] getInterceptors(EJBContainer container,
0183:                    Class type, Method method) {
0184:                ArrayList<InterceptorInfo> interceptors = new ArrayList<InterceptorInfo>();
0185:
0186:                if (!hasAnnotation(container, ExcludeDefaultInterceptors.class,
0187:                        method)) {
0188:                    HashSet<InterceptorInfo> infos = getDefaultInterceptors();
0189:                    if (infos != null) {
0190:                        interceptors.addAll(trimUnwanted(infos, type));
0191:                    }
0192:                    sorter.sortDefaultInterceptors(container, interceptors);
0193:                }
0194:
0195:                if (!hasAnnotation(container, ExcludeClassInterceptors.class,
0196:                        method)) {
0197:                    List<InterceptorInfo> infos = container
0198:                            .getClassInterceptors();
0199:                    if (infos != null) {
0200:                        interceptors.addAll(trimUnwanted(infos, type));
0201:                    }
0202:
0203:                    if (type != AroundInvoke.class) {
0204:                        List<InterceptorInfo> methodOnlyInterceptors = getMethodOnlyInterceptorsForLifecycle(
0205:                                container, type, interceptors);
0206:                        if (infos != null)
0207:                            interceptors.addAll(methodOnlyInterceptors);
0208:                    }
0209:                    sorter.sortClassInterceptors(container, interceptors);
0210:                }
0211:
0212:                if (type == AroundInvoke.class) {
0213:                    List<InterceptorInfo> infos = getMethodInterceptors(
0214:                            container, method);
0215:                    if (infos != null)
0216:                        interceptors.addAll(trimUnwanted(infos, type));
0217:                    sorter.sortMethodInterceptors(container, method,
0218:                            interceptors);
0219:                }
0220:
0221:                InterceptorInfo[] ints = interceptors
0222:                        .toArray(new InterceptorInfo[interceptors.size()]);
0223:                return ints;
0224:            }
0225:
0226:            private List<InterceptorInfo> getMethodOnlyInterceptorsForLifecycle(
0227:                    EJBContainer container, Class type,
0228:                    List<InterceptorInfo> infos) {
0229:                HashSet<InterceptorInfo> methodLevelInterceptors = (HashSet<InterceptorInfo>) container
0230:                        .getApplicableInterceptors().clone();
0231:
0232:                for (InterceptorInfo info : infos) {
0233:                    if (methodLevelInterceptors.contains(info)) {
0234:                        methodLevelInterceptors.remove(info);
0235:                    }
0236:                }
0237:
0238:                if (defaultInterceptors != null) {
0239:                    for (InterceptorInfo info : defaultInterceptors) {
0240:                        if (methodLevelInterceptors.contains(info)) {
0241:                            methodLevelInterceptors.remove(info);
0242:                        }
0243:                    }
0244:                }
0245:
0246:                List<InterceptorInfo> trimmedInfos = trimUnwanted(
0247:                        methodLevelInterceptors, type);
0248:                return trimmedInfos;
0249:            }
0250:
0251:            private boolean hasAnnotation(EJBContainer container,
0252:                    Class annotation, Method method) {
0253:                if (container.resolveAnnotation(annotation) != null) {
0254:                    return true;
0255:                }
0256:
0257:                if (method != null) {
0258:                    return container.resolveAnnotation(method, annotation) != null;
0259:                }
0260:
0261:                return false;
0262:            }
0263:
0264:            private List<InterceptorInfo> trimUnwanted(
0265:                    Collection<InterceptorInfo> interceptors, Class type) {
0266:                ArrayList<InterceptorInfo> ints = new ArrayList<InterceptorInfo>(
0267:                        interceptors.size());
0268:                ints.addAll(interceptors);
0269:
0270:                for (Iterator<InterceptorInfo> it = ints.iterator(); it
0271:                        .hasNext();) {
0272:                    InterceptorInfo info = it.next();
0273:                    if (!hasMethodsForEvent(info, type)) {
0274:                        it.remove();
0275:                    }
0276:                }
0277:
0278:                return ints;
0279:            }
0280:
0281:            private boolean hasMethodsForEvent(InterceptorInfo info, Class type) {
0282:                return getMethodsForEvent(info, type) != null;
0283:            }
0284:
0285:            private Method[] getMethodsForEvent(InterceptorInfo info, Class type) {
0286:                if (type == AroundInvoke.class)
0287:                    return info.getAroundInvokes();
0288:                else if (type == PostConstruct.class)
0289:                    return info.getPostConstructs();
0290:                else if (type == PostActivate.class)
0291:                    return info.getPostActivates();
0292:                else if (type == PrePassivate.class)
0293:                    return info.getPrePassivates();
0294:                else if (type == PreDestroy.class)
0295:                    return info.getPreDestroys();
0296:                return null;
0297:            }
0298:
0299:            private ArrayList<InterceptorInfo> getInterceptorsFromAnnotation(
0300:                    EJBContainer container,
0301:                    javax.interceptor.Interceptors interceptors) {
0302:                ArrayList<InterceptorInfo> inters = new ArrayList<InterceptorInfo>();
0303:                if (interceptors == null)
0304:                    return inters;
0305:
0306:                for (Class clazz : interceptors.value()) {
0307:                    InterceptorInfo info = getOrInitialiseFromAnnotations(clazz);
0308:                    validateInterceptorForContainer(container, info.getClazz());
0309:                    inters.add(info);
0310:                }
0311:
0312:                return inters;
0313:            }
0314:
0315:            private void validateInterceptorForContainer(
0316:                    EJBContainer container, Class interceptor) {
0317:                if (beanClasses.contains(interceptor.getName())) {
0318:                    if (!interceptor.equals(container.getClazz())) {
0319:                        throw new RuntimeException("Bean class "
0320:                                + interceptor.getName()
0321:                                + " cannot be used as an interceptor for "
0322:                                + container.getEjbName());
0323:                    }
0324:                }
0325:            }
0326:
0327:            private void initialiseInfosFromXml() {
0328:                if (interceptorsXml != null) {
0329:                    //Initialise all interceptor entries so we know which classes we have xml for
0330:                    HashMap<String, AnnotationInitialiser> initialisers = new HashMap<String, AnnotationInitialiser>();
0331:                    for (Interceptor xml : interceptorsXml.getInterceptors()) {
0332:                        XmlInitialiser init = new XmlInitialiser(xml);
0333:                        initialisers.put(xml.getInterceptorClass(), init);
0334:                    }
0335:
0336:                    //Create entries recursively, top classes first so we get the method hierarchies         
0337:                    for (Interceptor xml : interceptorsXml.getInterceptors()) {
0338:                        String clazz = xml.getInterceptorClass();
0339:                        initialiseSuperClassesFirstFromXmlOrAnnotations(
0340:                                initialisers, clazz);
0341:                    }
0342:
0343:                }
0344:            }
0345:
0346:            private InterceptorInfo initialiseSuperClassesFirstFromXmlOrAnnotations(
0347:                    HashMap<String, AnnotationInitialiser> initialisers,
0348:                    String super ClassName) {
0349:                if ("java.lang.Object".equals(super ClassName)) {
0350:                    return null;
0351:                }
0352:
0353:                AnnotationInitialiser initialiser = initialisers
0354:                        .get(super ClassName);
0355:                if (initialiser == null) {
0356:                    initialiser = new AnnotationInitialiser(super ClassName,
0357:                            InterceptorSignatureValidator.instance);
0358:                    initialisers.put(initialiser.getClazz().getName(),
0359:                            initialiser);
0360:                }
0361:                InterceptorInfo super Info = initialiseSuperClassesFirstFromXmlOrAnnotations(
0362:                        initialisers, initialiser.getClazz().getSuperclass()
0363:                                .getName());
0364:
0365:                InterceptorInfo info = initialiser.getInfo();
0366:                info.calculateHierarchy(super Info);
0367:                infos.put(info.getClazz(), info);
0368:                return info;
0369:            }
0370:
0371:            /*
0372:             * Default interceptors are defined using xml only
0373:             */
0374:            private void initialiseDefaultInterceptors() {
0375:                defaultInterceptors = new LinkedHashSet<InterceptorInfo>();
0376:
0377:                if (bindingsXml != null) {
0378:                    for (InterceptorBinding bindingXml : bindingsXml) {
0379:                        if (bindingXml.getEjbName().equals("*")
0380:                                && (bindingXml.getMethodName() == null || bindingXml
0381:                                        .getMethodName().length() == 0)) {
0382:                            for (String classname : bindingXml
0383:                                    .getInterceptorClasses()) {
0384:                                if (beanClasses.contains(classname)) {
0385:                                    throw new RuntimeException(
0386:                                            "Bean class defined in default binding "
0387:                                                    + classname);
0388:                                }
0389:                                InterceptorInfo info = getOrInitialiseFromAnnotations(classname);
0390:                                defaultInterceptors.add(info);
0391:                            }
0392:                        }
0393:                    }
0394:                }
0395:            }
0396:
0397:            private InterceptorInfo getOrInitialiseFromAnnotations(
0398:                    String classname) {
0399:                Class clazz = loadClass(classname);
0400:                return getOrInitialiseFromAnnotations(clazz);
0401:            }
0402:
0403:            private InterceptorInfo getOrInitialiseFromAnnotations(Class clazz) {
0404:                InterceptorInfo info = infos.get(clazz);
0405:
0406:                if (info == null) {
0407:                    synchronized (this ) {
0408:                        info = infos.get(clazz);
0409:                        if (info == null) {
0410:                            info = initialiseFromAnnotations(clazz);
0411:                            infos.put(clazz, info);
0412:                        }
0413:                    }
0414:                }
0415:
0416:                return info;
0417:            }
0418:
0419:            private InterceptorInfo initialiseFromAnnotations(Class clazz) {
0420:                InterceptorInfo super Info = null;
0421:                if (clazz.getSuperclass() != Object.class) {
0422:                    super Info = getOrInitialiseFromAnnotations(clazz
0423:                            .getSuperclass());
0424:                }
0425:
0426:                AnnotationInitialiser init = new AnnotationInitialiser(clazz,
0427:                        InterceptorSignatureValidator.instance);
0428:                InterceptorInfo info = init.getInfo();
0429:                info.calculateHierarchy(super Info);
0430:                return info;
0431:            }
0432:
0433:            private InterceptorInfo getOrInitialiseFromAnnotations(
0434:                    EJBContainer container) {
0435:                InterceptorInfo info = ejbInfos.get(container.getEjbName());
0436:
0437:                if (info == null) {
0438:                    synchronized (this ) {
0439:                        info = ejbInfos.get(container.getEjbName());
0440:                        if (info == null) {
0441:                            info = initialiseFromAnnotations(container);
0442:                            ejbInfos.put(container.getEjbName(), info);
0443:                        }
0444:                    }
0445:                }
0446:
0447:                return info;
0448:            }
0449:
0450:            private InterceptorInfo initialiseFromAnnotations(
0451:                    EJBContainer container) {
0452:                //Currently I see no way in spec for specifying interceptors of an ejb super class using xml,
0453:                //use annotations only to initialise super classes, and don't store these
0454:                InterceptorInfo super Info = initialiseContainerSuperClassFromAnnotationsOnly(container
0455:                        .getClazz().getSuperclass());
0456:                AnnotationInitialiser init = new ContainerInitialiser(container);
0457:                InterceptorInfo info = init.getInfo();
0458:                info.calculateHierarchy(super Info);
0459:                return info;
0460:            }
0461:
0462:            private InterceptorInfo initialiseContainerSuperClassFromAnnotationsOnly(
0463:                    Class clazz) {
0464:                InterceptorInfo super Info = null;
0465:                if (clazz != Object.class) {
0466:                    super Info = initialiseContainerSuperClassFromAnnotationsOnly(clazz
0467:                            .getSuperclass());
0468:                }
0469:
0470:                AnnotationInitialiser init = new AnnotationInitialiser(clazz,
0471:                        BeanSignatureValidator.instance);
0472:                InterceptorInfo info = init.getInfo();
0473:                info.calculateHierarchy(super Info);
0474:                return info;
0475:            }
0476:
0477:            private Class loadClass(String name) {
0478:                try {
0479:                    return Thread.currentThread().getContextClassLoader()
0480:                            .loadClass(name);
0481:                } catch (Exception e) {
0482:                    throw new RuntimeException("Interceptor class not found: "
0483:                            + name);
0484:                }
0485:            }
0486:
0487:            private static boolean checkExceptions(
0488:                    Class<?> allowedExceptions[], Method method) {
0489:                for (Class<?> exception : method.getExceptionTypes()) {
0490:                    boolean isAllowed = false;
0491:                    for (Class<?> allowed : allowedExceptions) {
0492:                        if (allowed.isAssignableFrom(exception))
0493:                            isAllowed = true;
0494:                    }
0495:                    if (!isAllowed) {
0496:                        log.warn("Illegal exception '" + exception.getName()
0497:                                + "' in lifecycle signature (EJB3 12.4.2): "
0498:                                + method);
0499:                        return false;
0500:                    }
0501:                }
0502:                return true;
0503:            }
0504:
0505:            public static boolean checkValidBusinessSignature(Method method) {
0506:                int modifiers = method.getModifiers();
0507:
0508:                if (!Modifier.isStatic(modifiers)) {
0509:                    if (method.getReturnType().equals(Object.class)) {
0510:                        Class[] params = method.getParameterTypes();
0511:                        if (params.length == 1
0512:                                && params[0].equals(InvocationContext.class)) {
0513:                            Class[] exceptions = method.getExceptionTypes();
0514:                            if (exceptions.length == 1
0515:                                    && exceptions[0].equals(Exception.class)) {
0516:                                return true;
0517:                            }
0518:                        }
0519:                    }
0520:                }
0521:                return false;
0522:            }
0523:
0524:            public static boolean checkValidLifecycleSignature(Method method) {
0525:                int modifiers = method.getModifiers();
0526:
0527:                if (!Modifier.isStatic(modifiers)) {
0528:                    if (method.getReturnType().equals(Void.TYPE)) {
0529:                        Class[] params = method.getParameterTypes();
0530:                        if (params.length == 1
0531:                                && params[0].equals(InvocationContext.class)) {
0532:                            return true;
0533:                        }
0534:                    }
0535:                }
0536:                return false;
0537:            }
0538:
0539:            /**
0540:             * EJB3 12.4
0541:             * Lifecycle methods may throw runtime exceptions, but not application exceptions.
0542:             * Note that for 2.1 beans CreateException (on ejbCreate) and RemoteException should pass.
0543:             * 
0544:             * @param method
0545:             * @return
0546:             */
0547:            public static boolean checkValidBeanLifecycleSignature(Method method) {
0548:                int modifiers = method.getModifiers();
0549:                if (method.getName().equals("ejbCreate")) {
0550:                    // for public void ejbCreate(...) throws javax.ejb.CreateException
0551:                    if (!Modifier.isStatic(modifiers)
0552:                            && method.getReturnType().equals(Void.TYPE)
0553:                            && method.getExceptionTypes().length <= 1) {
0554:                        if (!checkExceptions(new Class<?>[] {
0555:                                RuntimeException.class, CreateException.class,
0556:                                RemoteException.class }, method))
0557:                            return false;
0558:                        return true;
0559:                    }
0560:                } else if (!Modifier.isStatic(modifiers)
0561:                        && method.getReturnType().equals(Void.TYPE)
0562:                        && method.getParameterTypes().length == 0) {
0563:                    if (!checkExceptions(new Class<?>[] {
0564:                            RuntimeException.class, RemoteException.class },
0565:                            method))
0566:                        return false;
0567:                    return true;
0568:                }
0569:                return false;
0570:            }
0571:
0572:            public static String simpleType(Class type) {
0573:                Class ret = type;
0574:                if (ret.isArray()) {
0575:                    Class arr = ret;
0576:                    String array = "";
0577:                    while (arr.isArray()) {
0578:                        array += "[]";
0579:                        arr = arr.getComponentType();
0580:                    }
0581:                    return arr.getName() + array;
0582:                }
0583:                return ret.getName();
0584:            }
0585:
0586:            private interface SignatureValidator {
0587:                boolean checkValidLifecycle(Method m);
0588:
0589:                boolean checkValidAround(Method m);
0590:            }
0591:
0592:            private static class InterceptorSignatureValidator implements 
0593:                    SignatureValidator {
0594:                static SignatureValidator instance = new InterceptorSignatureValidator();
0595:
0596:                public boolean checkValidAround(Method m) {
0597:                    return checkValidBusinessSignature(m);
0598:                }
0599:
0600:                public boolean checkValidLifecycle(Method m) {
0601:                    return checkValidLifecycleSignature(m);
0602:                }
0603:            }
0604:
0605:            private static class BeanSignatureValidator implements 
0606:                    SignatureValidator {
0607:                static SignatureValidator instance = new BeanSignatureValidator();
0608:
0609:                public boolean checkValidAround(Method m) {
0610:                    return checkValidBusinessSignature(m);
0611:                }
0612:
0613:                public boolean checkValidLifecycle(Method m) {
0614:                    return checkValidBeanLifecycleSignature(m);
0615:                }
0616:            }
0617:
0618:            private class AnnotationInitialiser {
0619:                SignatureValidator signatureValidator;
0620:                Class clazz;
0621:
0622:                InterceptorInfo info;
0623:
0624:                AnnotationInitialiser(String classname,
0625:                        SignatureValidator signatureValidator) {
0626:                    clazz = loadClass(classname);
0627:                    this .signatureValidator = signatureValidator;
0628:                    info = new InterceptorInfo(clazz);
0629:                }
0630:
0631:                AnnotationInitialiser(Class clazz,
0632:                        SignatureValidator signatureValidator) {
0633:                    this .clazz = clazz;
0634:                    this .signatureValidator = signatureValidator;
0635:                    info = new InterceptorInfo(clazz);
0636:                }
0637:
0638:                public Class getClazz() {
0639:                    return clazz;
0640:                }
0641:
0642:                InterceptorInfo getInfo() {
0643:                    for (Method method : clazz.getDeclaredMethods()) {
0644:                        info.setAroundInvoke(resolveAroundInvoke(method));
0645:                        info.setPostConstruct(resolvePostConstruct(method));
0646:                        info.setPostActivate(resolvePostActivate(method));
0647:                        info.setPreDestroy(resolvePreDestroy(method));
0648:                        info.setPrePassivate(resolvePrePassivate(method));
0649:                    }
0650:                    return info;
0651:                }
0652:
0653:                Method resolveAroundInvoke(Method method) {
0654:                    AroundInvoke ann = (AroundInvoke) getAnnotation(method,
0655:                            AroundInvoke.class);
0656:                    if (ann != null) {
0657:                        if (!signatureValidator.checkValidAround(method)) {
0658:                            throw new RuntimeException(
0659:                                    "@"
0660:                                            + ((Annotation) ann)
0661:                                                    .annotationType().getName()
0662:                                            + " annotated method in has the wrong signature - "
0663:                                            + method);
0664:                        }
0665:                        return method;
0666:                    }
0667:                    return null;
0668:                }
0669:
0670:                Method resolvePostConstruct(Method method) {
0671:                    PostConstruct ann = (PostConstruct) getAnnotation(method,
0672:                            PostConstruct.class);
0673:                    return resolveLifecycleMethod(method, ann);
0674:                }
0675:
0676:                Method resolvePostActivate(Method method) {
0677:                    PostActivate ann = (PostActivate) getAnnotation(method,
0678:                            PostActivate.class);
0679:                    return resolveLifecycleMethod(method, ann);
0680:                }
0681:
0682:                Method resolvePreDestroy(Method method) {
0683:                    PreDestroy ann = (PreDestroy) getAnnotation(method,
0684:                            PreDestroy.class);
0685:                    return resolveLifecycleMethod(method, ann);
0686:                }
0687:
0688:                Method resolvePrePassivate(Method method) {
0689:                    PrePassivate ann = (PrePassivate) getAnnotation(method,
0690:                            PrePassivate.class);
0691:                    return resolveLifecycleMethod(method, ann);
0692:                }
0693:
0694:                Method resolveLifecycleMethod(Method method, Annotation ann) {
0695:                    if (ann != null) {
0696:                        if (!signatureValidator.checkValidLifecycle(method)) {
0697:                            throw new RuntimeException(
0698:                                    "@"
0699:                                            + ((Annotation) ann)
0700:                                                    .annotationType().getName()
0701:                                            + " annotated method  has the wrong signature - "
0702:                                            + method);
0703:                        }
0704:                        return method;
0705:                    }
0706:                    return null;
0707:                }
0708:
0709:                Object getAnnotation(Method method, Class annotation) {
0710:                    return method.getAnnotation(annotation);
0711:                }
0712:
0713:            }
0714:
0715:            private class ContainerInitialiser extends AnnotationInitialiser {
0716:                EJBContainer container;
0717:
0718:                public ContainerInitialiser(EJBContainer container) {
0719:                    // FIXME ContainerInitialiser constructor
0720:                    super (container.getBeanClass(),
0721:                            BeanSignatureValidator.instance);
0722:                    this .container = container;
0723:                }
0724:
0725:                Object getAnnotation(Method method, Class annotation) {
0726:                    return container.resolveAnnotation(method, annotation);
0727:                }
0728:
0729:                /*
0730:                 * Lifecycle methods on bean class have a different signature from those defined on
0731:                 * 
0732:                 */
0733:                Method resolveLifecycleMethod(Method method, Annotation ann) {
0734:                    if (ann != null) {
0735:                        if (!signatureValidator.checkValidLifecycle(method)) {
0736:                            throw new RuntimeException(
0737:                                    "@"
0738:                                            + ann.annotationType().getName()
0739:                                            + " annotated method has the wrong signature - "
0740:                                            + method);
0741:                        }
0742:                        return method;
0743:                    }
0744:                    return null;
0745:                }
0746:            }
0747:
0748:            private class XmlInitialiser extends AnnotationInitialiser {
0749:                Interceptor xml;
0750:
0751:                XmlInitialiser(Interceptor xml) {
0752:                    super (xml.getInterceptorClass(),
0753:                            InterceptorSignatureValidator.instance);
0754:                    this .xml = xml;
0755:                }
0756:
0757:                InterceptorInfo getInfo() {
0758:                    info.setAroundInvoke(findInterceptorMethodFromXml(clazz,
0759:                            "around-invoke-method", xml.getAroundInvoke()));
0760:                    info.setPostConstruct(findInterceptorMethodFromXml(clazz,
0761:                            "post-construct-method", xml.getPostConstruct()));
0762:                    info.setPostActivate(findInterceptorMethodFromXml(clazz,
0763:                            "post-activate-method", xml.getPostActivate()));
0764:                    info.setPreDestroy(findInterceptorMethodFromXml(clazz,
0765:                            "pre-destroy-method", xml.getPreDestroy()));
0766:                    info.setPrePassivate(findInterceptorMethodFromXml(clazz,
0767:                            "pre-passivate-method", xml.getPrePassivate()));
0768:                    super .getInfo();
0769:                    info.setXml(xml);
0770:                    return info;
0771:                }
0772:
0773:                java.lang.reflect.Method findInterceptorMethodFromXml(
0774:                        Class clazz, String lookingFor,
0775:                        org.jboss.ejb3.metamodel.Method xml) {
0776:                    if (xml == null)
0777:                        return null;
0778:                    if (xml.getMethodName() == null
0779:                            || xml.getMethodName().trim().equals("")) {
0780:                        throw new RuntimeException(
0781:                                lookingFor
0782:                                        + " must contain a valid method name for interceptor "
0783:                                        + clazz.getName());
0784:                    }
0785:                    if (xml.getMethodParams() != null) {
0786:                        log.debug("Ignoring method parameters for "
0787:                                + lookingFor + " in interceptor "
0788:                                + clazz.getName());
0789:                    }
0790:
0791:                    ArrayList<Method> possible = new ArrayList<Method>();
0792:                    for (java.lang.reflect.Method method : clazz
0793:                            .getDeclaredMethods()) {
0794:                        if (xml.getMethodName().equals(method.getName())) {
0795:                            possible.add(method);
0796:                        }
0797:                    }
0798:
0799:                    if (possible.size() == 0) {
0800:                        throw new RuntimeException(
0801:                                lookingFor
0802:                                        + " must contain a valid method name for interceptor "
0803:                                        + clazz.getName());
0804:                    }
0805:
0806:                    Method found = null;
0807:
0808:                    for (Method method : possible) {
0809:                        if (lookingFor.equals("around-invoke-method")) {
0810:                            if (signatureValidator.checkValidAround(method)) {
0811:                                found = method;
0812:                            }
0813:                        } else {
0814:                            if (signatureValidator.checkValidLifecycle(method)) {
0815:                                found = method;
0816:                            }
0817:                        }
0818:                    }
0819:
0820:                    if (found == null) {
0821:                        throw new RuntimeException(
0822:                                lookingFor
0823:                                        + " has the wrong method signature for interceptor "
0824:                                        + clazz.getName());
0825:                    }
0826:
0827:                    return found;
0828:                }
0829:            }
0830:
0831:            private class InterceptorSorter {
0832:                boolean initialised;
0833:                List<InterceptorBinding> orderedBindings;
0834:
0835:                private void initialise() {
0836:                    if (!initialised) {
0837:                        synchronized (this ) {
0838:                            if (bindingsXml != null) {
0839:                                for (InterceptorBinding binding : bindingsXml) {
0840:                                    if (binding.isOrdered()) {
0841:                                        //Validate each interceptor only occurs once
0842:                                        HashSet<String> names = new HashSet<String>();
0843:                                        for (Iterator it = binding
0844:                                                .getInterceptorClasses()
0845:                                                .iterator(); it.hasNext();) {
0846:                                            String className = (String) it
0847:                                                    .next();
0848:                                            if (names.contains(className)) {
0849:                                                throw new RuntimeException(
0850:                                                        className
0851:                                                                + " occurs more than once in ordered binding "
0852:                                                                + getInterceptorBindingString(binding));
0853:                                            }
0854:                                            names.add(className);
0855:                                        }
0856:
0857:                                        if (orderedBindings == null) {
0858:                                            orderedBindings = new ArrayList<InterceptorBinding>();
0859:                                        }
0860:                                        orderedBindings.add(binding);
0861:                                    }
0862:                                }
0863:                            }
0864:                        }
0865:                        log.trace("orderedBindings = " + orderedBindings);
0866:                        initialised = true;
0867:                    }
0868:                }
0869:
0870:                void sortDefaultInterceptors(EJBContainer container,
0871:                        ArrayList<InterceptorInfo> infos) {
0872:                    initialise();
0873:                    if (orderedBindings == null)
0874:                        return;
0875:                    ArrayList<String> bindingOrder = null;
0876:                    for (InterceptorBinding binding : orderedBindings) {
0877:                        if (binding.getEjbName().equals("*")) {
0878:                            if (bindingOrder != null) {
0879:                                throw new RuntimeException(
0880:                                        "There should only be one interceptor-binding specifying "
0881:                                                + "the order of default interceptors "
0882:                                                + getInterceptorBindingString(binding));
0883:                            }
0884:                            bindingOrder = binding.getInterceptorClasses();
0885:                        }
0886:                    }
0887:                    sortInterceptors(infos, bindingOrder);
0888:                }
0889:
0890:                void sortClassInterceptors(EJBContainer container,
0891:                        ArrayList<InterceptorInfo> infos) {
0892:                    initialise();
0893:                    if (orderedBindings == null)
0894:                        return;
0895:                    ArrayList<String> bindingOrder = null;
0896:                    for (InterceptorBinding binding : orderedBindings) {
0897:                        if (binding.getMethodName() != null
0898:                                && binding.getMethodName().trim().length() > 0) {
0899:                            continue;
0900:                        }
0901:                        if (binding.getEjbName().equals(container.getEjbName())) {
0902:                            if (bindingOrder != null) {
0903:                                throw new RuntimeException(
0904:                                        "There should only be one interceptor-binding specifying "
0905:                                                + "the order of class interceptors: "
0906:                                                + getInterceptorBindingString(binding));
0907:                            }
0908:                            bindingOrder = binding.getInterceptorClasses();
0909:                        }
0910:                    }
0911:                    sortInterceptors(infos, bindingOrder);
0912:                }
0913:
0914:                void sortMethodInterceptors(EJBContainer container,
0915:                        Method method, ArrayList<InterceptorInfo> infos) {
0916:                    initialise();
0917:                    if (orderedBindings == null)
0918:                        return;
0919:                    ArrayList<String> methodNoParamsOrder = null;
0920:                    ArrayList<String> methodParamsOrder = null;
0921:                    for (InterceptorBinding binding : orderedBindings) {
0922:                        if (binding.getEjbName().equals(container.getEjbName())) {
0923:                            if (binding.getMethodName() != null
0924:                                    && binding.getMethodName().equals(
0925:                                            method.getName())) {
0926:                                if (binding.getMethodParams() == null) {
0927:                                    if (methodNoParamsOrder != null) {
0928:                                        throw new RuntimeException(
0929:                                                "There should only be one interceptor-binding specifying "
0930:                                                        + "the order of method interceptors: "
0931:                                                        + getInterceptorBindingString(binding));
0932:                                    }
0933:                                    methodNoParamsOrder = binding
0934:                                            .getInterceptorClasses();
0935:                                } else {
0936:                                    Class[] params = method.getParameterTypes();
0937:                                    List<String> methodParams = binding
0938:                                            .getMethodParams();
0939:                                    if (methodParams.size() == params.length) {
0940:                                        boolean matches = true;
0941:                                        for (int i = 0; i < params.length; i++) {
0942:                                            if (!simpleType(params[i]).equals(
0943:                                                    methodParams.get(i))) {
0944:                                                matches = false;
0945:                                                break;
0946:                                            }
0947:                                        }
0948:
0949:                                        if (matches) {
0950:                                            if (methodParamsOrder != null) {
0951:                                                boolean first = false;
0952:                                                StringBuffer paramBuf = new StringBuffer();
0953:                                                paramBuf.append("(");
0954:                                                for (String par : methodParams) {
0955:                                                    if (!first)
0956:                                                        paramBuf.append(",");
0957:                                                    paramBuf.append(par);
0958:                                                }
0959:                                                paramBuf.append(")");
0960:                                                throw new RuntimeException(
0961:                                                        "There should only be one interceptor-binding specifying "
0962:                                                                + "the order of method interceptors: "
0963:                                                                + getInterceptorBindingString(binding));
0964:                                            }
0965:
0966:                                            methodParamsOrder = binding
0967:                                                    .getInterceptorClasses();
0968:                                        }
0969:                                    }
0970:                                }
0971:                            }
0972:                        }
0973:                    }
0974:
0975:                    if (methodParamsOrder != null) {
0976:                        sortInterceptors(infos, methodParamsOrder);
0977:
0978:                    } else {
0979:                        sortInterceptors(infos, methodNoParamsOrder);
0980:                    }
0981:                }
0982:
0983:                void sortInterceptors(ArrayList<InterceptorInfo> infos,
0984:                        ArrayList<String> interceptorOrder) {
0985:                    if (interceptorOrder == null)
0986:                        return;
0987:                    Collections.sort(infos, new InterceptorComparator(
0988:                            interceptorOrder));
0989:                }
0990:
0991:                String getInterceptorBindingString(InterceptorBinding binding) {
0992:                    StringBuffer buf = new StringBuffer();
0993:                    List methodParams = binding.getMethodParams();
0994:
0995:                    buf.append(binding.getEjbName());
0996:                    if (binding.getMethodName() != null) {
0997:                        buf.append("." + binding.getMethodName());
0998:                        if (methodParams != null) {
0999:                            buf.append("(");
1000:                            for (int i = 0; i < methodParams.size();) {
1001:                                if (i == 0)
1002:                                    buf.append(",");
1003:                                buf.append((String) methodParams.get(i));
1004:                            }
1005:                            buf.append(")");
1006:                        }
1007:                    }
1008:
1009:                    return buf.toString();
1010:                }
1011:            }
1012:
1013:            private class InterceptorComparator implements 
1014:                    Comparator<InterceptorInfo> {
1015:                ArrayList<String> ordered;
1016:
1017:                InterceptorComparator(ArrayList<String> ordered) {
1018:                    this .ordered = ordered;
1019:                }
1020:
1021:                public int compare(InterceptorInfo o1, InterceptorInfo o2) {
1022:                    int pos1 = ordered.indexOf(o1.getClazz().getName());
1023:                    int pos2 = ordered.indexOf(o2.getClazz().getName());
1024:
1025:                    //Make anything not specified in the order come last
1026:                    if (pos1 < 0)
1027:                        pos1 = Integer.MAX_VALUE;
1028:                    if (pos2 < 0)
1029:                        pos2 = Integer.MAX_VALUE;
1030:
1031:                    if (pos1 < pos2) {
1032:                        return -1;
1033:                    } else if (pos1 > pos2) {
1034:                        return 1;
1035:                    } else {
1036:                        return 0;
1037:                    }
1038:                }
1039:
1040:            }
1041:
1042:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.