View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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   */
16  package org.kuali.rice.krad.uif.component;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
20  import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
21  import org.springframework.util.MethodInvoker;
22  import org.springframework.util.ReflectionUtils;
23  
24  import java.io.Serializable;
25  import java.lang.reflect.Method;
26  
27  /**
28   * Extends <code>MethodInvoker</code> to add properties for specifying
29   * a method for invocation within the UIF
30   *
31   * @author Kuali Rice Team (rice.collab@kuali.org)
32   */
33  @BeanTag(name = "methodInvokerConfig-bean", parent = "Uif-MethodInvokerConfig")
34  public class MethodInvokerConfig extends MethodInvoker implements Serializable {
35      private static final long serialVersionUID = 6626790175367500081L;
36  
37      private String staticMethod;
38      private Class[] argumentTypes;
39  
40      /**
41       * Set a fully qualified static method name to invoke,
42       * e.g. "example.MyExampleClass.myExampleMethod".
43       * Convenient alternative to specifying targetClass and targetMethod.
44       *
45       * @return static method to invoke
46       */
47      @BeanTagAttribute(name="staticMethod")
48      public String getStaticMethod() {
49          return staticMethod;
50      }
51  
52      /**
53       * Override to catch a set staticMethod since super does
54       * not contain a getter
55       *
56       * @param staticMethod static method to invoke
57       */
58      @Override
59      public void setStaticMethod(String staticMethod) {
60          super.setStaticMethod(staticMethod);
61          this.staticMethod = staticMethod;
62      }
63  
64      /**
65       * Declared argument types for the method to be invoked, if not set the types will
66       * be retrieved based on the target class and target name
67       *
68       * @return method argument types
69       */
70      @BeanTagAttribute(name="argumentTypes",type= BeanTagAttribute.AttributeType.LISTBEAN)
71      public Class[] getArgumentTypes() {
72          if (argumentTypes == null) {
73              return getMethodArgumentTypes();
74          }
75  
76          return argumentTypes;
77      }
78  
79      /**
80       * Setter for the method argument types that should be invoked
81       *
82       * @param argumentTypes
83       */
84      public void setArgumentTypes(Class[] argumentTypes) {
85          this.argumentTypes = argumentTypes;
86      }
87  
88      /**
89       * Finds the method on the target class that matches the target name and
90       * returns the declared parameter types
91       *
92       * @return method parameter types
93       */
94      protected Class[] getMethodArgumentTypes() {
95          if (StringUtils.isNotBlank(staticMethod)) {
96              int lastDotIndex = this.staticMethod.lastIndexOf('.');
97              if (lastDotIndex == -1 || lastDotIndex == this.staticMethod.length()) {
98                  throw new IllegalArgumentException("staticMethod must be a fully qualified class plus method name: " +
99                          "e.g. 'example.MyExampleClass.myExampleMethod'");
100             }
101             String className = this.staticMethod.substring(0, lastDotIndex);
102             String methodName = this.staticMethod.substring(lastDotIndex + 1);
103             try {
104                 setTargetClass(resolveClassName(className));
105             } catch (ClassNotFoundException e) {
106                 throw new RuntimeException("Unable to get class for name: " + className);
107             }
108             setTargetMethod(methodName);
109         }
110 
111         Method[] candidates = ReflectionUtils.getAllDeclaredMethods(getTargetClass());
112         for (Method candidate : candidates) {
113             if (candidate.getName().equals(getTargetMethod())) {
114                 return candidate.getParameterTypes();
115             }
116         }
117 
118         return null;
119     }
120 
121 }