001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. 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: 558235 $ $Date: 2007-07-20 23:47:45 -0400 (Fri, 20 Jul 2007) $
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 is not used
054 this.operationInfo = new GOperationInfo(this.name, this.parameterTypes, "java.lang.Object");
055 }
056
057 public GBeanOperation(GBeanInstance gbeanInstance, GOperationInfo operationInfo) throws InvalidConfigurationException {
058 framework = false;
059 this.gbeanInstance = gbeanInstance;
060 this.name = operationInfo.getName();
061 this.operationInfo = operationInfo;
062
063 // get an array of the parameter classes
064 this.parameterTypes = Collections.unmodifiableList(new ArrayList(operationInfo.getParameterList()));
065 Class[] types = new Class[parameterTypes.size()];
066 ClassLoader classLoader = gbeanInstance.getClassLoader();
067 for (int i = 0; i < types.length; i++) {
068 String type = (String) parameterTypes.get(i);
069 try {
070 types[i] = ClassLoading.loadClass((String) parameterTypes.get(i), classLoader);
071 } catch (ClassNotFoundException e) {
072 throw new InvalidConfigurationException("Could not load operation parameter class:" +
073 " name=" + operationInfo.getName() +
074 " class=" + type, e);
075 }
076 }
077
078 // get a method invoker for the operation
079 if (operationInfo instanceof DynamicGOperationInfo) {
080 methodInvoker = new MethodInvoker() {
081 private String[] types = (String[]) parameterTypes.toArray(new String[parameterTypes.size()]);
082
083 public Object invoke(Object target, Object[] arguments) throws Exception {
084 DynamicGBean dynamicGBean = (DynamicGBean) target;
085 dynamicGBean.invoke(name, arguments, types);
086 return null;
087 }
088 };
089 } else {
090 try {
091 Method javaMethod = gbeanInstance.getType().getMethod(operationInfo.getMethodName(), types);
092 if (AbstractGBeanReference.NO_PROXY) {
093 methodInvoker = new ReflectionMethodInvoker(javaMethod);
094 } else {
095 methodInvoker = new FastMethodInvoker(javaMethod);
096 }
097 } catch (Exception e) {
098 throw new InvalidConfigurationException("Target does not have specified method (declared in a GBeanInfo operation):" +
099 " name=" + operationInfo.getName() +
100 " methodName=" + operationInfo.getMethodName() +
101 " returnType=" + operationInfo.getReturnType() +
102 " targetClass=" + gbeanInstance.getType().getName(), e);
103 }
104 }
105 }
106
107 public String getName() {
108 return name;
109 }
110
111 public List getParameterTypes() {
112 return parameterTypes;
113 }
114
115 public GOperationInfo getOperationInfo() {
116 return operationInfo;
117 }
118
119 public boolean isFramework() {
120 return framework;
121 }
122
123 public Object invoke(Object target, final Object[] arguments) throws Exception {
124 return methodInvoker.invoke(target, arguments);
125 }
126
127 public String getDescription() {
128 String signature = name + "(";
129 for (Iterator iterator = parameterTypes.iterator(); iterator.hasNext();) {
130 String type = (String) iterator.next();
131 signature += type;
132 if (iterator.hasNext()) {
133 signature += ", ";
134 }
135 }
136 signature += ")";
137 return "Operation Signature: " + signature + ", GBeanInstance: " + gbeanInstance.getName();
138 }
139 }