001
014
015 package com.liferay.portal.kernel.util;
016
017 import java.util.ArrayList;
018
019
022 public class MethodParameter {
023
024 public MethodParameter(String name, String signatures, Class<?> type) {
025 _name = name;
026 _signatures = signatures;
027 _type = type;
028 }
029
030 public Class<?>[] getGenericTypes() throws ClassNotFoundException {
031 if (_initialized) {
032 return _genericTypes;
033 }
034
035 String[] genericSignatures = _extractTopLevelGenericSignatures(
036 _signatures);
037
038 if (genericSignatures == null) {
039 _genericTypes = null;
040 }
041 else {
042 _genericTypes = _loadGenericTypes(genericSignatures);
043 }
044
045 _initialized = true;
046
047 return _genericTypes;
048 }
049
050 public String getName() {
051 return _name;
052 }
053
054 public String getSignature() {
055 return _signatures;
056 }
057
058 public Class<?> getType() {
059 return _type;
060 }
061
062 private static String[] _extractTopLevelGenericSignatures(
063 String signature) {
064
065 if (signature == null) {
066 return null;
067 }
068
069 int leftBracketIndex = signature.indexOf(CharPool.LESS_THAN);
070
071 if (leftBracketIndex == -1) {
072 return null;
073 }
074
075 int rightBracketIndex = signature.lastIndexOf(CharPool.GREATER_THAN);
076
077 if (rightBracketIndex == -1) {
078 return null;
079 }
080
081 String generics = signature.substring(
082 leftBracketIndex + 1, rightBracketIndex);
083
084 StringBuilder sb = new StringBuilder(generics.length());
085
086 ArrayList<String> list = new ArrayList<String>();
087
088 int level = 0;
089
090 for (int i = 0; i < generics.length(); i++) {
091 char c = generics.charAt(i);
092
093 if (c == '<') {
094 level++;
095 }
096 else if (c == '>') {
097 level--;
098 }
099 else if (level == 0) {
100 sb.append(c);
101
102 if (c == ';') {
103 list.add(sb.toString());
104
105 sb.setLength(0);
106 }
107 }
108 }
109
110 return list.toArray(new String[list.size()]);
111 }
112
113 private static Class<?>[] _loadGenericTypes(String[] signatures)
114 throws ClassNotFoundException {
115
116 Thread currentThread = Thread.currentThread();
117
118 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
119
120 Class<?>[] types = new Class<?>[signatures.length];
121
122 for (int i = 0; i < signatures.length; i++) {
123 String className = signatures[i];
124
125 char c = className.charAt(0);
126
127 if (c == 'B') {
128 types[i] = byte.class;
129 }
130 else if (c == 'C') {
131 types[i] = char.class;
132 }
133 else if (c == 'D') {
134 types[i] = double.class;
135 }
136 else if (c == 'F') {
137 types[i] = float.class;
138 }
139 else if (c == 'I') {
140 types[i] = int.class;
141 }
142 else if (c == 'J') {
143 types[i] = long.class;
144 }
145 else if (c == 'L') {
146 className = className.substring(1, className.length() - 1);
147 className = className.replace(CharPool.SLASH, CharPool.PERIOD);
148
149 types[i] = contextClassLoader.loadClass(className);
150 }
151 else if (c == 'S') {
152 types[i] = short.class;
153 }
154 else if (c == 'Z') {
155 types[i] = boolean.class;
156 }
157 else if (c == 'V') {
158 types[i] = void.class;
159 }
160 else if (c == CharPool.OPEN_BRACKET) {
161 className = className.replace(CharPool.SLASH, CharPool.PERIOD);
162
163 types[i] = contextClassLoader.loadClass(className);
164 }
165 else {
166 throw new ClassNotFoundException(className);
167 }
168 }
169
170 return types;
171 }
172
173 private Class<?>[] _genericTypes;
174 private boolean _initialized;
175 private String _name;
176 private String _signatures;
177 private Class<?> _type;
178
179 }