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    }