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: */package org.apache.geronimo.gbean.runtime;
017:
018: import java.lang.reflect.Method;
019: import java.util.ArrayList;
020: import java.util.Collections;
021: import java.util.Iterator;
022: import java.util.List;
023:
024: import org.apache.geronimo.gbean.DynamicGBean;
025: import org.apache.geronimo.gbean.DynamicGOperationInfo;
026: import org.apache.geronimo.gbean.GOperationInfo;
027: import org.apache.geronimo.gbean.InvalidConfigurationException;
028: import org.apache.geronimo.kernel.ClassLoading;
029:
030: /**
031: * @version $Rev: 558235 $ $Date: 2007-07-20 20:47:45 -0700 (Fri, 20 Jul 2007) $
032: */
033: public final class GBeanOperation {
034: private final GBeanInstance gbeanInstance;
035: private final String name;
036: private final List parameterTypes;
037: private final MethodInvoker methodInvoker;
038: private final boolean framework;
039: private final GOperationInfo operationInfo;
040:
041: static GBeanOperation createFrameworkOperation(
042: GBeanInstance gbeanInstance, String name,
043: List parameterTypes, MethodInvoker methodInvoker) {
044: return new GBeanOperation(gbeanInstance, name, parameterTypes,
045: methodInvoker);
046: }
047:
048: private GBeanOperation(GBeanInstance gbeanInstance, String name,
049: List parameterTypes, MethodInvoker methodInvoker) {
050: framework = true;
051: this .gbeanInstance = gbeanInstance;
052: this .name = name;
053: this .parameterTypes = Collections
054: .unmodifiableList(new ArrayList(parameterTypes));
055: this .methodInvoker = methodInvoker;
056: // this is not used
057: this .operationInfo = new GOperationInfo(this .name,
058: this .parameterTypes, "java.lang.Object");
059: }
060:
061: public GBeanOperation(GBeanInstance gbeanInstance,
062: GOperationInfo operationInfo)
063: throws InvalidConfigurationException {
064: framework = false;
065: this .gbeanInstance = gbeanInstance;
066: this .name = operationInfo.getName();
067: this .operationInfo = operationInfo;
068:
069: // get an array of the parameter classes
070: this .parameterTypes = Collections
071: .unmodifiableList(new ArrayList(operationInfo
072: .getParameterList()));
073: Class[] types = new Class[parameterTypes.size()];
074: ClassLoader classLoader = gbeanInstance.getClassLoader();
075: for (int i = 0; i < types.length; i++) {
076: String type = (String) parameterTypes.get(i);
077: try {
078: types[i] = ClassLoading.loadClass(
079: (String) parameterTypes.get(i), classLoader);
080: } catch (ClassNotFoundException e) {
081: throw new InvalidConfigurationException(
082: "Could not load operation parameter class:"
083: + " name=" + operationInfo.getName()
084: + " class=" + type, e);
085: }
086: }
087:
088: // get a method invoker for the operation
089: if (operationInfo instanceof DynamicGOperationInfo) {
090: methodInvoker = new MethodInvoker() {
091: private String[] types = (String[]) parameterTypes
092: .toArray(new String[parameterTypes.size()]);
093:
094: public Object invoke(Object target, Object[] arguments)
095: throws Exception {
096: DynamicGBean dynamicGBean = (DynamicGBean) target;
097: dynamicGBean.invoke(name, arguments, types);
098: return null;
099: }
100: };
101: } else {
102: try {
103: Method javaMethod = gbeanInstance.getType().getMethod(
104: operationInfo.getMethodName(), types);
105: if (AbstractGBeanReference.NO_PROXY) {
106: methodInvoker = new ReflectionMethodInvoker(
107: javaMethod);
108: } else {
109: methodInvoker = new FastMethodInvoker(javaMethod);
110: }
111: } catch (Exception e) {
112: throw new InvalidConfigurationException(
113: "Target does not have specified method (declared in a GBeanInfo operation):"
114: + " name=" + operationInfo.getName()
115: + " methodName="
116: + operationInfo.getMethodName()
117: + " returnType="
118: + operationInfo.getReturnType()
119: + " targetClass="
120: + gbeanInstance.getType().getName(), e);
121: }
122: }
123: }
124:
125: public String getName() {
126: return name;
127: }
128:
129: public List getParameterTypes() {
130: return parameterTypes;
131: }
132:
133: public GOperationInfo getOperationInfo() {
134: return operationInfo;
135: }
136:
137: public boolean isFramework() {
138: return framework;
139: }
140:
141: public Object invoke(Object target, final Object[] arguments)
142: throws Exception {
143: return methodInvoker.invoke(target, arguments);
144: }
145:
146: public String getDescription() {
147: String signature = name + "(";
148: for (Iterator iterator = parameterTypes.iterator(); iterator
149: .hasNext();) {
150: String type = (String) iterator.next();
151: signature += type;
152: if (iterator.hasNext()) {
153: signature += ", ";
154: }
155: }
156: signature += ")";
157: return "Operation Signature: " + signature
158: + ", GBeanInstance: " + gbeanInstance.getName();
159: }
160: }
|