Skip to content
Permalink
Browse files

WELD-1602 Revise WeldDecorator.getDecoratorMethod() implementations

  • Loading branch information...
jharting committed Feb 13, 2014
1 parent 59e4b97 commit 8847acfa389734a48a227b18c64b56388981e991
@@ -18,16 +18,13 @@
package org.jboss.weld.bean;

import java.lang.reflect.Method;
import java.util.Map;

import javax.enterprise.inject.spi.Decorator;

import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.annotated.enhanced.MethodSignature;
import org.jboss.weld.annotated.runtime.InvokableAnnotatedMethod;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.resources.ClassTransformer;
import org.jboss.weld.util.Decorators;
import org.jboss.weld.util.reflection.Reflections;

/**
@@ -40,7 +37,7 @@
private final Decorator<T> delegate;
private final EnhancedAnnotatedType<T> weldClass;

private Map<MethodSignature, InvokableAnnotatedMethod<?>> decoratorMethods;
private final DecoratedMethods decoratedMethods;

public static <T> CustomDecoratorWrapper<T> of(Decorator<T> delegate, BeanManagerImpl beanManager) {
return new CustomDecoratorWrapper<T>(delegate, beanManager);
@@ -49,19 +46,21 @@
private CustomDecoratorWrapper(Decorator<T> delegate, BeanManagerImpl beanManager) {
this.delegate = delegate;
this.weldClass = beanManager.getServices().get(ClassTransformer.class).getEnhancedAnnotatedType(Reflections.<Class<T>>cast(delegate.getBeanClass()), beanManager.getId());
this.decoratorMethods = Decorators.getDecoratorMethods(beanManager, delegate.getDecoratedTypes(), this.weldClass);
this.decoratedMethods = new DecoratedMethods(beanManager, this);
}

@Override
public Decorator<T> delegate() {
return delegate;
}

@Override
public EnhancedAnnotatedType<?> getEnhancedAnnotated() {
return weldClass;
}

@Override
public InvokableAnnotatedMethod<?> getDecoratorMethod(Method method) {
return Decorators.findDecoratorMethod(this, decoratorMethods, method);
return decoratedMethods.getDecoratedMethod(method);
}
}
@@ -23,13 +23,11 @@
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.enterprise.inject.spi.BeanAttributes;

import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.annotated.enhanced.MethodSignature;
import org.jboss.weld.annotated.runtime.InvokableAnnotatedMethod;
import org.jboss.weld.bootstrap.BeanDeployerEnvironment;
import org.jboss.weld.injection.attributes.WeldInjectionPointAttributes;
@@ -52,7 +50,7 @@
return new DecoratorImpl<T>(attributes, clazz, beanManager);
}

private Map<MethodSignature, InvokableAnnotatedMethod<?>> decoratorMethods;
private DecoratedMethods decoratedMethods;
private WeldInjectionPointAttributes<?, ?> delegateInjectionPoint;
private Set<Annotation> delegateBindings;
private Type delegateType;
@@ -77,7 +75,7 @@ protected void initDecoratedTypes() {
decoratedTypes.retainAll(getTypes());
decoratedTypes.remove(Serializable.class);
this.decoratedTypes = SharedObjectCache.instance(beanManager).getSharedSet(decoratedTypes);
this.decoratorMethods = Decorators.getDecoratorMethods(beanManager, decoratedTypes, getEnhancedAnnotated());
this.decoratedMethods = new DecoratedMethods(beanManager, this);
}

protected void initDelegateInjectionPoint() {
@@ -96,14 +94,17 @@ protected void initDelegateType() {
delegateTypes.add(delegateType);
}

@Override
public Set<Annotation> getDelegateQualifiers() {
return delegateBindings;
}

@Override
public Type getDelegateType() {
return delegateType;
}

@Override
public Set<Type> getDecoratedTypes() {
return decoratedTypes;
}
@@ -112,8 +113,9 @@ public Type getDelegateType() {
return delegateInjectionPoint;
}

@Override
public InvokableAnnotatedMethod<?> getDecoratorMethod(Method method) {
return Decorators.findDecoratorMethod(this, decoratorMethods, method);
return decoratedMethods.getDecoratedMethod(method);
}

@Override
@@ -0,0 +1,92 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2014, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.weld.bean;

import java.lang.reflect.Method;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.jboss.weld.annotated.runtime.InvokableAnnotatedMethod;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.util.Decorators;
import org.jboss.weld.util.reflection.Reflections;

/**
* Resolves decorator method for a given business method.
*
* @author Jozef Hartinger
*
*/
class DecoratedMethods {

/*
* We use this marker because ConcurrentMap does not support null values but we want to keep track of
* methods for which there is no decorated method declared by the decorator.
*/
private static final Object NULL_MARKER = new Object();

private final Set<InvokableAnnotatedMethod<?>> decoratedTypeMethods;
private final ConcurrentMap<Method, Object> cache;

DecoratedMethods(BeanManagerImpl manager, WeldDecorator<?> decorator) {
this.decoratedTypeMethods = Decorators.getDecoratorMethods(manager, decorator);
this.cache = new ConcurrentHashMap<Method, Object>();
}

public InvokableAnnotatedMethod<?> getDecoratedMethod(Method method) {
if (!cache.containsKey(method)) {
// this is not atomic and we may end up doing method lookup more than once - which is fine
cache.putIfAbsent(method, findMatchingDecoratedMethod(method));
}
Object value = cache.get(method);
if (value == NULL_MARKER) {
return null;
} else {
return Reflections.cast(value);
}
}

private Object findMatchingDecoratedMethod(Method method) {
for (InvokableAnnotatedMethod<?> decoratedMethod : decoratedTypeMethods) {
if (decoratedMethod.getJavaMember().equals(method)) {
return decoratedMethod;
}
}
for (InvokableAnnotatedMethod<?> decoratedMethod : decoratedTypeMethods) {
if (matches(decoratedMethod, method)) {
return decoratedMethod;
}
}
return NULL_MARKER;
}

private boolean matches(InvokableAnnotatedMethod<?> decoratedMethod, Method candidate) {
if (candidate.getParameterTypes().length != decoratedMethod.getParameters().size()) {
return false;
}
if (!candidate.getName().equals(decoratedMethod.getJavaMember().getName())) {
return false;
}
for (int i = 0; i < candidate.getParameterTypes().length; i++) {
if (!decoratedMethod.getJavaMember().getParameterTypes()[i].isAssignableFrom(candidate.getParameterTypes()[i])) {
return false;
}
}
return true;
}
}
@@ -18,14 +18,10 @@
package org.jboss.weld.util;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.enterprise.context.spi.CreationalContext;
@@ -40,7 +36,6 @@
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMethod;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.annotated.enhanced.MethodSignature;
import org.jboss.weld.annotated.enhanced.jlr.MethodSignatureImpl;
import org.jboss.weld.annotated.runtime.InvokableAnnotatedMethod;
import org.jboss.weld.bean.CustomDecoratorWrapper;
import org.jboss.weld.bean.DecoratorImpl;
@@ -59,6 +54,8 @@
import org.jboss.weld.util.reflection.HierarchyDiscovery;
import org.jboss.weld.util.reflection.Reflections;

