static Map<InterceptionType, List<MethodMetadata>> buildMethodMap( ClassMetadata<?> interceptorClass, boolean forTargetClass) { Map<InterceptionType, List<MethodMetadata>> methodMap = new HashMap<InterceptionType, List<MethodMetadata>>(); ClassMetadata<?> currentClass = interceptorClass; Set<MethodReference> foundMethods = new HashSet<MethodReference>(); do { Set<InterceptionType> detectedInterceptorTypes = new HashSet<InterceptionType>(); for (MethodMetadata method : currentClass.getDeclaredMethods()) { MethodReference methodReference = MethodReference.of(method, Modifier.isPrivate(method.getJavaMethod().getModifiers())); if (!foundMethods.contains(methodReference)) { for (InterceptionType interceptionType : InterceptionTypeRegistry.getSupportedInterceptionTypes()) { if (isInterceptorMethod(interceptionType, method, forTargetClass)) { if (methodMap.get(interceptionType) == null) { methodMap.put(interceptionType, new LinkedList<MethodMetadata>()); } if (detectedInterceptorTypes.contains(interceptionType)) { throw new InterceptorMetadataException( "Same interception type cannot be specified twice on the same class"); } else { detectedInterceptorTypes.add(interceptionType); } // add method in the list - if it is there already, it means that it has been added by // a subclass // final methods are treated separately, as a final method cannot override another // method nor be // overridden ReflectionUtils.ensureAccessible(method.getJavaMethod()); if (!foundMethods.contains(methodReference)) { methodMap.get(interceptionType).add(0, method); } } } // the method reference must be added anyway - overridden methods are not taken into // consideration foundMethods.add(methodReference); } } currentClass = currentClass.getSuperclass(); } while (currentClass != null && !OBJECT_CLASS_NAME.equals(currentClass.getJavaClass())); return methodMap; }
public static boolean isInterceptorMethod( InterceptionType interceptionType, MethodMetadata method, boolean forTargetClass) { if (!method.getSupportedInterceptionTypes().contains(interceptionType)) { return false; } if (interceptionType.isLifecycleCallback()) { if (!Void.TYPE.equals(method.getReturnType())) { if (LOG.isWarnEnabled()) { LOG.warn( getStandardIgnoredMessage(interceptionType, method.getJavaMethod()) + "does not have a void return type"); } return false; } Class<?>[] parameterTypes = method.getJavaMethod().getParameterTypes(); if (forTargetClass && parameterTypes.length != 0) { if (LOG.isWarnEnabled()) { LOG.warn( getStandardIgnoredMessage(interceptionType, method.getJavaMethod()) + "is defined on the target class and does not have 0 arguments"); } return false; } if (!forTargetClass && parameterTypes.length != 1) { if (LOG.isWarnEnabled()) { LOG.warn( getStandardIgnoredMessage(interceptionType, method.getJavaMethod()) + "does not have exactly one parameter"); } return false; } if (parameterTypes.length == 1 && !InvocationContext.class.isAssignableFrom(parameterTypes[0])) { if (LOG.isWarnEnabled()) { LOG.warn( getStandardIgnoredMessage(interceptionType, method.getJavaMethod()) + "its single argument is not a " + InvocationContext.class.getName()); } return false; } return true; } else { if (!Object.class.equals(method.getReturnType())) { if (LOG.isWarnEnabled()) { LOG.warn( getStandardIgnoredMessage(interceptionType, method.getJavaMethod()) + "does not return a " + OBJECT_CLASS_NAME); } return false; } Class<?>[] parameterTypes = method.getJavaMethod().getParameterTypes(); if (parameterTypes.length != 1) { if (LOG.isWarnEnabled()) { LOG.debug( getStandardIgnoredMessage(interceptionType, method.getJavaMethod()) + "does not have exactly 1 parameter"); } return false; } if (!InvocationContext.class.isAssignableFrom(parameterTypes[0])) { if (LOG.isWarnEnabled()) { LOG.debug( getStandardIgnoredMessage(interceptionType, method.getJavaMethod()) + "does not have a " + InvocationContext.class.getName() + " parameter "); } return false; } return true; } }