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 }