001
014
015 package com.liferay.portal.kernel.util;
016
017 import java.util.ArrayList;
018 import java.util.List;
019
020
023 public class MethodParameter {
024
025 public MethodParameter(
026 String name, String signatures, Class<?> type, boolean initialize) {
027
028 _name = name;
029 _signatures = signatures;
030 _type = type;
031
032 if (initialize) {
033 try {
034 getGenericTypes();
035 }
036 catch (ClassNotFoundException cnfe) {
037 throw new IllegalArgumentException(cnfe);
038 }
039 }
040 }
041
042 public Class<?>[] getGenericTypes() throws ClassNotFoundException {
043 if (_initialized) {
044 return _genericTypes;
045 }
046
047 _genericTypes = _getGenericTypes(_signatures);
048
049 _initialized = true;
050
051 return _genericTypes;
052 }
053
054 public String getName() {
055 return _name;
056 }
057
058 public String getSignature() {
059 return _signatures;
060 }
061
062 public Class<?> getType() {
063 return _type;
064 }
065
066 private String _getClassName(String signature) {
067 String className = signature;
068
069 char c = signature.charAt(0);
070
071 if (_isPrimitive(c)) {
072 if (signature.length() != 1) {
073 throw new IllegalArgumentException(
074 "Invalid signature " + signature);
075 }
076 }
077 else if (c == 'L') {
078 className = className.substring(1, className.length() - 1);
079 className = className.replace(CharPool.SLASH, CharPool.PERIOD);
080 }
081 else if (c == '[') {
082 className = className.replace(CharPool.SLASH, CharPool.PERIOD);
083 }
084 else {
085 throw new IllegalArgumentException(
086 "Invalid signature " + signature);
087 }
088
089 return className;
090 }
091
092 private ClassLoader _getContextClassLoader() {
093 if (_contextClassLoader != null) {
094 return _contextClassLoader;
095 }
096
097 Thread currentThread = Thread.currentThread();
098
099 _contextClassLoader = currentThread.getContextClassLoader();
100
101 return _contextClassLoader;
102 }
103
104 private String _getGenericName(String typeName) {
105 if (typeName.equals(StringPool.STAR)) {
106 return null;
107 }
108
109 if (typeName.startsWith(StringPool.MINUS) ||
110 typeName.startsWith(StringPool.PLUS)) {
111
112 typeName = typeName.substring(1);
113 }
114
115 return typeName;
116 }
117
118 private Class<?> _getGenericType(String signature)
119 throws ClassNotFoundException {
120
121 ClassLoader contextClassLoader = _getContextClassLoader();
122
123 String className = _getClassName(signature);
124
125 if (className.startsWith(StringPool.OPEN_BRACKET)) {
126 try {
127 return Class.forName(className, true, contextClassLoader);
128 }
129 catch (ClassNotFoundException cnfe) {
130 }
131 }
132
133 return contextClassLoader.loadClass(className);
134 }
135
136 private Class<?>[] _getGenericTypes(String signatures)
137 throws ClassNotFoundException {
138
139 if (signatures == null) {
140 return null;
141 }
142
143 int leftBracketIndex = signatures.indexOf(CharPool.LESS_THAN);
144
145 if (leftBracketIndex == -1) {
146 return null;
147 }
148
149 int rightBracketIndex = signatures.lastIndexOf(CharPool.GREATER_THAN);
150
151 if (rightBracketIndex == -1) {
152 return null;
153 }
154
155 String generics = signatures.substring(
156 leftBracketIndex + 1, rightBracketIndex);
157
158 List<Class<?>> genericTypeslist = new ArrayList<>();
159
160 int level = 0;
161 int index = 0;
162
163 while (index < generics.length()) {
164 char c = generics.charAt(index);
165
166 index++;
167
168 if (c == CharPool.LESS_THAN) {
169 level++;
170 }
171 else if (c == CharPool.GREATER_THAN) {
172 level--;
173 }
174 else if (level == 0) {
175 String extractedTopLevelGenericName = null;
176
177 if (c == 'L') {
178 int bracketIndex = generics.indexOf(
179 StringPool.LESS_THAN, index);
180 int endIndex =
181 generics.indexOf(StringPool.SEMICOLON, index) + 1;
182
183 if ((bracketIndex != -1) && (bracketIndex < endIndex)) {
184 endIndex = bracketIndex;
185
186 extractedTopLevelGenericName = _getGenericName(
187 generics.substring(index - 1, endIndex));
188 extractedTopLevelGenericName =
189 extractedTopLevelGenericName.concat(
190 StringPool.SEMICOLON);
191 }
192 else {
193 extractedTopLevelGenericName = _getGenericName(
194 generics.substring(index - 1, endIndex));
195 }
196
197 index = endIndex;
198 }
199 else if (c == '[') {
200 char nextChar = generics.charAt(index);
201
202 if (_isPrimitive(nextChar)) {
203 extractedTopLevelGenericName = _getGenericName(
204 generics.substring(index - 1, index + 1));
205
206 index++;
207 }
208 else if (nextChar == 'L') {
209 int endIndex =
210 generics.indexOf(StringPool.SEMICOLON, index) + 1;
211
212 extractedTopLevelGenericName = _getGenericName(
213 generics.substring(index - 1, endIndex));
214
215 index = endIndex;
216 }
217 }
218
219 if (Validator.isNotNull(extractedTopLevelGenericName)) {
220 genericTypeslist.add(
221 _getGenericType(extractedTopLevelGenericName));
222 }
223 }
224 }
225
226 if (genericTypeslist.isEmpty()) {
227 return null;
228 }
229
230 return genericTypeslist.toArray(new Class<?>[genericTypeslist.size()]);
231 }
232
233 private boolean _isPrimitive(char c) {
234 if ((c == 'B') || (c == 'C') || (c == 'D') || (c == 'F') ||
235 (c == 'I') || (c == 'J') || (c == 'S') || (c == 'V') ||
236 (c == 'Z')) {
237
238 return true;
239 }
240 else {
241 return false;
242 }
243 }
244
245 private ClassLoader _contextClassLoader;
246 private Class<?>[] _genericTypes;
247 private boolean _initialized;
248 private final String _name;
249 private final String _signatures;
250 private final Class<?> _type;
251
252 }