001 /*
002 * $Id: SignatureHelper.java,v 1.6 2013/08/31 20:00:26 oboehm Exp $
003 *
004 * Copyright (c) 2009 by Oliver Boehm
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 *
018 * (c)reated 03.04.2009 by oliver (ob@aosd.de)
019 */
020 package patterntesting.runtime.util;
021
022 import java.lang.reflect.*;
023
024 import org.apache.commons.lang.StringUtils;
025 import org.aspectj.lang.*;
026 import org.aspectj.lang.reflect.*;
027 import org.slf4j.*;
028
029 import patterntesting.runtime.util.reflect.*;
030
031 /**
032 * The Class SignatureHelper.
033 *
034 * @author <a href="boehm@javatux.de">oliver</a>
035 * @since 03.04.2009
036 * @version $Revision: 1.6 $
037 */
038 public class SignatureHelper {
039
040 private static final Logger log = LoggerFactory.getLogger(SignatureHelper.class);
041
042 /** Utility class - no need to instantiate it */
043 private SignatureHelper() {}
044
045 /**
046 * The difference to Signature.toString() is that in case of a methode
047 * or constructor the return type is not part of result.
048 *
049 * @param sig the sig
050 *
051 * @return the given signature as string
052 */
053 public static String getAsString(final Signature sig) {
054 try {
055 CodeSignature codeSig = (CodeSignature) sig;
056 String name = getAsString(sig.getDeclaringTypeName(), sig);
057 Class<?>[] params = codeSig.getParameterTypes();
058 return name + "(" + Converter.toShortString(params) + ")";
059 } catch (Exception e) {
060 log.debug("can't get '" + sig + "' as String", e);
061 return sig.toString();
062 }
063 }
064
065 /**
066 * Gets the as string.
067 *
068 * @param type the type
069 * @param sig the sig
070 *
071 * @return the as string
072 */
073 public static String getAsString(final String type, final Signature sig) {
074 String name = sig.getName();
075 if (name.equals("<init>")) {
076 return "new " + type;
077 } else {
078 return type + "." + name;
079 }
080 }
081
082 /**
083 * Gets the as signature.
084 *
085 * @param method the method
086 *
087 * @return the as signature
088 */
089 public static MethodSignature getAsSignature(final Method method) {
090 return new MethodSignatureImpl(method);
091 }
092
093 /**
094 * Gets the as signature.
095 *
096 * @param ctor the ctor
097 *
098 * @return the as signature
099 */
100 public static ConstructorSignature getAsSignature(final Constructor<?> ctor) {
101 return new ConstructorSignatureImpl(ctor);
102 }
103
104 /**
105 * Gets the as signature.
106 *
107 * @param label e.g. "java.lang.String.substring(int)" or
108 * "new java.lang.String()
109 *
110 * @return the given label as Signature
111 *
112 * @throws ClassNotFoundException the class not found exception
113 * @throws NoSuchMethodException the no such method exception
114 * @throws SecurityException the security exception
115 */
116 public static Signature getAsSignature(final String label)
117 throws ClassNotFoundException, SecurityException,
118 NoSuchMethodException {
119 if (label.startsWith("new ")) {
120 return getAsConstructorSignature(label);
121 }
122 String classDotMethod = StringUtils.substringBefore(label, "(");
123 String className = StringUtils.substringBeforeLast(classDotMethod, ".");
124 String methodName = StringUtils.substringAfterLast(classDotMethod, ".");
125 Class<?>[] params = getParameterTypes(label);
126 return getAsSignature(Class.forName(className), methodName, params);
127 }
128
129 private static Signature getAsSignature(final Class<?> clazz, final String methodName,
130 final Class<?>[] parameterTypes) throws ClassNotFoundException, SecurityException,
131 NoSuchMethodException {
132 Method method = clazz.getMethod(methodName, parameterTypes);
133 return getAsSignature(method);
134 }
135
136 private static ConstructorSignature getAsConstructorSignature(final String label)
137 throws ClassNotFoundException, SecurityException,
138 NoSuchMethodException {
139 String ctor = StringUtils.substringAfterLast(label, " ").trim();
140 String className = StringUtils.substringBefore(ctor, "(");
141 Class<?>[] params = getParameterTypes(label);
142 return getAsConstructorSignature(Class.forName(className), params);
143 }
144
145 private static ConstructorSignature getAsConstructorSignature(final Class<?> clazz,
146 final Class<?>[] parameterTypes) throws ClassNotFoundException, SecurityException,
147 NoSuchMethodException {
148 Constructor<?> ctor = clazz.getConstructor(parameterTypes);
149 return getAsSignature(ctor);
150 }
151
152 private static Class<?>[] getParameterTypes(final String label)
153 throws ClassNotFoundException {
154 String parameters = StringUtils.substringAfter(label, "(");
155 parameters = StringUtils.substringBefore(parameters, ")");
156 String[] params = StringUtils.split(parameters, ',');
157 Class<?>[] parameterTypes = new Class<?>[params.length];
158 for (int i = 0; i < params.length; i++) {
159 parameterTypes[i] = Class.forName(params[i].trim());
160 }
161 return parameterTypes;
162 }
163
164 /**
165 * Returns true if the given signature is a {@link MethodSignature} and
166 * the return value is not of type 'void'.
167 *
168 * @param signature the signature
169 * @return true, if successful
170 * @since 1.3.1
171 */
172 public static boolean hasReturnType(final Signature signature) {
173 if (signature instanceof MethodSignature) {
174 MethodSignature methodSignature = (MethodSignature) signature;
175 if (methodSignature.getReturnType() != void.class) {
176 return true;
177 }
178 }
179 return false;
180 }
181
182 }