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 }