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