MethodSignature.java
package org.djutils.reflection;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* A method descriptor represents the parameters that the method takes and the value that it returns. It is a series of
* characters generated by the grammar described at
* <a href = "https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3"> The Java Virtual Machine
* Specification: Method Descriptors </a>.
* <p>
* Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
* for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
* distributed under a three-clause BSD-style license, which can be found at
* <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
* </p>
* @author Peter Jacobs, Niels Lang, Alexander Verbraeck
*/
public class MethodSignature implements Serializable
{
/** The default serial version UID for serializable classes. */
private static final long serialVersionUID = 20191230L;
/** the value of the methodDescriptor. */
private String value = null;
/**
* constructs a new MethodSignature.
* @param value String; the descriptor
*/
public MethodSignature(final String value)
{
this.value = value;
}
/**
* constructs a new MethodSignature.
* @param method Method; the method
*/
public MethodSignature(final Method method)
{
Class<?>[] parameterTypes = new Class<?>[0];
if (method.getParameterTypes() != null)
{
parameterTypes = method.getParameterTypes();
}
this.value = "(";
for (int i = 0; i < parameterTypes.length; i++)
{
this.value = this.value + FieldSignature.toDescriptor(parameterTypes[i]);
}
this.value = this.value + ")" + FieldSignature.toDescriptor(method.getReturnType());
}
/**
* constructs a new MethodSignature.
* @param constructor Constructor<?>; the constructor
*/
public MethodSignature(final Constructor<?> constructor)
{
Class<?>[] parameterTypes = new Class<?>[0];
if (constructor.getParameterTypes() != null)
{
parameterTypes = constructor.getParameterTypes();
}
this.value = "(";
for (int i = 0; i < parameterTypes.length; i++)
{
this.value = this.value + FieldSignature.toDescriptor(parameterTypes[i]);
}
this.value = this.value + ")" + FieldSignature.toDescriptor(constructor.getDeclaringClass());
}
/**
* @return Returns the parameterDescriptor
*/
public String getParameterDescriptor()
{
return MethodSignature.getParameterDescriptor(this.value);
}
/**
* returns the parameterTypes.
* @return ClassDescriptor[] the result
* @throws ClassNotFoundException on incomplete classPath
*/
public Class<?>[] getParameterTypes() throws ClassNotFoundException
{
return MethodSignature.getParameterTypes(this.value);
}
/**
* @return Returns the returnDescriptor.
*/
public String getReturnDescriptor()
{
return MethodSignature.getReturnDescriptor(this.value);
}
/**
* returns the returnType of this methodDescriptor.
* @return Returns the returnType
* @throws ClassNotFoundException on incomplete classPath
*/
public Class<?> getReturnType() throws ClassNotFoundException
{
return MethodSignature.getReturnType(this.value);
}
@Override
public String toString()
{
return this.value;
}
/**
* @return Returns the parameterDescriptor
* @param methodDescriptor String; the methodDescriptor
*/
public static String getParameterDescriptor(final String methodDescriptor)
{
return methodDescriptor.substring(1, methodDescriptor.indexOf(')'));
}
/**
* returns the parameterTypes.
* @param methodDescriptor String; the string
* @return ClassDescriptor[] the result
* @throws ClassNotFoundException on incomplete classPath
*/
public static Class<?>[] getParameterTypes(final String methodDescriptor) throws ClassNotFoundException
{
String parameterDescriptor = MethodSignature.getParameterDescriptor(methodDescriptor);
List<Class<?>> result = new ArrayList<Class<?>>();
int length = 0;
while (length < parameterDescriptor.length())
{
String array = "";
while (parameterDescriptor.charAt(length) == '[')
{
array = array + "[";
length++;
}
if (parameterDescriptor.charAt(length) == 'L')
{
String argument = parameterDescriptor.substring(length);
argument = array + argument.substring(0, argument.indexOf(';') + 1);
result.add(FieldSignature.toClass(argument));
length = length + argument.length() - array.length();
}
else
{
result.add(FieldSignature.toClass(array + parameterDescriptor.charAt(length)));
length++;
}
}
return result.toArray(new Class<?>[result.size()]);
}
/**
* @return Returns the returnDescriptor
* @param methodDescriptor String; the methodDescriptor
*/
public static String getReturnDescriptor(final String methodDescriptor)
{
return methodDescriptor.substring(methodDescriptor.indexOf(')') + 1);
}
/**
* returns the returnType of this methodDescriptor.
* @param methodDescriptor String; the returnDescriptor
* @return Returns the returnType
* @throws ClassNotFoundException on incomplete classPath
*/
public static Class<?> getReturnType(final String methodDescriptor) throws ClassNotFoundException
{
return FieldSignature.toClass(MethodSignature.getReturnDescriptor(methodDescriptor));
}
}