import com.google.common.collect.ImmutableSet;

/**
* Helper class for {@link javax.enterprise.inject.spi.Decorator} inspections.
*
@@ -69,34 +66,28 @@
private Decorators() {
}

public static Map<MethodSignature, InvokableAnnotatedMethod<?>> getDecoratorMethods(BeanManagerImpl beanManager, Set<Type> decoratedTypes, EnhancedAnnotatedType<?> decoratorClass) {
List<EnhancedAnnotatedMethod<?, ?>> decoratedMethods = Decorators.getDecoratedMethods(beanManager, decoratedTypes);
Map<MethodSignature, InvokableAnnotatedMethod<?>> decoratorMethods = new HashMap<MethodSignature, InvokableAnnotatedMethod<?>>();
for (EnhancedAnnotatedMethod<?, ?> method : decoratorClass.getEnhancedMethods()) {
MethodSignatureImpl methodSignature = new MethodSignatureImpl(method);
for (EnhancedAnnotatedMethod<?, ?> decoratedMethod : decoratedMethods) {
if (new MethodSignatureImpl(decoratedMethod).equals(methodSignature)) {
decoratorMethods.put(methodSignature, InvokableAnnotatedMethod.of(decoratedMethod.slim()));
}
}
}
return decoratorMethods;
}

public static List<EnhancedAnnotatedMethod<?, ?>> getDecoratedMethods(BeanManagerImpl beanManager, Set<Type> decoratedTypes) {
List<EnhancedAnnotatedMethod<?, ?>> methods = new ArrayList<EnhancedAnnotatedMethod<?, ?>>();
for (Type type : decoratedTypes) {
/**
* Determines the set of {@link InvokableAnnotatedMethod}s representing decorated methods of the specified decorator. A decorated method
* is any method declared by a decorated type which is implemented by the decorator.
*
* @param beanManager the bean manager
* @param decorator the specified decorator
* @return the set of {@link InvokableAnnotatedMethod}s representing decorated methods of the specified decorator
*/
public static Set<InvokableAnnotatedMethod<?>> getDecoratorMethods(BeanManagerImpl beanManager, WeldDecorator<?> decorator) {
ImmutableSet.Builder<InvokableAnnotatedMethod<?>> builder = ImmutableSet.builder();
for (Type type : decorator.getDecoratedTypes()) {
EnhancedAnnotatedType<?> weldClass = getWeldClassOfDecoratedType(beanManager, type);
for (EnhancedAnnotatedMethod<?, ?> method : weldClass.getEnhancedMethods()) {
if (!methods.contains(method)) {
methods.add(method);
for (EnhancedAnnotatedMethod<?, ?> method : weldClass.getDeclaredEnhancedMethods()) {
if (decorator.getEnhancedAnnotated().getEnhancedMethod(method.getSignature()) != null) {
builder.add(InvokableAnnotatedMethod.of(method.slim()));
}
}
}
return methods;
return builder.build();
}

public static EnhancedAnnotatedType<?> getWeldClassOfDecoratedType(BeanManagerImpl beanManager, Type type) {
private static EnhancedAnnotatedType<?> getWeldClassOfDecoratedType(BeanManagerImpl beanManager, Type type) {
if (type instanceof Class<?>) {
return beanManager.createEnhancedAnnotatedType((Class<?>) type);
}
@@ -106,29 +97,6 @@ private Decorators() {
throw new IllegalStateException(BeanLogger.LOG.unableToProcess(type));
}

public static <T> InvokableAnnotatedMethod<?> findDecoratorMethod(WeldDecorator<T> decorator, Map<MethodSignature, InvokableAnnotatedMethod<?>> decoratorMethods, Method method) {
// try the signature first, might be simpler
MethodSignature key = new MethodSignatureImpl(method);
InvokableAnnotatedMethod<?> foundMethod = decoratorMethods.get(key);
if (foundMethod != null) {
return foundMethod;
}
// try all methods
for (InvokableAnnotatedMethod<?> decoratorMethod : decoratorMethods.values()) {
if (method.getParameterTypes().length == decoratorMethod.getParameters().size()
&& method.getName().equals(decoratorMethod.getJavaMember().getName())) {
boolean parameterMatch = true;
for (int i = 0; parameterMatch && i < method.getParameterTypes().length; i++) {
parameterMatch = parameterMatch && decoratorMethod.getJavaMember().getParameterTypes()[i].isAssignableFrom(method.getParameterTypes()[i]);
}
if (parameterMatch) {
return decoratorMethod;
}
}
}
return null;
}

public static WeldInjectionPointAttributes<?, ?> findDelegateInjectionPoint(AnnotatedType<?> type, Iterable<InjectionPoint> injectionPoints) {
WeldInjectionPointAttributes<?, ?> result = null;
for (InjectionPoint injectionPoint : injectionPoints) {

0 comments on commit 8847acf

Please sign in to comment.
You can’t perform that action at this time.