Package org.jboss.as.ee.component

Source Code of org.jboss.as.ee.component.ComponentInstallProcessor

/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.ee.component;

import org.jboss.as.ee.naming.ContextNames;
import org.jboss.as.ee.naming.NamespaceSelectorService;
import org.jboss.as.ee.naming.RootContextService;
import org.jboss.as.naming.ManagedReferenceFactory;
import org.jboss.as.naming.NamingStore;
import org.jboss.as.naming.context.NamespaceContextSelector;
import org.jboss.as.naming.service.BinderService;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex;
import org.jboss.invocation.proxy.ProxyFactory;
import org.jboss.modules.Module;
import org.jboss.modules.ModuleClassLoader;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.msc.value.InjectedValue;
import org.jboss.msc.value.Value;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*/
public final class ComponentInstallProcessor implements DeploymentUnitProcessor {

    public void deploy(final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
        final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
        final Module module = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);
        if (module == null) {
            // Nothing to do
            return;
        }
        final EEModuleDescription moduleDescription = deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
        // Iterate through each component, installing it into the container
        for (AbstractComponentDescription description : moduleDescription.getComponentDescriptions()) {
            try {
                deployComponent(phaseContext, description);
            }
            catch (RuntimeException e) {
                throw new DeploymentUnitProcessingException("Failed to install component " + description, e);
            }
        }
    }

    protected void deployComponent(final DeploymentPhaseContext phaseContext, final AbstractComponentDescription description) throws DeploymentUnitProcessingException {

        final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
        final Module module = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);
        final ModuleClassLoader classLoader = module.getClassLoader();
        final EEModuleDescription moduleDescription = deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
        final DeploymentReflectionIndex deploymentReflectionIndex = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.REFLECTION_INDEX);
        final ServiceTarget serviceTarget = phaseContext.getServiceTarget();

        final JndiInjectionPointStore moduleInjectionPointStore = deploymentUnit.getAttachment(Attachments.MODULE_INJECTIONS);
        final JndiInjectionPointStore injectionPointStore;
        if(moduleInjectionPointStore != null) {
            injectionPointStore = new JndiInjectionPointStore(moduleInjectionPointStore);
        } else {
            injectionPointStore = new JndiInjectionPointStore();
        }

        final String className = description.getComponentClassName();
        final Class<?> componentClass;
        try {
            componentClass = Class.forName(className, false, classLoader);
        } catch (ClassNotFoundException e) {
            throw new DeploymentUnitProcessingException("Component class not found", e);
        }
        final String applicationName = description.getApplicationName();
        final String moduleName = description.getModuleName();
        final String componentName = description.getComponentName();
        final ServiceName baseName = deploymentUnit.getServiceName().append("component").append(componentName);

        final AbstractComponentConfiguration configuration = description.createComponentConfiguration(phaseContext, componentClass);
        configuration.setComponentClass(componentClass);

        //create additional injectors
        final List<ServiceName> additionalDependencies = new ArrayList<ServiceName>();
        for (InjectionFactory injectionFactory : moduleDescription.getInjectionFactories()) {
            final ComponentInjector injector = injectionFactory.createInjector(configuration);
            if (injector != null) {
                configuration.addComponentInjector(injector);
                ServiceName injectorServiceName = injector.getServiceName();
                if (injector.getServiceName() != null) {
                    additionalDependencies.add(injectorServiceName);
                }
            }
        }

        final ServiceName createServiceName = baseName.append("CREATE");
        final ServiceName startServiceName = baseName.append("START");
        final ComponentCreateService createService = new ComponentCreateService(configuration);
        final ServiceBuilder<Component> createBuilder = serviceTarget.addService(createServiceName, createService);
        final ComponentStartService startService = new ComponentStartService();
        final ServiceBuilder<Component> startBuilder = serviceTarget.addService(startServiceName, startService);

        // Add all service dependencies
        Map<ServiceName, InjectedValue<Object>> injections = configuration.getDependencyInjections();
        for (Map.Entry<ServiceName, ServiceBuilder.DependencyType> entry : description.getDependencies().entrySet()) {
            createBuilder.addDependency(entry.getValue(), entry.getKey(), injections.get(entry.getKey()));
        }

        final ServiceName appContextServiceName = ContextNames.contextServiceNameOfApplication(applicationName);
        final ServiceName moduleContextServiceName = ContextNames.contextServiceNameOfModule(applicationName, moduleName);
        final ServiceName componentContextServiceName;

        switch (description.getNamingMode()) {
            case CREATE: {
                componentContextServiceName = ContextNames.contextServiceNameOfComponent(applicationName, moduleName, componentName);
                // And, create the context...
                RootContextService contextService = new RootContextService();
                serviceTarget.addService(componentContextServiceName, contextService)
                        .addDependency(createServiceName)
                        .install();
                break;
            }
            case USE_MODULE: {
                componentContextServiceName = moduleContextServiceName;
                break;
            }
            default: {
                componentContextServiceName = null;
                break;
            }
        }

        final NamespaceSelectorService selectorService = new NamespaceSelectorService();
        final ServiceName selectorServiceName = baseName.append("NAMESPACE");
        final ServiceBuilder<NamespaceContextSelector> selectorServiceBuilder = serviceTarget.addService(selectorServiceName, selectorService)
                .addDependency(appContextServiceName, NamingStore.class, selectorService.getApp())
                .addDependency(moduleContextServiceName, NamingStore.class, selectorService.getModule());
        if (componentContextServiceName != null) {
            selectorServiceBuilder.addDependency(componentContextServiceName, NamingStore.class, selectorService.getComp());
        }
        selectorServiceBuilder.install();

        // START depends on CREATE
        startBuilder.addDependency(createServiceName, AbstractComponent.class, startService.getComponentInjector());
        //add dependencies on the injector services
        startBuilder.addDependencies(additionalDependencies);

        // Iterate through each view, creating the services for each
        for (Map.Entry<Class<?>, ProxyFactory<?>> entry : configuration.getProxyFactories().entrySet()) {
            final Class<?> viewClass = entry.getKey();
            final ServiceName serviceName = baseName.append("VIEW").append(viewClass.getName());
            final ProxyFactory<?> proxyFactory = entry.getValue();
            final ViewService viewService = new ViewService(viewClass, proxyFactory);
            serviceTarget.addService(serviceName, viewService)
                    .addDependency(createServiceName, AbstractComponent.class, viewService.getComponentInjector())
                    .install();
            configuration.getViewServices().put(viewClass, serviceName);
        }

        // Iterate through each binding/injection, creating the JNDI binding and wiring dependencies for each
        final List<BindingDescription> bindingDescriptions = description.getMergedBindings();
        for (BindingDescription bindingDescription : bindingDescriptions) {
            addJndiBinding(classLoader, serviceTarget, applicationName, moduleName, componentName, createServiceName, startBuilder, bindingDescription, phaseContext, injectionPointStore);
        }

        // Now iterate the interceptors and their bindings
        final Collection<InterceptorDescription> interceptorClasses = description.getAllInterceptors().values();

        for (InterceptorDescription interceptorDescription : interceptorClasses) {
            String interceptorClassName = interceptorDescription.getInterceptorClassName();
            final Class<?> interceptorClass;
            try {
                interceptorClass = Class.forName(interceptorClassName, false, classLoader);
            } catch (ClassNotFoundException e) {
                throw new DeploymentUnitProcessingException("Component interceptor class not found", e);
            }

            List<ResourceInjection> injectionList = injectionPointStore.applyInjections(interceptorClass, deploymentReflectionIndex);

            configuration.addInterceptorResourceInjection(interceptorClass,injectionList);
        }
        List<ResourceInjection> injectionList = injectionPointStore.applyInjections(componentClass, deploymentReflectionIndex);
        //we want to make sure that all JNDI entries are available when the component is created.
        startBuilder.addDependencies(injectionPointStore.getServiceNames());
        configuration.getResourceInjections().addAll(injectionList);

        createBuilder.install();
        startBuilder.install();
    }

    private static void addJndiBinding(final ModuleClassLoader classLoader, final ServiceTarget serviceTarget, final String applicationName, final String moduleName, final String componentName, final ServiceName createServiceName, final ServiceBuilder<Component> startBuilder, final BindingDescription bindingDescription, final DeploymentPhaseContext phaseContext, final JndiInjectionPointStore injectionPointStore) throws DeploymentUnitProcessingException {
        // Gather information about the dependency
        final String bindingName = bindingDescription.getBindingName();
        final String bindingType = bindingDescription.getBindingType();
        try {
            // Sanity check before we invest a lot of effort
            Class.forName(bindingType, false, classLoader);
        } catch (ClassNotFoundException e) {
            throw new DeploymentUnitProcessingException("Component binding class not found", e);
        }

        // There are four applicable scenarios for an injectable dependency
        // 1. The source is a service, and the resource is bound into JNDI (start->binding->service)
        // 2. The source is a service but the resource is not bound into JNDI (start->service)
        // 3. The source is not a service and the resource is bound into JNDI (start->binding)
        // 4. The source is not a service and the resource is not bound (no dependency)

        Value<ManagedReferenceFactory> resourceValue;

        // Check to see if this entry should actually be bound into JNDI.
        if (bindingName != null) {
            // bind into JNDI
            final String serviceBindingName;

            int idx = bindingName.indexOf('/');
            if (idx == -1) {
                serviceBindingName = bindingName;
            } else {
                serviceBindingName = bindingName.substring(idx + 1);
            }
            final BinderService service = new BinderService(serviceBindingName);
            final ServiceName bindingServiceName = ContextNames.serviceNameOfContext(applicationName, moduleName, componentName, bindingName);
            if (bindingServiceName == null) {
                throw new IllegalArgumentException("Invalid context name '" + bindingName + "' for binding");
            }
            // The service builder for the binding
            ServiceBuilder<ManagedReferenceFactory> sourceServiceBuilder = serviceTarget.addService(bindingServiceName, service);
            // The resource value is determined by the reference source, which may add a dependency on the original value to the binding
            bindingDescription.getReferenceSourceDescription().getResourceValue(bindingDescription, sourceServiceBuilder, phaseContext, service.getManagedObjectInjector());
            resourceValue = sourceServiceBuilder
                    .addDependency(createServiceName)
                    .addDependency(bindingServiceName.getParent(), NamingStore.class, service.getNamingStoreInjector())
                    .install();
            // Start service depends on the binding if the binding is a dependency
            if (bindingDescription.isDependency()) startBuilder.addDependency(bindingServiceName);

            for(final InjectionTargetDescription injectionTarget : bindingDescription.getInjectionTargetDescriptions()) {
                injectionPointStore.addInjectedValue(injectionTarget,resourceValue,bindingServiceName);
            }
        } else {
            // do not bind into JNDI
            // The resource value comes from the reference source, which may add a dependency on the original value to the start service
            final InjectedValue<ManagedReferenceFactory> injectedValue = new InjectedValue<ManagedReferenceFactory>();
            bindingDescription.getReferenceSourceDescription().getResourceValue(bindingDescription, startBuilder, phaseContext, injectedValue);
            resourceValue = injectedValue;
            for(final InjectionTargetDescription injectionTarget : bindingDescription.getInjectionTargetDescriptions()) {
                injectionPointStore.addInjectedValue(injectionTarget,resourceValue,null);
            }
        }
    }

    public void undeploy(final DeploymentUnit context) {
    }
}
TOP

Related Classes of org.jboss.as.ee.component.ComponentInstallProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.