/*
* MicroJIAC - A Lightweight Agent Framework
* This file is part of MicroJIAC CDC-Common.
*
* Copyright (c) 2007-2012 DAI-Labor, Technische Universität Berlin
*
* This library includes software developed at DAI-Labor, Technische
* Universität Berlin (http://www.dai-labor.de)
*
* 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 3 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* $Id$
*/
package de.jiac.micro.internal.util;
import java.util.ArrayList;
import com.github.libxjava.lang.IClassLoader;
/**
* @author Marcel Patzlaff
* @version $Revision$
*/
public final class SignatureUtil {
private final static StringBuffer SIGNATURE_BUFFER= new StringBuffer();
private final static ArrayList SIGNATURE_CLASS_NAMES= new ArrayList();
public final static Class[] getSignatureClasses(IClassLoader classLoader, String methodDescriptor) throws ClassNotFoundException {
synchronized (SIGNATURE_BUFFER) {
try {
SIGNATURE_BUFFER.append(methodDescriptor);
SIGNATURE_BUFFER.delete(0, methodDescriptor.indexOf('(') + 1);
while(SIGNATURE_BUFFER.charAt(0) != ')') {
SIGNATURE_CLASS_NAMES.add(getClassForInternalName(classLoader, SIGNATURE_BUFFER));
}
SIGNATURE_BUFFER.deleteCharAt(0);
SIGNATURE_CLASS_NAMES.add(0, getClassForInternalName(classLoader, SIGNATURE_BUFFER));
Class[] result= new Class[SIGNATURE_CLASS_NAMES.size()];
SIGNATURE_CLASS_NAMES.toArray(result);
return result;
} finally {
SIGNATURE_BUFFER.setLength(0);
SIGNATURE_CLASS_NAMES.clear();
}
}
}
public final static String getMethodDescriptor(Class[] parameterTypes, Class returnType) {
synchronized (SIGNATURE_BUFFER) {
try {
SIGNATURE_BUFFER.append('(');
for(int i= 0; i < parameterTypes.length; ++i) {
getDescriptor(SIGNATURE_BUFFER, parameterTypes[i]);
}
SIGNATURE_BUFFER.append(')');
getDescriptor(SIGNATURE_BUFFER, returnType);
return SIGNATURE_BUFFER.toString();
} finally {
SIGNATURE_BUFFER.setLength(0);
}
}
}
// public final static String getDeclaringClassName(String descriptor) {
// return descriptor.substring(0, descriptor.indexOf('#'));
// }
//
// public final static String getMethodName(String descriptor) {
// return descriptor.substring(descriptor.indexOf('#') + 1, descriptor.indexOf('('));
// }
//
private static void getDescriptor(final StringBuffer buf, final Class c) {
Class d = c;
while (true) {
if (!Object.class.isAssignableFrom(c)) {
char car;
if (d == int.class) {
car = 'I';
} else if (d == void.class) {
car = 'V';
} else if (d == boolean.class) {
car = 'Z';
} else if (d == byte.class) {
car = 'B';
} else if (d == char.class) {
car = 'C';
} else if (d == short.class) {
car = 'S';
} else if (d == double.class) {
car = 'D';
} else if (d == float.class) {
car = 'F';
} else /* if (d == long.class) */{
car = 'J';
}
buf.append(car);
return;
} else {
if (!d.isArray()) {
buf.append('L');
}
String name = d.getName();
int len = name.length();
for (int i = 0; i < len; ++i) {
char car = name.charAt(i);
buf.append(car == '.' ? '/' : car);
}
if(!d.isArray()) {
buf.append(';');
}
return;
}
}
}
private static final Class getClassForInternalName(IClassLoader classLoader, StringBuffer buf) throws ClassNotFoundException {
StringBuffer className= null;
char ch= buf.charAt(0);
buf.deleteCharAt(0);
int index= 0;
boolean keepSeparator= false;
switch(ch) {
case 'V': return void.class;
case 'Z': return boolean.class;
case 'C': return char.class;
case 'B': return byte.class;
case 'S': return short.class;
case 'I': return int.class;
case 'F': return float.class;
case 'J': return long.class;
case 'D': return double.class;
case '[': {
className= new StringBuffer();
className.append(ch);
for(; (ch= buf.charAt(index)) == '['; ++index) {
className.append(ch);
}
className.append(ch);
if(ch != 'L') {
buf.delete(0, index + 1);
return classLoader.loadClass(className.toString());
}
// fall through to L case
keepSeparator= true;
index++;
}
default: {
if(className == null) {
className= new StringBuffer();
}
for(; (ch= buf.charAt(index)) != ';' ; ++index) {
className.append(ch == '/' ? '.' : ch);
}
if(keepSeparator) {
className.append(';');
}
buf.delete(0, index + 1);
return classLoader.loadClass(className.toString());
}
}
}
private SignatureUtil() {}
}