View Javadoc
1   package org.djutils.reflection;
2   
3   import java.io.Serializable;
4   import java.lang.reflect.Constructor;
5   import java.lang.reflect.Method;
6   import java.util.ArrayList;
7   import java.util.List;
8   
9   /**
10   * A method descriptor represents the parameters that the method takes and the value that it returns. It is a series of
11   * characters generated by the grammar described at
12   * <a href = "https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3"> The Java Virtual Machine
13   * Specification: Method Descriptors </a>.
14   * <p>
15   * Copyright (c) 2002-2019 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
16   * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
17   * distributed under a three-clause BSD-style license, which can be found at
18   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
19   * </p>
20   * @author Peter Jacobs, Niels Lang, Alexander Verbraeck
21   */
22  public class MethodSignature implements Serializable
23  {
24      /** The default serial version UID for serializable classes. */
25      private static final long serialVersionUID = 1L;
26  
27      /** the value of the methodDescriptor. */
28      private String value = null;
29  
30      /**
31       * constructs a new MethodSignature.
32       * @param value String; the descriptor
33       */
34      public MethodSignature(final String value)
35      {
36          super();
37          this.value = value;
38      }
39  
40      /**
41       * constructs a new MethodSignature.
42       * @param method Method; the method
43       */
44      public MethodSignature(final Method method)
45      {
46          super();
47          Class<?>[] parameterTypes = new Class<?>[0];
48          if (method.getParameterTypes() != null)
49          {
50              parameterTypes = method.getParameterTypes();
51          }
52          this.value = "(";
53          for (int i = 0; i < parameterTypes.length; i++)
54          {
55              this.value = this.value + FieldSignature.toDescriptor(parameterTypes[i]);
56          }
57          this.value = this.value + ")" + FieldSignature.toDescriptor(method.getReturnType());
58      }
59  
60      /**
61       * constructs a new MethodSignature.
62       * @param constructor Constructor&lt;?&gt;; the constructor
63       */
64      public MethodSignature(final Constructor<?> constructor)
65      {
66          super();
67          Class<?>[] parameterTypes = new Class<?>[0];
68          if (constructor.getParameterTypes() != null)
69          {
70              parameterTypes = constructor.getParameterTypes();
71          }
72  
73          this.value = "(";
74          for (int i = 0; i < parameterTypes.length; i++)
75          {
76              this.value = this.value + FieldSignature.toDescriptor(parameterTypes[i]);
77          }
78          this.value = this.value + ")" + FieldSignature.toDescriptor(constructor.getDeclaringClass());
79      }
80  
81      /**
82       * @return Returns the parameterDescriptor
83       */
84      public String getParameterDescriptor()
85      {
86          return MethodSignature.getParameterDescriptor(this.value);
87      }
88  
89      /**
90       * returns the parameterTypes
91       * @return ClassDescriptor[] the result
92       * @throws ClassNotFoundException on incomplete classPath
93       */
94      public Class<?>[] getParameterTypes() throws ClassNotFoundException
95      {
96          return MethodSignature.getParameterTypes(this.value);
97      }
98  
99      /**
100      * @return Returns the returnDescriptor
101      */
102     public String getReturnDescriptor()
103     {
104         return MethodSignature.getReturnDescriptor(this.value);
105     }
106 
107     /**
108      * returns the returnType of this methodDescriptor
109      * @return Returns the returnType
110      * @throws ClassNotFoundException on incomplete classPath
111      */
112     public Class<?> getReturnType() throws ClassNotFoundException
113     {
114         return MethodSignature.getReturnType(this.value);
115     }
116 
117     /** {@inheritDoc} */
118     @Override
119     public String toString()
120     {
121         return this.value;
122     }
123 
124     /**
125      * @return Returns the parameterDescriptor
126      * @param methodDescriptor String; the methodDescriptor
127      */
128     public static String getParameterDescriptor(final String methodDescriptor)
129     {
130         return methodDescriptor.substring(1, methodDescriptor.indexOf(')'));
131     }
132 
133     /**
134      * returns the parameterTypes
135      * @param methodDescriptor String; the string
136      * @return ClassDescriptor[] the result
137      * @throws ClassNotFoundException on incomplete classPath
138      */
139     public static Class<?>[] getParameterTypes(final String methodDescriptor) throws ClassNotFoundException
140     {
141         String parameterDescriptor = MethodSignature.getParameterDescriptor(methodDescriptor);
142         List<Class<?>> result = new ArrayList<Class<?>>();
143         int length = 0;
144         while (length < parameterDescriptor.length())
145         {
146             String array = "";
147             while (parameterDescriptor.charAt(length) == '[')
148             {
149                 array = array + "[";
150                 length++;
151             }
152             if (parameterDescriptor.charAt(length) == 'L')
153             {
154                 String argument = parameterDescriptor.substring(length);
155                 argument = array + argument.substring(0, argument.indexOf(';') + 1);
156                 result.add(FieldSignature.toClass(argument));
157                 length = length + argument.length() - array.length();
158             }
159             else
160             {
161                 result.add(FieldSignature.toClass(array + parameterDescriptor.charAt(length)));
162                 length++;
163             }
164         }
165         return result.toArray(new Class<?>[result.size()]);
166     }
167 
168     /**
169      * @return Returns the returnDescriptor
170      * @param methodDescriptor String; the methodDescriptor
171      */
172     public static String getReturnDescriptor(final String methodDescriptor)
173     {
174         return methodDescriptor.substring(methodDescriptor.indexOf(')') + 1);
175     }
176 
177     /**
178      * returns the returnType of this methodDescriptor
179      * @param methodDescriptor String; the returnDescriptor
180      * @return Returns the returnType
181      * @throws ClassNotFoundException on incomplete classPath
182      */
183     public static Class<?> getReturnType(final String methodDescriptor) throws ClassNotFoundException
184     {
185         return FieldSignature.toClass(MethodSignature.getReturnDescriptor(methodDescriptor));
186     }
187 }