/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.kernel.util;
import java.util.ArrayList;
import java.util.List;
/**
* @author Igor Spasic
*/
public class MethodParameter {
public MethodParameter(String name, String signatures, Class<?> type) {
_name = name;
_type = type;
try {
Thread currentThread = Thread.currentThread();
ClassLoader contextClassLoader =
currentThread.getContextClassLoader();
_genericTypes = _getGenericTypes(contextClassLoader, signatures);
}
catch (ClassNotFoundException cnfe) {
throw new IllegalArgumentException(cnfe);
}
}
public Class<?>[] getGenericTypes() {
return _genericTypes;
}
public String getName() {
return _name;
}
public Class<?> getType() {
return _type;
}
private String _getClassName(String signature) {
String className = signature;
char c = signature.charAt(0);
if (_isPrimitive(c)) {
if (signature.length() != 1) {
throw new IllegalArgumentException(
"Invalid signature " + signature);
}
}
else if (c == 'L') {
className = className.substring(1, className.length() - 1);
className = className.replace(CharPool.SLASH, CharPool.PERIOD);
}
else if (c == '[') {
className = className.replace(CharPool.SLASH, CharPool.PERIOD);
}
else {
throw new IllegalArgumentException(
"Invalid signature " + signature);
}
return className;
}
private String _getGenericName(String typeName) {
if (typeName.equals(StringPool.STAR)) {
return null;
}
if (typeName.startsWith(StringPool.MINUS) ||
typeName.startsWith(StringPool.PLUS)) {
typeName = typeName.substring(1);
}
return typeName;
}
private Class<?> _getGenericType(
ClassLoader contextClassLoader, String signature)
throws ClassNotFoundException {
String className = _getClassName(signature);
if (className.startsWith(StringPool.OPEN_BRACKET)) {
try {
return Class.forName(className, true, contextClassLoader);
}
catch (ClassNotFoundException cnfe) {
}
}
return contextClassLoader.loadClass(className);
}
private Class<?>[] _getGenericTypes(
ClassLoader contextClassLoader, String signatures)
throws ClassNotFoundException {
if (signatures == null) {
return null;
}
int leftBracketIndex = signatures.indexOf(CharPool.LESS_THAN);
if (leftBracketIndex == -1) {
return null;
}
int rightBracketIndex = signatures.lastIndexOf(CharPool.GREATER_THAN);
if (rightBracketIndex == -1) {
return null;
}
String generics = signatures.substring(
leftBracketIndex + 1, rightBracketIndex);
List<Class<?>> genericTypeslist = new ArrayList<>();
int level = 0;
int index = 0;
while (index < generics.length()) {
char c = generics.charAt(index);
index++;
if (c == CharPool.LESS_THAN) {
level++;
}
else if (c == CharPool.GREATER_THAN) {
level--;
}
else if (level == 0) {
String extractedTopLevelGenericName = null;
if (c == 'L') {
int bracketIndex = generics.indexOf(
StringPool.LESS_THAN, index);
int endIndex =
generics.indexOf(StringPool.SEMICOLON, index) + 1;
if ((bracketIndex != -1) && (bracketIndex < endIndex)) {
endIndex = bracketIndex;
extractedTopLevelGenericName = _getGenericName(
generics.substring(index - 1, endIndex));
extractedTopLevelGenericName =
extractedTopLevelGenericName.concat(
StringPool.SEMICOLON);
}
else {
extractedTopLevelGenericName = _getGenericName(
generics.substring(index - 1, endIndex));
}
index = endIndex;
}
else if (c == '[') {
char nextChar = generics.charAt(index);
if (_isPrimitive(nextChar)) {
extractedTopLevelGenericName = _getGenericName(
generics.substring(index - 1, index + 1));
index++;
}
else if (nextChar == 'L') {
int endIndex =
generics.indexOf(StringPool.SEMICOLON, index) + 1;
extractedTopLevelGenericName = _getGenericName(
generics.substring(index - 1, endIndex));
index = endIndex;
}
}
if (Validator.isNotNull(extractedTopLevelGenericName)) {
genericTypeslist.add(
_getGenericType(
contextClassLoader, extractedTopLevelGenericName));
}
}
}
if (genericTypeslist.isEmpty()) {
return null;
}
return genericTypeslist.toArray(new Class<?>[genericTypeslist.size()]);
}
private boolean _isPrimitive(char c) {
if ((c == 'B') || (c == 'C') || (c == 'D') || (c == 'F') ||
(c == 'I') || (c == 'J') || (c == 'S') || (c == 'V') ||
(c == 'Z')) {
return true;
}
else {
return false;
}
}
private final Class<?>[] _genericTypes;
private final String _name;
private final Class<?> _type;
}