EMMA Coverage Report (generated Thu May 22 12:08:10 CDT 2014)
[all classes][org.springframework.batch.support]

COVERAGE SUMMARY FOR SOURCE FILE [MethodInvokerUtils.java]

nameclass, %method, %block, %line, %
MethodInvokerUtils.java0%   (0/4)0%   (0/13)0%   (0/391)0%   (0/69)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MethodInvokerUtils0%   (0/1)0%   (0/7)0%   (0/222)0%   (0/43)
MethodInvokerUtils (): void 0%   (0/1)0%   (0/3)0%   (0/1)
getMethodInvokerByAnnotation (Class, Object): MethodInvoker 0%   (0/1)0%   (0/67)0%   (0/13)
getMethodInvokerByAnnotation (Class, Object, Class []): MethodInvoker 0%   (0/1)0%   (0/27)0%   (0/6)
getMethodInvokerByName (Object, String, boolean, Class []): MethodInvoker 0%   (0/1)0%   (0/56)0%   (0/10)
getMethodInvokerForInterface (Class, String, Object, Class []): MethodInvoker 0%   (0/1)0%   (0/13)0%   (0/3)
getMethodInvokerForSingleArgument (Object): MethodInvoker 0%   (0/1)0%   (0/21)0%   (0/4)
getParamTypesString (Class []): String 0%   (0/1)0%   (0/35)0%   (0/6)
     
class MethodInvokerUtils$10%   (0/1)0%   (0/2)0%   (0/85)0%   (0/13)
MethodInvokerUtils$1 (Class, Class, Class []): void 0%   (0/1)0%   (0/12)0%   (0/1)
doWith (Method): void 0%   (0/1)0%   (0/73)0%   (0/12)
     
class MethodInvokerUtils$20%   (0/1)0%   (0/2)0%   (0/46)0%   (0/8)
MethodInvokerUtils$2 (Class, AtomicReference, Class): void 0%   (0/1)0%   (0/12)0%   (0/1)
doWith (Method): void 0%   (0/1)0%   (0/34)0%   (0/7)
     
class MethodInvokerUtils$30%   (0/1)0%   (0/2)0%   (0/38)0%   (0/8)
MethodInvokerUtils$3 (AtomicReference): void 0%   (0/1)0%   (0/6)0%   (0/1)
doWith (Method): void 0%   (0/1)0%   (0/32)0%   (0/7)

