001 /**
002 *
003 * Copyright 2003-2004 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.gbean.runtime;
019
020 import java.lang.reflect.Method;
021 import java.util.ArrayList;
022 import java.util.Collections;
023 import java.util.Iterator;
024 import java.util.List;
025
026 import org.apache.geronimo.gbean.DynamicGBean;
027 import org.apache.geronimo.gbean.DynamicGOperationInfo;
028 import org.apache.geronimo.gbean.GOperationInfo;
029 import org.apache.geronimo.gbean.InvalidConfigurationException;
030 import org.apache.geronimo.kernel.ClassLoading;
031
032 /**
033 * @version $Rev: 389907 $ $Date: 2006-03-29 14:16:54 -0800 (Wed, 29 Mar 2006) $
034 */
035 public final class GBeanOperation {
036 private final GBeanInstance gbeanInstance;
037 private final String name;
038 private final List parameterTypes;
039 private final MethodInvoker methodInvoker;
040 private final boolean framework;
041 private final GOperationInfo operationInfo;
042
043 static GBeanOperation createFrameworkOperation(GBeanInstance gbeanInstance, String name, List parameterTypes, MethodInvoker methodInvoker) {
044 return new GBeanOperation(gbeanInstance, name, parameterTypes, methodInvoker);
045 }
046
047 private GBeanOperation(GBeanInstance gbeanInstance, String name, List parameterTypes, MethodInvoker methodInvoker) {
048 framework = true;
049 this.gbeanInstance = gbeanInstance;
050 this.name = name;
051 this.parameterTypes = Collections.unmodifiableList(new ArrayList(parameterTypes));
052 this.methodInvoker = methodInvoker;
053 this.operationInfo = new GOperationInfo(this.name, this.parameterTypes);
054 }
055
056 public GBeanOperation(GBeanInstance gbeanInstance, GOperationInfo operationInfo) throws InvalidConfigurationException {
057 framework = false;
058 this.gbeanInstance = gbeanInstance;
059 this.name = operationInfo.getName();
060 this.operationInfo = operationInfo;
061
062 // get an array of the parameter classes
063 this.parameterTypes = Collections.unmodifiableList(new ArrayList(operationInfo.getParameterList()));
064 Class[] types = new Class[parameterTypes.size()];
065 ClassLoader classLoader = gbeanInstance.getClassLoader();
066 for (int i = 0; i < types.length; i++) {
067 String type = (String) parameterTypes.get(i);
068 try {
069 types[i] = ClassLoading.loadClass((String) parameterTypes.get(i), classLoader);
070 } catch (ClassNotFoundException e) {
071 throw new InvalidConfigurationException("Could not load operation parameter class:" +
072 " name=" + operationInfo.getName() +
073 " class=" + type);
074 }
075 }
076
077 // get a method invoker for the operation
078 if (operationInfo instanceof DynamicGOperationInfo) {
079 methodInvoker = new MethodInvoker() {
080 private String[] types = (String[]) parameterTypes.toArray(new String[parameterTypes.size()]);
081
082 public Object invoke(Object target, Object[] arguments) throws Exception {
083 DynamicGBean dynamicGBean = (DynamicGBean) target;
084 dynamicGBean.invoke(name, arguments, types);
085 return null;
086 }
087 };
088 } else {
089 try {
090 Method javaMethod = gbeanInstance.getType().getMethod(operationInfo.getMethodName(), types);
091 if (AbstractGBeanReference.NO_PROXY) {
092 methodInvoker = new ReflectionMethodInvoker(javaMethod);
093 } else {
094 methodInvoker = new FastMethodInvoker(javaMethod);
095 }
096 } catch (Exception e) {
097 throw new InvalidConfigurationException("Target does not have specified method (declared in a GBeanInfo operation):" +
098 " name=" + operationInfo.getName() +
099 " 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 }