/* * Copyright (C) 2015 Sebastian Daschner, sebastian-daschner.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sebastian_daschner.jaxrs_analyzer.model.methods; import com.sebastian_daschner.jaxrs_analyzer.model.JavaUtils; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; import static java.util.Arrays.asList; /** * The method type signature with which a method can be identified. * * @author Sebastian Daschner */ public class MethodIdentifier { /** * The containing class as JVM class name, e.g. {@code java/lang/String}. */ private final String containingClass; private final String methodName; /** * The return type as JVM type descriptor, e.g. {@code Ljava/lang/String;}. */ private final String returnType; private final boolean staticMethod; private final List<String> parameters; private MethodIdentifier(final String containingClass, final String methodName, final List<String> parameters, final String returnType, final boolean staticMethod) { Objects.requireNonNull(containingClass); Objects.requireNonNull(methodName); Objects.requireNonNull(returnType); this.containingClass = containingClass; this.methodName = methodName; this.returnType = returnType; this.staticMethod = staticMethod; this.parameters = parameters; } /** * Returns the method signature, e.g. {@code (Ljava/lang/String;)V}. */ public String getSignature() { final StringBuilder builder = new StringBuilder("("); parameters.forEach(builder::append); return builder.append(')').append(returnType).toString(); } public String getContainingClass() { return containingClass; } public String getMethodName() { return methodName; } public List<String> getParameters() { return parameters; } public String getReturnType() { return returnType; } public boolean isStaticMethod() { return staticMethod; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MethodIdentifier that = (MethodIdentifier) o; if (staticMethod != that.staticMethod) return false; if (!containingClass.equals(that.containingClass)) return false; if (!methodName.equals(that.methodName)) return false; if (parameters.equals(that.parameters)) return true; // fallback if signature matches after type erasure if (parameters.size() == that.parameters.size()) { final List<String> erasedTypes = parameters.stream().map(JavaUtils::toClassName).collect(Collectors.toList()); final List<String> erasedThatTypes = that.parameters.stream().map(JavaUtils::toClassName).collect(Collectors.toList()); final String erasedReturnType = JavaUtils.toClassName(returnType); final String erasedThatReturnType = JavaUtils.toClassName(that.returnType); return erasedTypes.equals(erasedThatTypes) && erasedReturnType.equals(erasedThatReturnType); } return false; } @Override public int hashCode() { int result = containingClass.hashCode(); result = 31 * result + methodName.hashCode(); result = 31 * result + returnType.hashCode(); result = 31 * result + (staticMethod ? 1 : 0); result = 31 * result + parameters.hashCode(); return result; } @Override public String toString() { return "MethodIdentifier{" + "containingClass='" + containingClass + '\'' + ", methodName='" + methodName + '\'' + ", returnType='" + returnType + '\'' + ", staticMethod=" + staticMethod + ", parameters=" + parameters + '}'; } /** * Creates an identifier of the given parameters. * * @param containingClass The class name * @param methodName The method name * @param signature The method signature * @param staticMethod If the method is static * @return The method identifier */ public static MethodIdentifier of(final String containingClass, final String methodName, final String signature, final boolean staticMethod) { final String returnType = JavaUtils.getReturnType(signature); final List<String> parameters = JavaUtils.getParameters(signature); return new MethodIdentifier(containingClass, methodName, parameters, returnType, staticMethod); } /** * Creates an identifier of a non-static method. * * @param containingClass The class name * @param methodName The method name * @param returnType The return type * @param parameterTypes The parameter types * @return The method identifier */ public static MethodIdentifier ofNonStatic(final String containingClass, final String methodName, final String returnType, final String... parameterTypes) { return of(containingClass, methodName, returnType, false, parameterTypes); } /** * Creates an identifier of a static method. * * @param containingClass The class name * @param methodName The method name * @param returnType The return type * @param parameterTypes The parameter types * @return The method identifier */ public static MethodIdentifier ofStatic(final String containingClass, final String methodName, final String returnType, final String... parameterTypes) { return of(containingClass, methodName, returnType, true, parameterTypes); } private static MethodIdentifier of(String containingClass, String methodName, String returnType, final boolean staticMethod, String[] parameterTypes) { Objects.requireNonNull(parameterTypes); return new MethodIdentifier(containingClass, methodName, asList(parameterTypes), returnType, staticMethod); } }