1/*
2 * Copyright 2002-2008 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.springframework.batch.support;
17 
18import java.lang.annotation.Annotation;
19import java.lang.annotation.ElementType;
20import java.lang.annotation.Target;
21import java.lang.reflect.Method;
22import java.util.concurrent.atomic.AtomicReference;
23 
24import org.springframework.aop.framework.Advised;
25import org.springframework.core.annotation.AnnotationUtils;
26import org.springframework.util.Assert;
27import org.springframework.util.ClassUtils;
28import org.springframework.util.ObjectUtils;
29import org.springframework.util.ReflectionUtils;
30 
31/**
32 * Utility methods for create MethodInvoker instances.
33 * 
34 * @author Lucas Ward
35 * @since 2.0
36 */
37public class MethodInvokerUtils {
38 
39        /**
40         * Create a {@link MethodInvoker} using the provided method name to search.
41         * 
42         * @param object to be invoked
43         * @param methodName of the method to be invoked
44         * @param paramsRequired boolean indicating whether the parameters are
45         * required, if false, a no args version of the method will be searched for.
46         * @param paramTypes - parameter types of the method to search for.
47         * @return MethodInvoker if the method is found, null if it is not.
48         */
49        public static MethodInvoker getMethodInvokerByName(Object object, String methodName, boolean paramsRequired,
50                        Class<?>... paramTypes) {
51                Assert.notNull(object, "Object to invoke must not be null");
52                Method method = ClassUtils.getMethodIfAvailable(object.getClass(), methodName, paramTypes);
53                if (method == null) {
54                        String errorMsg = "no method found with name [" + methodName + "] on class ["
55                                        + object.getClass().getSimpleName() + "] compatable with the signature ["
56                                        + getParamTypesString(paramTypes) + "].";
57                        Assert.isTrue(!paramsRequired, errorMsg);
58                        // if no method was found for the given parameters, and the
59                        // parameters aren't required, then try with no params
60                        method = ClassUtils.getMethodIfAvailable(object.getClass(), methodName, new Class[] {});
61                        Assert.notNull(method, errorMsg);
62                }
63                return new SimpleMethodInvoker(object, method);
64        }
65 
66        /**
67         * Create a String representation of the array of parameter types.
68         * 
69         * @param paramTypes
70         * @return String
71         */
72        public static String getParamTypesString(Class<?>... paramTypes) {
73                StringBuffer paramTypesList = new StringBuffer("(");
74                for (int i = 0; i < paramTypes.length; i++) {
75                        paramTypesList.append(paramTypes[i].getSimpleName());
76                        if (i + 1 < paramTypes.length) {
77                                paramTypesList.append(", ");
78                        }
79                }
80                return paramTypesList.append(")").toString();
81        }
82 
83        /**
84         * Create a {@link MethodInvoker} using the provided interface, and method
85         * name from that interface.
86         * 
87         * @param cls the interface to search for the method named
88         * @param methodName of the method to be invoked
89         * @param object to be invoked
90         * @param paramTypes - parameter types of the method to search for.
91         * @return MethodInvoker if the method is found, null if it is not.
92         */
93        public static MethodInvoker getMethodInvokerForInterface(Class<?> cls, String methodName, Object object,
94                        Class<?>... paramTypes) {
95 
96                if (cls.isAssignableFrom(object.getClass())) {
97                        return MethodInvokerUtils.getMethodInvokerByName(object, methodName, true, paramTypes);
98                }
99                else {
100                        return null;
101                }
102        }
103 
104        /**
105         * Create a MethodInvoker from the delegate based on the annotationType.
106         * Ensure that the annotated method has a valid set of parameters.
107         * 
108         * @param annotationType the annotation to scan for
109         * @param target the target object
110         * @param expectedParamTypes the expected parameter types for the method
111         * @return a MethodInvoker
112         */
113        public static MethodInvoker getMethodInvokerByAnnotation(final Class<? extends Annotation> annotationType,
114                        final Object target, final Class<?>... expectedParamTypes) {
115                MethodInvoker mi = MethodInvokerUtils.getMethodInvokerByAnnotation(annotationType, target);
116                final Class<?> targetClass = (target instanceof Advised) ? ((Advised) target).getTargetSource()
117                                .getTargetClass() : target.getClass();
118                if (mi != null) {
119                        ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() {
120                @Override
121                                public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
122                                        Annotation annotation = AnnotationUtils.findAnnotation(method, annotationType);
123                                        if (annotation != null) {
124                                                Class<?>[] paramTypes = method.getParameterTypes();
125                                                if (paramTypes.length > 0) {
126                                                        String errorMsg = "The method [" + method.getName() + "] on target class ["
127                                                                        + targetClass.getSimpleName() + "] is incompatable with the signature ["
128                                                                        + getParamTypesString(expectedParamTypes) + "] expected for the annotation ["
129                                                                        + annotationType.getSimpleName() + "].";
130 
131                                                        Assert.isTrue(paramTypes.length == expectedParamTypes.length, errorMsg);
132                                                        for (int i = 0; i < paramTypes.length; i++) {
133                                                                Assert.isTrue(expectedParamTypes[i].isAssignableFrom(paramTypes[i]), errorMsg);
134                                                        }
135                                                }
136                                        }
137                                }
138                        });
139                }
140                return mi;
141        }
142 
143        /**
144         * Create {@link MethodInvoker} for the method with the provided annotation
145         * on the provided object. Annotations that cannot be applied to methods
146         * (i.e. that aren't annotated with an element type of METHOD) will cause an
147         * exception to be thrown.
148         * 
149         * @param annotationType to be searched for
150         * @param target to be invoked
151         * @return MethodInvoker for the provided annotation, null if none is found.
152         */
153        public static MethodInvoker getMethodInvokerByAnnotation(final Class<? extends Annotation> annotationType,
154                        final Object target) {
155                Assert.notNull(target, "Target must not be null");
156                Assert.notNull(annotationType, "AnnotationType must not be null");
157                Assert.isTrue(ObjectUtils.containsElement(annotationType.getAnnotation(Target.class).value(),
158                                ElementType.METHOD), "Annotation [" + annotationType + "] is not a Method-level annotation.");
159                final Class<?> targetClass = (target instanceof Advised) ? ((Advised) target).getTargetSource()
160                                .getTargetClass() : target.getClass();
161                if (targetClass == null) {
162                        // Proxy with no target cannot have annotations
163                        return null;
164                }
165                final AtomicReference<Method> annotatedMethod = new AtomicReference<Method>();
166                ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() {
167            @Override
168                        public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
169                                Annotation annotation = AnnotationUtils.findAnnotation(method, annotationType);
170                                if (annotation != null) {
171                                        Assert.isNull(annotatedMethod.get(), "found more than one method on target class ["
172                                                        + targetClass.getSimpleName() + "] with the annotation type ["
173                                                        + annotationType.getSimpleName() + "].");
174                                        annotatedMethod.set(method);
175                                }
176                        }
177                });
178                Method method = annotatedMethod.get();
179                if (method == null) {
180                        return null;
181                }
182                else {
183                        return new SimpleMethodInvoker(target, annotatedMethod.get());
184                }
185        }
186 
187        /**
188         * Create a {@link MethodInvoker} for the delegate from a single public
189         * method.
190         * 
191         * @param target an object to search for an appropriate method
192         * @return a MethodInvoker that calls a method on the delegate
193         */
194        public static <C, T> MethodInvoker getMethodInvokerForSingleArgument(Object target) {
195                final AtomicReference<Method> methodHolder = new AtomicReference<Method>();
196                ReflectionUtils.doWithMethods(target.getClass(), new ReflectionUtils.MethodCallback() {
197            @Override
198                        public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
199                                if (method.getParameterTypes() == null || method.getParameterTypes().length != 1) {
200                                        return;
201                                }
202                                if (method.getReturnType().equals(Void.TYPE) || ReflectionUtils.isEqualsMethod(method)) {
203                                        return;
204                                }
205                                Assert.state(methodHolder.get() == null,
206                                                "More than one non-void public method detected with single argument.");
207                                methodHolder.set(method);
208                        }
209                });
210                Method method = methodHolder.get();
211                return new SimpleMethodInvoker(target, method);
212        }
213}

[all classes][org.springframework.batch.support]
EMMA 2.0.5312 (C) Vladimir Roubtsov