1 25 26 package org.objectweb.easybeans.deployment.annotations.helper.bean.session.checks; 27 28 import java.util.List ; 29 import static org.objectweb.asm.Opcodes.ACC_STATIC; 30 import static org.objectweb.asm.Opcodes.ACC_FINAL; 31 32 import org.objectweb.easybeans.deployment.annotations.JMethod; 33 import org.objectweb.easybeans.deployment.annotations.exceptions.InterceptorsValidationException; 34 import org.objectweb.easybeans.deployment.annotations.impl.JInterceptors; 35 import org.objectweb.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata; 36 import org.objectweb.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata; 37 import org.objectweb.easybeans.deployment.annotations.metadata.MethodAnnotationMetadata; 38 39 43 public final class InterceptorsValidator { 44 45 48 private static final String AROUND_INVOKE_DESCRIPTOR_EJB = "(Ljavax/interceptor/InvocationContext;)Ljava/lang/Object;"; 49 50 53 private static final String LIFECYCLE_DESCRIPTOR_OUTSIDEBEAN = "(Ljavax/interceptor/InvocationContext;)V"; 54 55 58 private static final String LIFECYCLE_DESCRIPTOR_BEAN = "()V"; 59 60 63 private static final String AROUND_INVOKE_EXCEPTION = "java/lang/Exception"; 64 65 68 private static final String DEFAULT_CONSTRUCTOR_DESCRIPTOR = "()V"; 69 70 73 private static final String CONSTRUCTOR_METHOD = "<init>"; 74 75 78 private InterceptorsValidator() { 79 } 80 81 85 public static void validate(final ClassAnnotationMetadata bean) { 86 87 EjbJarAnnotationMetadata ejbMetaData = bean.getEjbJarAnnotationMetadata(); 89 90 if (bean.isBean()) { 92 for (MethodAnnotationMetadata method : bean.getMethodAnnotationMetadataCollection()) { 93 94 if (method.isLifeCycleMethod()) { 96 validateJMethod(method.getJMethod(), LIFECYCLE_DESCRIPTOR_BEAN, null, bean.getClassName()); 97 } else if (method.isAroundInvoke()) { 98 validateJMethod(method.getJMethod(), AROUND_INVOKE_DESCRIPTOR_EJB, AROUND_INVOKE_EXCEPTION, bean 99 .getClassName()); 100 } 101 102 JInterceptors methodInterceptors = method.getAnnotationInterceptors(); 104 if (methodInterceptors != null) { 106 for (String className : methodInterceptors.getClasses()) { 107 analyzeInterceptorClass(ejbMetaData, className); 108 } 109 } 110 } 111 112 JInterceptors methodInterceptors = bean.getAnnotationInterceptors(); 114 if (methodInterceptors != null) { 116 for (String className : methodInterceptors.getClasses()) { 117 analyzeInterceptorClass(ejbMetaData, className); 118 } 119 } 120 121 String [] interfaces = bean.getInterfaces(); 124 if (interfaces != null) { 125 for (String itf : interfaces) { 126 ClassAnnotationMetadata interfaceMetaData = ejbMetaData.getClassAnnotationMetadata(itf); 127 if (interfaceMetaData != null) { 128 for (MethodAnnotationMetadata method : interfaceMetaData 129 .getMethodAnnotationMetadataCollection()) { 130 if (method.isAroundInvoke()) { 132 throw new InterceptorsValidationException("The method '" + method 133 + "' in the bean class '" + bean.getClassName() 134 + "' cannot be an AroundInvoke as it is an interface"); 135 } 136 if (method.isLifeCycleMethod()) { 137 throw new InterceptorsValidationException("The method '" + method 138 + "' in the bean class '" + bean.getClassName() 139 + "' cannot be a lifecycle as it is an interface"); 140 } 141 } 142 } 143 } 144 } 145 } 146 147 if (bean.isInterceptor()) { 149 analyzeInterceptorClass(ejbMetaData, bean.getClassName()); 150 } 151 152 } 153 154 159 private static void analyzeInterceptorClass(final EjbJarAnnotationMetadata ejbMetaData, final String className) { 160 ClassAnnotationMetadata interceptorMetaData = ejbMetaData.getClassAnnotationMetadata(className); 162 if (interceptorMetaData == null) { 163 throw new InterceptorsValidationException("Internal problem as no metadata was found for '" + className 164 + "'."); 165 } 166 167 List <MethodAnnotationMetadata> aroundInvokeList = interceptorMetaData.getAroundInvokeMethodMetadatas(); 168 if (aroundInvokeList != null && aroundInvokeList.size() > 1) { 169 String errMsg = "There are severals @AroundInvoke in the class '" + className 170 + "', while only one is allowed. List of Methods : '" + aroundInvokeList + "'."; 171 throw new InterceptorsValidationException(errMsg); 172 } 173 174 JMethod defaultConstructor = new JMethod(0, CONSTRUCTOR_METHOD, DEFAULT_CONSTRUCTOR_DESCRIPTOR, null, null); 176 if (interceptorMetaData.getMethodAnnotationMetadata(defaultConstructor) == null) { 177 throw new InterceptorsValidationException("No default constructor in the interceptor class '" + className 178 + "'."); 179 } 180 181 for (MethodAnnotationMetadata method : interceptorMetaData.getMethodAnnotationMetadataCollection()) { 182 183 if (method.isLifeCycleMethod() && !method.getClassAnnotationMetadata().isBean()) { 185 validateJMethod(method.getJMethod(), LIFECYCLE_DESCRIPTOR_OUTSIDEBEAN, null, className); 186 } else if (method.isAroundInvoke()) { 187 validateJMethod(method.getJMethod(), AROUND_INVOKE_DESCRIPTOR_EJB, AROUND_INVOKE_EXCEPTION, className); 189 190 ensureNoAccess(ACC_FINAL, method.getJMethod(), "Final", className); 192 ensureNoAccess(ACC_STATIC, method.getJMethod(), "Static", className); 193 } 194 195 } 196 197 } 198 199 206 private static void ensureNoAccess(final int acc, final JMethod jMethod, final String desc, final String className) { 207 if ((jMethod.getAccess() & acc) == acc) { 208 throw new InterceptorsValidationException("The method '" + jMethod + "' of the class '" + className 209 + "' is not compliant on the method access. It shouldn't use the '" + desc + "' keyword."); 210 } 211 } 212 213 220 private static void validateJMethod(final JMethod jMethod, final String desc, final String awaitedException, 221 final String className) { 222 223 if (!jMethod.getDescriptor().equals(desc)) { 225 throw new InterceptorsValidationException("Method '" + jMethod + "' of the class '" + className 226 + "' is not compliant with the signature '" + desc + "'. Signature found = '" 227 + jMethod.getDescriptor() + "'."); 228 } 229 230 String [] exceptions = jMethod.getExceptions(); 232 if (awaitedException == null) { 233 return; 234 } 235 236 boolean found = false; 237 238 if (exceptions != null) { 239 for (String exception : exceptions) { 240 if (exception.equals(awaitedException)) { 241 found = true; 242 } 243 } 244 } 245 if (!found) { 246 throw new InterceptorsValidationException("Method '" + jMethod + "' of the class '" + className 247 + "' is not compliant with the signature '" + desc + "' as the required exception '" 248 + awaitedException + "' is missing."); 249 } 250 } 251 252 } 253 | Popular Tags |