use of org.jboss.weld.annotated.enhanced.MethodSignature in project core by weld.
the class Decorators method checkAbstractMethods.
/**
* Check all abstract methods are declared by the decorated types.
*
* @param type
* @param beanManager
* @param delegateType
* @throws DefinitionException If any of the abstract methods is not declared by the decorated types
*/
public static <T> void checkAbstractMethods(Set<Type> decoratedTypes, EnhancedAnnotatedType<T> type, BeanManagerImpl beanManager) {
if (decoratedTypes == null) {
decoratedTypes = new HashSet<Type>(type.getInterfaceClosure());
decoratedTypes.remove(Serializable.class);
}
Set<MethodSignature> signatures = new HashSet<MethodSignature>();
for (Type decoratedType : decoratedTypes) {
for (EnhancedAnnotatedMethod<?, ?> method : ClassTransformer.instance(beanManager).getEnhancedAnnotatedType(Reflections.getRawType(decoratedType), beanManager.getId()).getEnhancedMethods()) {
signatures.add(method.getSignature());
}
}
for (EnhancedAnnotatedMethod<?, ?> method : type.getEnhancedMethods()) {
if (Reflections.isAbstract(((AnnotatedMethod<?>) method).getJavaMember())) {
MethodSignature methodSignature = method.getSignature();
if (!signatures.contains(methodSignature)) {
throw BeanLogger.LOG.abstractMethodMustMatchDecoratedType(method, Formats.formatAsStackTraceElement(method.getJavaMember()));
}
}
}
}
use of org.jboss.weld.annotated.enhanced.MethodSignature in project core by weld.
the class InterceptedSubclassFactory method addMethodsFromClass.
@Override
protected void addMethodsFromClass(ClassFile proxyClassType, ClassMethod staticConstructor) {
try {
final Set<MethodSignature> finalMethods = new HashSet<MethodSignature>();
final Set<BridgeMethod> processedBridgeMethods = new HashSet<BridgeMethod>();
// Add all methods from the class hierarchy
Class<?> cls = getBeanType();
while (cls != null) {
Set<BridgeMethod> declaredBridgeMethods = new HashSet<BridgeMethod>();
for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))) {
final MethodSignatureImpl methodSignature = new MethodSignatureImpl(method);
if (!Modifier.isFinal(method.getModifiers()) && !method.isBridge() && enhancedMethodSignatures.contains(methodSignature) && !finalMethods.contains(methodSignature) && !bridgeMethodsContainsMethod(processedBridgeMethods, methodSignature, method.getGenericReturnType(), Modifier.isAbstract(method.getModifiers()))) {
try {
final MethodInformation methodInfo = new RuntimeMethodInformation(method);
if (interceptedMethodSignatures.contains(methodSignature)) {
// create delegate-to-super method
createDelegateMethod(proxyClassType, method, methodInfo);
// this method is intercepted
// override a subclass method to delegate to method handler
ClassMethod classMethod = proxyClassType.addMethod(method);
addConstructedGuardToMethodBody(classMethod);
createForwardingMethodBody(classMethod, methodInfo, staticConstructor);
BeanLogger.LOG.addingMethodToProxy(method);
} else {
// this method is not intercepted
// we still need to override and push InterceptionDecorationContext stack to prevent full interception
ClassMethod classMethod = proxyClassType.addMethod(method);
new RunWithinInterceptionDecorationContextGenerator(classMethod, this) {
@Override
void doWork(CodeAttribute b, ClassMethod classMethod) {
if (Modifier.isPrivate(classMethod.getAccessFlags())) {
// Weld cannot use invokespecial to invoke a private method from the superclass
invokePrivateMethodHandler(b, classMethod, methodInfo, staticConstructor);
} else {
// build the bytecode that invokes the super class method directly
b.aload(0);
// create the method invocation
b.loadMethodParameters();
b.invokespecial(methodInfo.getDeclaringClass(), methodInfo.getName(), methodInfo.getDescriptor());
}
// leave the result on top of the stack
}
@Override
void doReturn(CodeAttribute b, ClassMethod method) {
// assumes doWork() result is on top of the stack
b.returnInstruction();
}
}.runStartIfNotOnTop();
}
} 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(new BridgeMethod(methodSignature, method.getGenericReturnType()));
}
}
}
processedBridgeMethods.addAll(declaredBridgeMethods);
cls = cls.getSuperclass();
}
for (Class<?> c : getAdditionalInterfaces()) {
for (Method method : c.getMethods()) {
MethodSignature signature = new MethodSignatureImpl(method);
// For interfaces we do not consider return types when going through processed bridge methods
if (enhancedMethodSignatures.contains(signature) && !bridgeMethodsContainsMethod(processedBridgeMethods, signature, null, Modifier.isAbstract(method.getModifiers()))) {
try {
MethodInformation methodInfo = new RuntimeMethodInformation(method);
if (interceptedMethodSignatures.contains(signature) && Reflections.isDefault(method)) {
createDelegateMethod(proxyClassType, method, methodInfo);
// this method is intercepted
// override a subclass method to delegate to method handler
ClassMethod classMethod = proxyClassType.addMethod(method);
addConstructedGuardToMethodBody(classMethod);
createForwardingMethodBody(classMethod, methodInfo, staticConstructor);
BeanLogger.LOG.addingMethodToProxy(method);
} else {
if (Reflections.isDefault(method)) {
createDelegateMethod(proxyClassType, method, methodInfo);
} else {
final ClassMethod classMethod = proxyClassType.addMethod(method);
createSpecialMethodBody(classMethod, methodInfo, staticConstructor);
BeanLogger.LOG.addingMethodToProxy(method);
}
}
} catch (DuplicateMemberException e) {
}
}
if (method.isBridge()) {
processedBridgeMethods.add(new BridgeMethod(signature, method.getGenericReturnType()));
}
}
}
} catch (Exception e) {
throw new WeldException(e);
}
}
use of org.jboss.weld.annotated.enhanced.MethodSignature 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.annotated.enhanced.MethodSignature in project core by weld.
the class SubclassedComponentInstantiator method createEnhancedSubclass.
protected Class<T> createEnhancedSubclass(EnhancedAnnotatedType<T> type, Bean<?> bean, BeanManagerImpl manager) {
Set<InterceptionModel> models = getInterceptionModelsForType(type, manager, bean);
Set<MethodSignature> enhancedMethodSignatures = new HashSet<MethodSignature>();
Set<MethodSignature> interceptedMethodSignatures = (models == null) ? enhancedMethodSignatures : new HashSet<MethodSignature>();
for (AnnotatedMethod<?> method : Beans.getInterceptableMethods(type)) {
enhancedMethodSignatures.add(MethodSignatureImpl.of(method));
if (models != null) {
for (InterceptionModel model : models) {
if (!model.getInterceptors(InterceptionType.AROUND_INVOKE, method.getJavaMember()).isEmpty()) {
interceptedMethodSignatures.add(MethodSignatureImpl.of(method));
break;
}
}
}
}
Set<Type> types = null;
if (bean == null) {
types = Collections.<Type>singleton(type.getJavaClass());
} else {
types = bean.getTypes();
}
return new InterceptedSubclassFactory<T>(manager.getContextId(), type.getJavaClass(), types, bean, enhancedMethodSignatures, interceptedMethodSignatures).getProxyClass();
}
Aggregations