package nl.tudelft.simulation.language.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 The Java Virtual Machine
* Specification .
*
* Copyright (c) 2002-2009 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights
* reserved.
*
* See for project information www.simulation.tudelft.nl.
*
* The DSOL project is distributed under the following BSD-style license:
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* - Neither the name of Delft University of Technology, nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and any express or implied warranties,
* including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are
* disclaimed. In no event shall the copyright holder or contributors be liable for any direct, indirect, incidental,
* special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or
* services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability,
* whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use
* of this software, even if advised of the possibility of such damage.
* @author Peter Jacobs, Niels Lang, Alexander Verbraeck
* @version $Revision: 1.2 $ $Date: 2009/10/21 07:32:43 $
* @since 1.5
*/
public class MethodSignature implements Serializable
{
/** The default serial version UID for serializable classes. */
private static final long serialVersionUID = 1L;
/** the value of the methodDescriptor. */
private String value = null;
/**
* constructs a new MethodSignature.
* @param value the descriptor
*/
public MethodSignature(final String value)
{
super();
this.value = value;
}
/**
* constructs a new MethodSignature.
* @param method the method
*/
public MethodSignature(final Method method)
{
super();
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 the constructor
*/
public MethodSignature(final Constructor> constructor)
{
super();
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);
}
/** {@inheritDoc} */
@Override
public String toString()
{
return this.value;
}
/**
* @return Returns the parameterDescriptor
* @param methodDescriptor the methodDescriptor
*/
public static String getParameterDescriptor(final String methodDescriptor)
{
return methodDescriptor.substring(1, methodDescriptor.indexOf(')'));
}
/**
* returns the parameterTypes
* @param methodDescriptor 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> result = new ArrayList>();
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 the methodDescriptor
*/
public static String getReturnDescriptor(final String methodDescriptor)
{
return methodDescriptor.substring(methodDescriptor.indexOf(')') + 1);
}
/**
* returns the returnType of this methodDescriptor
* @param methodDescriptor 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));
}
}