package org.hotswap.agent.plugin.owb.command; import java.lang.annotation.Annotation; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.annotation.Priority; import javax.enterprise.inject.spi.AnnotatedField; import javax.enterprise.inject.spi.AnnotatedMethod; import javax.enterprise.inject.spi.AnnotatedType; import javax.enterprise.inject.spi.ObserverMethod; import org.apache.webbeans.component.BeanAttributesImpl; import org.apache.webbeans.component.CdiInterceptorBean; import org.apache.webbeans.component.DecoratorBean; import org.apache.webbeans.component.InjectionTargetBean; import org.apache.webbeans.component.ManagedBean; import org.apache.webbeans.component.ProducerFieldBean; import org.apache.webbeans.component.ProducerMethodBean; import org.apache.webbeans.component.creation.BeanAttributesBuilder; import org.apache.webbeans.component.creation.CdiInterceptorBeanBuilder; import org.apache.webbeans.component.creation.DecoratorBeanBuilder; import org.apache.webbeans.component.creation.ManagedBeanBuilder; import org.apache.webbeans.component.creation.ObserverMethodsBuilder; import org.apache.webbeans.component.creation.ProducerFieldBeansBuilder; import org.apache.webbeans.component.creation.ProducerMethodBeansBuilder; import org.apache.webbeans.config.WebBeansContext; import org.apache.webbeans.container.BeanManagerImpl; import org.apache.webbeans.decorator.DecoratorsManager; import org.apache.webbeans.event.ObserverMethodImpl; import org.apache.webbeans.intercept.InterceptorsManager; import org.apache.webbeans.portable.AnnotatedElementFactory; import org.apache.webbeans.portable.events.ProcessBeanImpl; import org.apache.webbeans.portable.events.generics.GProcessManagedBean; import org.apache.webbeans.util.WebBeansUtil; import org.hotswap.agent.logging.AgentLogger; /** * The Class HaBeanDeployer. Based on code from BeanDeployer * * @author Vladimir Dvorak */ public class HaBeanDeployer { private static AgentLogger LOGGER = AgentLogger.getLogger(HaBeanDeployer.class); @SuppressWarnings({ "rawtypes", "unchecked" }) public static void doDefineManagedBean(BeanManagerImpl beanManager, Class<?> beanClass) { WebBeansContext wbc = beanManager.getWebBeansContext(); AnnotatedElementFactory annotatedElementFactory = wbc.getAnnotatedElementFactory(); // Clear AnnotatedElementFactory caches (is it necessary for definition ?) annotatedElementFactory.clear(); // Injection resolver cache must be cleared before / after definition beanManager.getInjectionResolver().clearCaches(); AnnotatedType annotatedType = annotatedElementFactory.newAnnotatedType(beanClass); BeanAttributesImpl attributes = BeanAttributesBuilder.forContext(wbc).newBeanAttibutes(annotatedType).build(); if(wbc.getWebBeansUtil().supportsJavaEeComponentInjections(beanClass)) { //Fires ProcessInjectionTarget wbc.getWebBeansUtil().fireProcessInjectionTargetEventForJavaEeComponents(beanClass).setStarted(); wbc.getWebBeansUtil().inspectDeploymentErrorStack( "There are errors that are added by ProcessInjectionTarget event observers. Look at logs for further details"); //Checks that not contains @Inject InjectionPoint wbc.getAnnotationManager().checkInjectionPointForInjectInjectionPoint(beanClass); } { ManagedBeanBuilder managedBeanCreator = new ManagedBeanBuilder(wbc, annotatedType, attributes); DecoratorsManager decoratorsManager = wbc.getDecoratorsManager(); InterceptorsManager interceptorsManager = wbc.getInterceptorsManager(); if(WebBeansUtil.isDecorator(annotatedType)) { LOGGER.debug("Found Managed Bean Decorator with class name : [{}]", annotatedType.getJavaClass().getName()); DecoratorBeanBuilder dbb = new DecoratorBeanBuilder(wbc, annotatedType, attributes); if (dbb.isDecoratorEnabled()) { dbb.defineDecoratorRules(); DecoratorBean decorator = dbb.getBean(); decoratorsManager.addDecorator(decorator); } } else if(WebBeansUtil.isCdiInterceptor(annotatedType)) { LOGGER.debug("Found Managed Bean Interceptor with class name : [{}]", annotatedType.getJavaClass().getName()); CdiInterceptorBeanBuilder ibb = new CdiInterceptorBeanBuilder(wbc, annotatedType, attributes); if (ibb.isInterceptorEnabled()) { ibb.defineCdiInterceptorRules(); CdiInterceptorBean interceptor = (CdiInterceptorBean) ibb.getBean(); interceptorsManager.addCdiInterceptor(interceptor); } } else { InjectionTargetBean bean = managedBeanCreator.getBean(); if (decoratorsManager.containsCustomDecoratorClass(annotatedType.getJavaClass()) || interceptorsManager.containsCustomInterceptorClass(annotatedType.getJavaClass())) { return; //TODO discuss this case (it was ignored before) } LOGGER.debug("Found Managed Bean with class name : [{}]", annotatedType.getJavaClass().getName()); Set<ObserverMethod<?>> observerMethods; AnnotatedType beanAnnotatedType = bean.getAnnotatedType(); // AnnotatedType defaultAt = webBeansContext.getAnnotatedElementFactory().getAnnotatedType(beanAnnotatedType.getJavaClass()); boolean ignoreProducer = false /*defaultAt != beanAnnotatedType && annotatedTypes.containsKey(defaultAt)*/; if(bean.isEnabled()) { observerMethods = new ObserverMethodsBuilder(wbc, beanAnnotatedType).defineObserverMethods(bean); } else { observerMethods = new HashSet<ObserverMethod<?>>(); } Set<ProducerFieldBean<?>> producerFields = ignoreProducer ? Collections.emptySet() : new ProducerFieldBeansBuilder(wbc, beanAnnotatedType).defineProducerFields(bean); Set<ProducerMethodBean<?>> producerMethods = ignoreProducer ? Collections.emptySet() : new ProducerMethodBeansBuilder(wbc, beanAnnotatedType).defineProducerMethods(bean, producerFields); ManagedBean managedBean = (ManagedBean)bean; Map<ProducerMethodBean<?>,AnnotatedMethod<?>> annotatedMethods = new HashMap<ProducerMethodBean<?>, AnnotatedMethod<?>>(); if (!producerFields.isEmpty() || !producerMethods.isEmpty()) { final Priority priority = annotatedType.getAnnotation(Priority.class); if (priority != null && !wbc.getAlternativesManager() .isAlternative(annotatedType.getJavaClass(), Collections.<Class<? extends Annotation>>emptySet())) { wbc.getAlternativesManager().addPriorityClazzAlternative(annotatedType.getJavaClass(), priority); } } for(ProducerMethodBean<?> producerMethod : producerMethods) { AnnotatedMethod method = wbc.getAnnotatedElementFactory().newAnnotatedMethod(producerMethod.getCreatorMethod(), annotatedType); wbc.getWebBeansUtil().inspectDeploymentErrorStack("There are errors that are added by ProcessProducer event observers for " + "ProducerMethods. Look at logs for further details"); annotatedMethods.put(producerMethod, method); } Map<ProducerFieldBean<?>,AnnotatedField<?>> annotatedFields = new HashMap<ProducerFieldBean<?>, AnnotatedField<?>>(); for(ProducerFieldBean<?> producerField : producerFields) { /* TODO: check if needed in HA webBeansContext.getWebBeansUtil().inspectDeploymentErrorStack("There are errors that are added by ProcessProducer event observers for" + " ProducerFields. Look at logs for further details"); */ annotatedFields.put(producerField, wbc.getAnnotatedElementFactory().newAnnotatedField( producerField.getCreatorField(), wbc.getAnnotatedElementFactory().newAnnotatedType(producerField.getBeanClass()))); } Map<ObserverMethod<?>,AnnotatedMethod<?>> observerMethodsMap = new HashMap<ObserverMethod<?>, AnnotatedMethod<?>>(); for(ObserverMethod<?> observerMethod : observerMethods) { ObserverMethodImpl<?> impl = (ObserverMethodImpl<?>)observerMethod; AnnotatedMethod<?> method = impl.getObserverMethod(); observerMethodsMap.put(observerMethod, method); } //Fires ProcessManagedBean ProcessBeanImpl processBeanEvent = new GProcessManagedBean(managedBean, annotatedType); beanManager.fireEvent(processBeanEvent, true); processBeanEvent.setStarted(); wbc.getWebBeansUtil().inspectDefinitionErrorStack("There are errors that are added by ProcessManagedBean event observers for " + "managed beans. Look at logs for further details"); //Fires ProcessProducerMethod wbc.getWebBeansUtil().fireProcessProducerMethodBeanEvent(annotatedMethods, annotatedType); wbc.getWebBeansUtil().inspectDefinitionErrorStack("There are errors that are added by ProcessProducerMethod event observers for " + "producer method beans. Look at logs for further details"); //Fires ProcessProducerField wbc.getWebBeansUtil().fireProcessProducerFieldBeanEvent(annotatedFields); wbc.getWebBeansUtil().inspectDefinitionErrorStack("There are errors that are added by ProcessProducerField event observers for " + "producer field beans. Look at logs for further details"); //Fire ObservableMethods wbc.getWebBeansUtil().fireProcessObservableMethodBeanEvent(observerMethodsMap); wbc.getWebBeansUtil().inspectDefinitionErrorStack("There are errors that are added by ProcessObserverMethod event observers for " + "observer methods. Look at logs for further details"); if(!wbc.getWebBeansUtil().isAnnotatedTypeDecoratorOrInterceptor(annotatedType)) { beanManager.addBean(bean); for (ProducerMethodBean<?> producerMethod : producerMethods) { // add them one after the other to enable serialization handling et al beanManager.addBean(producerMethod); } for (ProducerFieldBean<?> producerField : producerFields) { // add them one after the other to enable serialization handling et al beanManager.addBean(producerField); } } } } } }