001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import java.io.Serializable;
018    
019    import java.lang.reflect.Method;
020    
021    import java.util.HashMap;
022    import java.util.Map;
023    
024    /**
025     * @author Brian Wing Shun Chan
026     * @author Shuyang Zhou
027     */
028    public class MethodKey implements Serializable {
029    
030            public MethodKey(Method method) {
031                    this(
032                            method.getDeclaringClass().getName(), method.getName(),
033                            method.getParameterTypes());
034            }
035    
036            public MethodKey(
037                    String className, String methodName, Class<?>... parameterTypes) {
038    
039                    _className = className;
040                    _methodName = methodName;
041                    _parameterTypes = parameterTypes;
042            }
043    
044            public MethodKey(
045                            String className, String methodName, String[] parameterTypeNames)
046                    throws ClassNotFoundException {
047    
048                    _className = className;
049                    _methodName = methodName;
050    
051                    _parameterTypes = new Class[parameterTypeNames.length];
052    
053                    ClassLoader classLoader = null;
054    
055                    if (parameterTypeNames.length > 0) {
056                            Thread currentThread = Thread.currentThread();
057    
058                            classLoader = currentThread.getContextClassLoader();
059                    }
060    
061                    for (int i = 0; i < parameterTypeNames.length; i++) {
062                            String parameterTypeName = parameterTypeNames[i];
063    
064                            _parameterTypes[i] = _getClass(parameterTypeName, classLoader);
065                    }
066            }
067    
068            @Override
069            public boolean equals(Object obj) {
070                    if (obj == null) {
071                            return false;
072                    }
073    
074                    MethodKey methodKey = (MethodKey)obj;
075    
076                    String string = toString();
077    
078                    if (string.equals(methodKey.toString())) {
079                            return true;
080                    }
081                    else {
082                            return false;
083                    }
084            }
085    
086            public String getClassName() {
087                    return _className;
088            }
089    
090            public String getMethodName() {
091                    return _methodName;
092            }
093    
094            public Class<?>[] getParameterTypes() {
095                    return _parameterTypes;
096            }
097    
098            @Override
099            public int hashCode() {
100                    return toString().hashCode();
101            }
102    
103            @Override
104            public String toString() {
105                    return _toString();
106            }
107    
108            private Class<?> _getClass(String typeName, ClassLoader classLoader)
109                    throws ClassNotFoundException {
110    
111                    if (_primitiveClasses.containsKey(typeName)) {
112                            return _primitiveClasses.get(typeName);
113                    }
114                    else {
115                            return Class.forName(typeName, true, classLoader);
116                    }
117            }
118    
119            private String _toString() {
120                    if (_toString == null) {
121                            if ((_parameterTypes != null) && (_parameterTypes.length > 0)) {
122                                    StringBundler sb = new StringBundler(
123                                            3 + _parameterTypes.length);
124    
125                                    sb.append(_className);
126                                    sb.append(_methodName);
127                                    sb.append(StringPool.DASH);
128    
129                                    for (Class<?> parameterType : _parameterTypes) {
130                                            sb.append(parameterType.getName());
131                                    }
132    
133                                    _toString = sb.toString();
134                            }
135                            else {
136                                    _toString = _className.concat(_methodName);
137                            }
138                    }
139    
140                    return _toString;
141            }
142    
143            private static Map<String, Class<?>> _primitiveClasses =
144                    new HashMap<String, Class<?>>();
145    
146            static {
147                    _primitiveClasses.put("byte", byte.class);
148                    _primitiveClasses.put("boolean", boolean.class);
149                    _primitiveClasses.put("char", char.class);
150                    _primitiveClasses.put("double", double.class);
151                    _primitiveClasses.put("float", float.class);
152                    _primitiveClasses.put("int", int.class);
153                    _primitiveClasses.put("long", long.class);
154                    _primitiveClasses.put("short", short.class);
155            }
156    
157            private String _className;
158            private String _methodName;
159            private Class<?>[] _parameterTypes;
160            private String _toString;
161    
162    }