use of org.jboss.weld.util.bytecode.RuntimeMethodInformation in project core by weld.
the class InterceptedProxyFactory method addMethodsFromClass.
@Override
protected void addMethodsFromClass(ClassFile proxyClassType, ClassMethod staticConstructor) {
try {
final Set<MethodSignature> finalMethods = new HashSet<MethodSignature>();
final Set<MethodSignature> processedBridgeMethods = new HashSet<MethodSignature>();
// Add all methods from the class hierarchy
Class<?> cls = getBeanType();
while (cls != null) {
Set<MethodSignature> declaredBridgeMethods = new HashSet<MethodSignature>();
for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))) {
final MethodSignatureImpl methodSignature = new MethodSignatureImpl(method);
if (isMethodAccepted(method, getProxySuperclass()) && enhancedMethodSignatures.contains(methodSignature) && !finalMethods.contains(methodSignature) && !processedBridgeMethods.contains(methodSignature)) {
try {
final MethodInformation methodInfo = new RuntimeMethodInformation(method);
ClassMethod classMethod = proxyClassType.addMethod(method);
if (interceptedMethodSignatures.contains(methodSignature)) {
// this method is intercepted
final CodeAttribute b = classMethod.getCodeAttribute();
b.aload(0);
getMethodHandlerField(classMethod.getClassFile(), b);
// get the Stack
b.invokestatic(InterceptionDecorationContext.class.getName(), "getStack", "()" + DescriptorUtils.makeDescriptor(Stack.class));
b.aload(0);
DEFAULT_METHOD_RESOLVER.getDeclaredMethod(classMethod, methodInfo.getDeclaringClass(), method.getName(), methodInfo.getParameterTypes(), staticConstructor);
b.dup();
// Params
b.iconst(method.getParameterTypes().length);
b.anewarray(JAVA_LANG_OBJECT);
int localVariableCount = 1;
for (int i = 0; i < method.getParameterTypes().length; ++i) {
String typeString = methodInfo.getParameterTypes()[i];
// duplicate the array reference
b.dup();
b.iconst(i);
// load the parameter value
BytecodeUtils.addLoadInstruction(b, typeString, localVariableCount);
// box the parameter if necessary
Boxing.boxIfNessesary(b, typeString);
// and store it in the array
b.aastore();
if (isWide(typeString)) {
localVariableCount = localVariableCount + 2;
} else {
localVariableCount++;
}
}
b.invokeinterface(StackAwareMethodHandler.class.getName(), INVOKE_METHOD_NAME, LJAVA_LANG_OBJECT, InterceptedSubclassFactory.INVOKE_METHOD_PARAMETERS);
if (methodInfo.getReturnType().equals(BytecodeUtils.VOID_CLASS_DESCRIPTOR)) {
b.returnInstruction();
} else if (isPrimitive(methodInfo.getReturnType())) {
Boxing.unbox(b, classMethod.getReturnType());
b.returnInstruction();
} else {
b.checkcast(BytecodeUtils.getName(methodInfo.getReturnType()));
b.returnInstruction();
}
BeanLogger.LOG.addingMethodToProxy(method);
} else {
final CodeAttribute b = classMethod.getCodeAttribute();
b.aload(0);
getMethodHandlerField(classMethod.getClassFile(), b);
b.aload(0);
DEFAULT_METHOD_RESOLVER.getDeclaredMethod(classMethod, methodInfo.getDeclaringClass(), method.getName(), methodInfo.getParameterTypes(), staticConstructor);
b.aconstNull();
b.iconst(method.getParameterTypes().length);
b.anewarray(JAVA_LANG_OBJECT);
int localVariableCount = 1;
for (int i = 0; i < method.getParameterTypes().length; ++i) {
String typeString = methodInfo.getParameterTypes()[i];
// duplicate the array reference
b.dup();
b.iconst(i);
// load the parameter value
BytecodeUtils.addLoadInstruction(b, typeString, localVariableCount);
// box the parameter if necessary
Boxing.boxIfNessesary(b, typeString);
// and store it in the array
b.aastore();
if (isWide(typeString)) {
localVariableCount = localVariableCount + 2;
} else {
localVariableCount++;
}
}
b.invokeinterface(MethodHandler.class.getName(), INVOKE_METHOD_NAME, LJAVA_LANG_OBJECT, new String[] { LJAVA_LANG_OBJECT, LJAVA_LANG_REFLECT_METHOD, LJAVA_LANG_REFLECT_METHOD, "[" + LJAVA_LANG_OBJECT });
if (methodInfo.getReturnType().equals(BytecodeUtils.VOID_CLASS_DESCRIPTOR)) {
b.returnInstruction();
} else if (isPrimitive(methodInfo.getReturnType())) {
Boxing.unbox(b, classMethod.getReturnType());
b.returnInstruction();
} else {
b.checkcast(BytecodeUtils.getName(methodInfo.getReturnType()));
b.returnInstruction();
}
}
} catch (DuplicateMemberException e) {
// do nothing. This will happen if superclass methods have
// been overridden
}
} else {
if (Modifier.isFinal(method.getModifiers())) {
finalMethods.add(methodSignature);
}
if (method.isBridge()) {
declaredBridgeMethods.add(methodSignature);
}
}
}
processedBridgeMethods.addAll(declaredBridgeMethods);
cls = cls.getSuperclass();
}
} catch (Exception e) {
throw new WeldException(e);
}
}
use of org.jboss.weld.util.bytecode.RuntimeMethodInformation in project core by weld.
the class InterceptedSubclassFactory method addSpecialMethods.
/**
* Adds methods requiring special implementations rather than just
* delegation.
*
* @param proxyClassType the Javassist class description for the proxy type
*/
protected void addSpecialMethods(ClassFile proxyClassType, ClassMethod staticConstructor) {
try {
// Add special methods for interceptors
for (Method method : LifecycleMixin.class.getMethods()) {
BeanLogger.LOG.addingMethodToProxy(method);
MethodInformation methodInfo = new RuntimeMethodInformation(method);
createInterceptorBody(proxyClassType.addMethod(method), methodInfo, false, staticConstructor);
}
Method getInstanceMethod = TargetInstanceProxy.class.getMethod("getTargetInstance");
Method getInstanceClassMethod = TargetInstanceProxy.class.getMethod("getTargetClass");
generateGetTargetInstanceBody(proxyClassType.addMethod(getInstanceMethod));
generateGetTargetClassBody(proxyClassType.addMethod(getInstanceClassMethod));
Method setMethodHandlerMethod = ProxyObject.class.getMethod("setHandler", MethodHandler.class);
generateSetMethodHandlerBody(proxyClassType.addMethod(setMethodHandlerMethod));
Method getMethodHandlerMethod = ProxyObject.class.getMethod("getHandler");
generateGetMethodHandlerBody(proxyClassType.addMethod(getMethodHandlerMethod));
} catch (Exception e) {
throw new WeldException(e);
}
}
use of org.jboss.weld.util.bytecode.RuntimeMethodInformation in project core by weld.
the class ProxyFactory method addSpecialMethods.
/**
* Adds methods requiring special implementations rather than just
* delegation.
*
* @param proxyClassType the Javassist class description for the proxy type
*/
protected void addSpecialMethods(ClassFile proxyClassType, ClassMethod staticConstructor) {
try {
// Add special methods for interceptors
for (Method method : LifecycleMixin.class.getMethods()) {
BeanLogger.LOG.addingMethodToProxy(method);
MethodInformation methodInfo = new RuntimeMethodInformation(method);
final ClassMethod classMethod = proxyClassType.addMethod(method);
createInterceptorBody(classMethod, methodInfo, staticConstructor);
}
Method getInstanceMethod = TargetInstanceProxy.class.getMethod("getTargetInstance");
Method getInstanceClassMethod = TargetInstanceProxy.class.getMethod("getTargetClass");
MethodInformation getInstanceMethodInfo = new RuntimeMethodInformation(getInstanceMethod);
createInterceptorBody(proxyClassType.addMethod(getInstanceMethod), getInstanceMethodInfo, staticConstructor);
MethodInformation getInstanceClassMethodInfo = new RuntimeMethodInformation(getInstanceClassMethod);
createInterceptorBody(proxyClassType.addMethod(getInstanceClassMethod), getInstanceClassMethodInfo, staticConstructor);
Method setMethodHandlerMethod = ProxyObject.class.getMethod("setHandler", MethodHandler.class);
generateSetMethodHandlerBody(proxyClassType.addMethod(setMethodHandlerMethod));
Method getMethodHandlerMethod = ProxyObject.class.getMethod("getHandler");
generateGetMethodHandlerBody(proxyClassType.addMethod(getMethodHandlerMethod));
} catch (Exception e) {
throw new WeldException(e);
}
}
Aggregations