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 }