View Javadoc

1   /**
2    *
3    * Copyright 2003-2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.geronimo.gbean.runtime;
19  
20  import java.lang.reflect.Method;
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import org.apache.geronimo.gbean.DynamicGBean;
27  import org.apache.geronimo.gbean.DynamicGOperationInfo;
28  import org.apache.geronimo.gbean.GOperationInfo;
29  import org.apache.geronimo.gbean.InvalidConfigurationException;
30  import org.apache.geronimo.kernel.ClassLoading;
31  
32  /**
33   * @version $Rev: 389907 $ $Date: 2006-03-29 14:16:54 -0800 (Wed, 29 Mar 2006) $
34   */
35  public final class GBeanOperation {
36      private final GBeanInstance gbeanInstance;
37      private final String name;
38      private final List parameterTypes;
39      private final MethodInvoker methodInvoker;
40      private final boolean framework;
41      private final GOperationInfo operationInfo;
42  
43      static GBeanOperation createFrameworkOperation(GBeanInstance gbeanInstance, String name, List parameterTypes, MethodInvoker methodInvoker) {
44          return new GBeanOperation(gbeanInstance, name, parameterTypes, methodInvoker);
45      }
46  
47      private GBeanOperation(GBeanInstance gbeanInstance, String name, List parameterTypes, MethodInvoker methodInvoker) {
48          framework = true;
49          this.gbeanInstance = gbeanInstance;
50          this.name = name;
51          this.parameterTypes = Collections.unmodifiableList(new ArrayList(parameterTypes));
52          this.methodInvoker = methodInvoker;
53          this.operationInfo = new GOperationInfo(this.name, this.parameterTypes);
54      }
55  
56      public GBeanOperation(GBeanInstance gbeanInstance, GOperationInfo operationInfo) throws InvalidConfigurationException {
57          framework = false;
58          this.gbeanInstance = gbeanInstance;
59          this.name = operationInfo.getName();
60          this.operationInfo = operationInfo;
61  
62          // get an array of the parameter classes
63          this.parameterTypes = Collections.unmodifiableList(new ArrayList(operationInfo.getParameterList()));
64          Class[] types = new Class[parameterTypes.size()];
65          ClassLoader classLoader = gbeanInstance.getClassLoader();
66          for (int i = 0; i < types.length; i++) {
67              String type = (String) parameterTypes.get(i);
68              try {
69                  types[i] = ClassLoading.loadClass((String) parameterTypes.get(i), classLoader);
70              } catch (ClassNotFoundException e) {
71                  throw new InvalidConfigurationException("Could not load operation parameter class:" +
72                          " name=" + operationInfo.getName() +
73                          " class=" + type);
74              }
75          }
76  
77          // get a method invoker for the operation
78          if (operationInfo instanceof DynamicGOperationInfo) {
79              methodInvoker = new MethodInvoker() {
80                  private String[] types = (String[]) parameterTypes.toArray(new String[parameterTypes.size()]);
81  
82                  public Object invoke(Object target, Object[] arguments) throws Exception {
83                      DynamicGBean dynamicGBean = (DynamicGBean) target;
84                      dynamicGBean.invoke(name, arguments, types);
85                      return null;
86                  }
87              };
88          } else {
89              try {
90                  Method javaMethod = gbeanInstance.getType().getMethod(operationInfo.getMethodName(), types);
91                  if (AbstractGBeanReference.NO_PROXY) {
92                      methodInvoker = new ReflectionMethodInvoker(javaMethod);
93                  } else {
94                      methodInvoker = new FastMethodInvoker(javaMethod);
95                  }
96              } catch (Exception e) {
97                  throw new InvalidConfigurationException("Target does not have specified method (declared in a GBeanInfo operation):" +
98                          " name=" + operationInfo.getName() +
99                          " methodName=" + operationInfo.getMethodName() +
100                         " targetClass=" + gbeanInstance.getType().getName());
101             }
102         }
103     }
104 
105     public String getName() {
106         return name;
107     }
108 
109     public List getParameterTypes() {
110         return parameterTypes;
111     }
112 
113     public GOperationInfo getOperationInfo() {
114         return operationInfo;
115     }
116 
117     public boolean isFramework() {
118         return framework;
119     }
120 
121     public Object invoke(Object target, final Object[] arguments) throws Exception {
122         return methodInvoker.invoke(target, arguments);
123     }
124 
125     public String getDescription() {
126         String signature = name + "(";
127         for (Iterator iterator = parameterTypes.iterator(); iterator.hasNext();) {
128             String type = (String) iterator.next();
129             signature += type;
130             if (iterator.hasNext()) {
131                 signature += ", ";
132             }
133         }
134         signature += ")";
135         return "Operation Signature: " + signature + ", GBeanInstance: " + gbeanInstance.getName();
136     }
137 }