/* * Bean Testing. * * 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 info.novatec.beantest.extension; import info.novatec.beantest.transactions.Transactional; import javax.ejb.EJB; import javax.ejb.MessageDriven; import javax.ejb.Singleton; import javax.ejb.Stateless; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.RequestScoped; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.AnnotatedType; import javax.enterprise.inject.spi.Extension; import javax.enterprise.inject.spi.ProcessAnnotatedType; import javax.enterprise.inject.spi.WithAnnotations; import javax.inject.Inject; import javax.interceptor.Interceptor; import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder; /** * Extension to modify bean meta data. * <p> * This extension adds and changes the bean meta data in order to convert EJB injection points into CDI injection points. * Therefore the extension changes the meta data of Beans annotated with {@link EJB}<br> * It also changes injection points in interceptors. * * @author Carlos Barragan ([email protected]) */ public class BeanTestExtension implements Extension { /** * Replaces the meta data of the {@link ProcessAnnotatedType}. * * <p> * The ProcessAnnotatedType's meta data will be replaced, if the annotated type has one of the following annotations: * <ul> * <li> {@link Stateless} * <li> {@link MessageDriven} * <li> {@link Interceptor} * <li> {@link Singleton} * </ul> * * @param <X> the type of the ProcessAnnotatedType * @param pat the annotated type representing the class being processed */ public <X> void processInjectionTarget(@Observes @WithAnnotations({Stateless.class, MessageDriven.class, Interceptor.class, Singleton.class}) ProcessAnnotatedType<X> pat) { if (pat.getAnnotatedType().isAnnotationPresent(Stateless.class) || pat.getAnnotatedType().isAnnotationPresent(MessageDriven.class)) { modifiyAnnotatedTypeMetadata(pat); } else if (pat.getAnnotatedType().isAnnotationPresent(Interceptor.class)) { processInterceptorDependencies(pat); } else if(pat.getAnnotatedType().isAnnotationPresent(Singleton.class)) { addApplicationScopedAndTransactionalToSingleton(pat); } } /** * Adds {@link Transactional} and {@link ApplicationScoped} to the given annotated type and converts * its EJB injection points into CDI injection points (i.e. it adds the {@link Inject}) * @param <X> the type of the annotated type. * @param pat the process annotated type. */ private <X> void addApplicationScopedAndTransactionalToSingleton(ProcessAnnotatedType<X> pat) { AnnotatedType at = pat.getAnnotatedType(); AnnotatedTypeBuilder<X> builder = new AnnotatedTypeBuilder<X>().readFromType(at); builder.addToClass(AnnotationInstances.APPLICATION_SCOPED).addToClass(AnnotationInstances.TRANSACTIONAL); InjectionHelper.addInjectAnnotation(at, builder); pat.setAnnotatedType(builder.create()); } /** * Adds {@link Transactional} and {@link RequestScoped} to the given annotated type and converts * its EJB injection points into CDI injection points (i.e. it adds the {@link Inject}) * @param <X> the type of the annotated type * @param pat the process annotated type. */ private <X> void modifiyAnnotatedTypeMetadata(ProcessAnnotatedType<X> pat) { AnnotatedType at = pat.getAnnotatedType(); AnnotatedTypeBuilder<X> builder = new AnnotatedTypeBuilder<X>().readFromType(at); builder.addToClass(AnnotationInstances.TRANSACTIONAL).addToClass(AnnotationInstances.REQUEST_SCOPED); InjectionHelper.addInjectAnnotation(at, builder); //Set the wrapper instead the actual annotated type pat.setAnnotatedType(builder.create()); } /** * Adds {@link Inject} annotation to all the dependencies of the interceptor. * * @param <X> * the type of the annotated type * @param pat * the process annotated type. */ private <X> void processInterceptorDependencies(ProcessAnnotatedType<X> pat) { AnnotatedTypeBuilder<X> builder = new AnnotatedTypeBuilder<X>().readFromType(pat.getAnnotatedType()); InjectionHelper.addInjectAnnotation(pat.getAnnotatedType(), builder); pat.setAnnotatedType(builder.create()); } }