1 | /* |
2 | * Copyright (c) 2001-2009, Jean Tessier |
3 | * All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * |
9 | * * Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * |
12 | * * Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * |
16 | * * Neither the name of Jean Tessier nor the names of his contributors |
17 | * may be used to endorse or promote products derived from this software |
18 | * without specific prior written permission. |
19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR |
24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | */ |
32 | |
33 | package com.jeantessier.classreader; |
34 | |
35 | import java.util.*; |
36 | |
37 | import org.apache.log4j.*; |
38 | |
39 | public final class SignatureHelper { |
40 | private static Map<String, String> conversion = new HashMap<String, String>(); |
41 | |
42 | static { |
43 | conversion.put("B", "byte"); |
44 | conversion.put("C", "char"); |
45 | conversion.put("D", "double"); |
46 | conversion.put("F", "float"); |
47 | conversion.put("I", "int"); |
48 | conversion.put("J", "long"); |
49 | conversion.put("S", "short"); |
50 | conversion.put("V", "void"); |
51 | conversion.put("Z", "boolean"); |
52 | } |
53 | |
54 | private SignatureHelper() { |
55 | // Prevent instantiation |
56 | } |
57 | |
58 | public static String convert(String type) { |
59 | String result = null; |
60 | |
61 | Logger.getLogger(SignatureHelper.class).debug("Begin Convert(\"" + type + "\")"); |
62 | |
63 | if (type.length() == 1) { |
64 | result = conversion.get(type); |
65 | } else if (type.charAt(0) == 'L') { |
66 | result = ClassNameHelper.path2ClassName(type.substring(1, type.indexOf(';'))); |
67 | } else if (type.charAt(0) == 'T') { |
68 | result = ClassNameHelper.path2ClassName(type.substring(1, type.indexOf(';'))); |
69 | } else if (type.charAt(0) == '[') { |
70 | result = convert(type.substring(1)) + "[]"; |
71 | } |
72 | |
73 | Logger.getLogger(SignatureHelper.class).debug("End Convert(\"" + type + "\"): \"" + result + "\""); |
74 | |
75 | return result; |
76 | } |
77 | |
78 | public static String getSignature(String descriptor) { |
79 | StringBuffer result = new StringBuffer(); |
80 | |
81 | Logger.getLogger(SignatureHelper.class).debug("Begin Signature(\"" + descriptor + "\")"); |
82 | |
83 | result.append("("); |
84 | |
85 | int start = descriptor.indexOf("(") + 1; |
86 | int end = descriptor.indexOf(")"); |
87 | |
88 | Iterator i = new SignatureIterator(descriptor.substring(start, end)); |
89 | while (i.hasNext()) { |
90 | result.append(i.next()); |
91 | if (i.hasNext()) { |
92 | result.append(", "); |
93 | } |
94 | } |
95 | |
96 | result.append(")"); |
97 | |
98 | Logger.getLogger(SignatureHelper.class).debug("End Signature(\"" + descriptor + "\"): \"" + result + "\""); |
99 | |
100 | return result.toString(); |
101 | } |
102 | |
103 | public static int getParameterCount(String descriptor) { |
104 | int result = 0; |
105 | |
106 | Logger.getLogger(SignatureHelper.class).debug("Begin ParameterCount(\"" + descriptor + "\")"); |
107 | |
108 | int start = descriptor.indexOf("(") + 1; |
109 | int end = descriptor.indexOf(")"); |
110 | |
111 | Iterator i = new SignatureIterator(descriptor.substring(start, end)); |
112 | while (i.hasNext()) { |
113 | i.next(); |
114 | result++; |
115 | } |
116 | |
117 | Logger.getLogger(SignatureHelper.class).debug("End ParameterCount(\"" + descriptor + "\"): \"" + result + "\""); |
118 | |
119 | return result; |
120 | } |
121 | |
122 | public static String getReturnType(String descriptor) { |
123 | return convert(descriptor.substring(descriptor.lastIndexOf(")") + 1)); |
124 | } |
125 | |
126 | public static String getType(String descriptor) { |
127 | return convert(descriptor); |
128 | } |
129 | } |
130 | |
131 | class SignatureIterator implements Iterator { |
132 | private String descriptor; |
133 | private int currentPos = 0; |
134 | |
135 | public SignatureIterator(String descriptor) { |
136 | this.descriptor = descriptor; |
137 | } |
138 | |
139 | public boolean hasNext() { |
140 | return currentPos < descriptor.length(); |
141 | } |
142 | |
143 | public Object next() { |
144 | String result; |
145 | |
146 | if (hasNext()) { |
147 | int nextPos = currentPos; |
148 | |
149 | while (descriptor.charAt(nextPos) == '[') { |
150 | nextPos++; |
151 | } |
152 | |
153 | if (descriptor.charAt(nextPos) == 'L') { |
154 | nextPos = descriptor.indexOf(";", nextPos); |
155 | } |
156 | |
157 | if (descriptor.charAt(nextPos) == 'T') { |
158 | nextPos = descriptor.indexOf(";", nextPos); |
159 | } |
160 | |
161 | result = SignatureHelper.convert(descriptor.substring(currentPos, nextPos + 1)); |
162 | |
163 | currentPos = nextPos + 1; |
164 | } else { |
165 | throw new NoSuchElementException(); |
166 | } |
167 | |
168 | return result; |
169 | } |
170 | |
171 | public void remove() { |
172 | throw new UnsupportedOperationException(); |
173 | } |
174 | } |