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.security.remoting.jmx; 019 020 import java.io.Serializable; 021 import java.lang.reflect.Method; 022 import java.util.Collections; 023 import java.util.HashMap; 024 import java.util.Map; 025 import java.util.WeakHashMap; 026 027 import org.apache.geronimo.kernel.ClassLoading; 028 029 /** 030 * @version $Rev: 417891 $ $Date: 2006-06-28 15:45:07 -0700 (Wed, 28 Jun 2006) $ 031 */ 032 public class MarshalledMethod implements Serializable { 033 034 String declaringClass; 035 String signature; 036 037 /** 038 * 039 */ 040 public MarshalledMethod() { 041 } 042 043 /** 044 * @param method 045 */ 046 public MarshalledMethod(Method method) { 047 declaringClass = method.getDeclaringClass().getName(); 048 signature = getSignature( method ); 049 } 050 051 /** 052 * @param method 053 * @return 054 */ 055 static public String getSignature(Method method) { 056 StringBuffer sb = new StringBuffer(); 057 sb.append(method.getName()); 058 sb.append(' '); 059 Class[] args = method.getParameterTypes(); 060 for (int i = 0; i < args.length; i++) { 061 sb.append(' '); 062 sb.append( ClassLoading.getClassName(args[i]) ); 063 } 064 return sb.toString(); 065 } 066 067 /** 068 * @return 069 */ 070 public Method getMethod() throws ClassNotFoundException { 071 Class c = Thread.currentThread().getContextClassLoader().loadClass(declaringClass); 072 Map sigs = getCachedSignatureMap(c); 073 return (Method) sigs.get(signature); 074 } 075 076 /** 077 * TODO: try to cache the results. 078 * @param clazz 079 * @return 080 */ 081 static private Map getSignatureMapFor(Class clazz) { 082 Map rc = new HashMap(); 083 Method[] methods = clazz.getDeclaredMethods(); 084 for (int i = 0; i < methods.length; i++) { 085 Method method = methods[i]; 086 rc.put(getSignature(method), method); 087 } 088 return rc; 089 } 090 091 private static Map SignatureMapCache= Collections.synchronizedMap(new WeakHashMap()); 092 static class CacheValue { 093 Class clazz; 094 Map sigs; 095 } 096 097 098 public static Map getCachedSignatureMap(Class clazz) { 099 String cacheKey = clazz.getName(); 100 CacheValue rc = (CacheValue) SignatureMapCache.get(cacheKey); 101 if (rc == null) { 102 rc = new CacheValue(); 103 rc.clazz = clazz; 104 rc.sigs = getSignatureMapFor(clazz); 105 SignatureMapCache.put(cacheKey, rc); 106 return rc.sigs; 107 } else if ( rc.clazz.equals( clazz ) ) { 108 return rc.sigs; 109 } else { 110 // the previously cache class name might not be the same class 111 // due to classloader issues. 112 return getSignatureMapFor(clazz); 113 } 114 115 } 116 117 118 119 }