Package org.jboss.as.service

Source Code of org.jboss.as.service.ParsedServiceDeploymentProcessor

/*
* JBoss, Home of Professional Open Source.
* Copyright 2010, 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.service;

import static org.jboss.msc.value.Values.cached;

import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.jboss.as.server.deployment.Attachments;
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.ClassReflectionIndex;
import org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex;
import org.jboss.as.service.descriptor.JBossServiceAttributeConfig;
import org.jboss.as.service.descriptor.JBossServiceAttributeConfig.Inject;
import org.jboss.as.service.descriptor.JBossServiceAttributeConfig.ValueFactory;
import org.jboss.as.service.descriptor.JBossServiceAttributeConfig.ValueFactoryParameter;
import org.jboss.as.service.descriptor.JBossServiceConfig;
import org.jboss.as.service.descriptor.JBossServiceConstructorConfig;
import org.jboss.as.service.descriptor.JBossServiceConstructorConfig.Argument;
import org.jboss.as.service.descriptor.JBossServiceDependencyConfig;
import org.jboss.as.service.descriptor.JBossServiceXmlDescriptor;
import org.jboss.modules.Module;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.inject.MethodInjector;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.msc.value.ImmediateValue;
import org.jboss.msc.value.MethodValue;
import org.jboss.msc.value.Value;
import org.jboss.msc.value.Values;

/**
* DeploymentUnit processor responsible for taking JBossServiceXmlDescriptor configuration and creating the
* corresponding services.
*
* @author John E. Bailey
* @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
*/
public class ParsedServiceDeploymentProcessor implements DeploymentUnitProcessor {

    /**
     * Process a deployment for JbossService configuration.  Will install a {@code JBossService} for each configured service.
     *
     * @param phaseContext the deployment unit context
     * @throws DeploymentUnitProcessingException
     */
    public void deploy(final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
        final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
        final JBossServiceXmlDescriptor serviceXmlDescriptor = deploymentUnit.getAttachment(JBossServiceXmlDescriptor.ATTACHMENT_KEY);
        if (serviceXmlDescriptor == null) {
            // Skip deployments without a service xml descriptor
            return;
        }

        // assert module
        final Module module = deploymentUnit.getAttachment(Attachments.MODULE);
        if (module == null)
            throw SarMessages.MESSAGES.failedToGetAttachment("module", deploymentUnit);

        // assert reflection index
        final DeploymentReflectionIndex reflectionIndex = deploymentUnit.getAttachment(Attachments.REFLECTION_INDEX);
        if (reflectionIndex == null)
            throw SarMessages.MESSAGES.failedToGetAttachment("reflection index", deploymentUnit);

        // install services
        final ClassLoader classLoader = module.getClassLoader();
        final List<JBossServiceConfig> serviceConfigs = serviceXmlDescriptor.getServiceConfigs();
        final ServiceTarget target = phaseContext.getServiceTarget();
        for (final JBossServiceConfig serviceConfig : serviceConfigs) {
            addServices(target, serviceConfig, classLoader, reflectionIndex);
        }
    }

    public void undeploy(final DeploymentUnit context) {
    }

    private void addServices(final ServiceTarget target, final JBossServiceConfig mBeanConfig, final ClassLoader classLoader, final DeploymentReflectionIndex index) throws DeploymentUnitProcessingException {
        final String mBeanClassName = mBeanConfig.getCode();
        final List<ClassReflectionIndex<?>> mBeanClassHierarchy = ReflectionUtils.getClassHierarchy(mBeanClassName, index, classLoader);
        final Object mBeanInstance = newInstance(mBeanConfig, mBeanClassHierarchy, classLoader);
        final String mBeanName = mBeanConfig.getName();
        final MBeanServices mBeanServices = new MBeanServices(mBeanName, mBeanInstance, mBeanClassHierarchy, target);

        final JBossServiceDependencyConfig[] dependencyConfigs = mBeanConfig.getDependencyConfigs();
        if (dependencyConfigs != null) {
            final Service<Object> createDestroyService = mBeanServices.getCreateDestroyService();
            for (final JBossServiceDependencyConfig dependencyConfig : dependencyConfigs) {
                final Injector<Object> injector = getInjector(dependencyConfig, mBeanClassHierarchy, createDestroyService);
                mBeanServices.addDependency(dependencyConfig.getDependencyName(), injector);
            }
        }

        final JBossServiceAttributeConfig[] attributeConfigs = mBeanConfig.getAttributeConfigs();
        if (attributeConfigs != null) {
            final Service<Object> createDestroyService = mBeanServices.getCreateDestroyService();
            for (final JBossServiceAttributeConfig attributeConfig : attributeConfigs) {
                final String propertyName = attributeConfig.getName();
                final Inject injectConfig = attributeConfig.getInject();
                final ValueFactory valueFactoryConfig = attributeConfig.getValueFactory();

                if (injectConfig != null) {
                    final Value<?> value = getValue(injectConfig, mBeanClassHierarchy);
                    final Injector<Object> injector = getPropertyInjector(propertyName, mBeanClassHierarchy, createDestroyService, value);
                    mBeanServices.addDependency(injectConfig.getBeanName(), injector);
                } else if (valueFactoryConfig != null) {
                    final Value<?> value = getValue(valueFactoryConfig, mBeanClassHierarchy, classLoader);
                    final Injector<Object> injector = getPropertyInjector(propertyName, mBeanClassHierarchy, createDestroyService, value);
                    mBeanServices.addDependency(valueFactoryConfig.getBeanName(), injector);
                } else {
                    final Value<?> value = getValue(attributeConfig, mBeanClassHierarchy);
                    final Injector<Object> injector = getPropertyInjector(propertyName, mBeanClassHierarchy, createDestroyService, Values.injectedValue());
                    mBeanServices.addInjectionValue(injector, value);
                }
            }
        }

        // register all mBean related services
        mBeanServices.install();
    }

    private static Injector<Object> getInjector(final JBossServiceDependencyConfig dependencyConfig, final List<ClassReflectionIndex<?>> mBeanClassHierarchy, final Service<Object> service) {
        final String attrName = dependencyConfig.getOptionalAttributeName();
        return attrName != null ? getPropertyInjector(attrName, mBeanClassHierarchy, service, Values.injectedValue()) : NullInjector.getInstance();
    }

    private static Value<?> getValue(final Inject injectConfig, final List<ClassReflectionIndex<?>> mBeanClassHierarchy) {
        final String propertyName = injectConfig.getPropertyName();
        Value<?> valueToInject = Values.injectedValue();
        if (propertyName != null) {
            final Method getter = ReflectionUtils.getGetter(mBeanClassHierarchy, propertyName);
            final Value<Method> getterValue = new ImmediateValue<Method>(getter);
            valueToInject = cached(new MethodValue<Object>(getterValue, valueToInject, Values.<Object>emptyList()));
        }
        return valueToInject;
    }

    private static Value<?> getValue(final ValueFactory valueFactory, final List<ClassReflectionIndex<?>> mBeanClassHierarchy, final ClassLoader classLoader) throws DeploymentUnitProcessingException {
        final String methodName = valueFactory.getMethodName();
        final ValueFactoryParameter[] parameters = valueFactory.getParameters();
        final List<Class<?>> paramTypes = new ArrayList<Class<?>>(parameters.length);
        final List<Value<?>> paramValues = new ArrayList<Value<?>>(parameters.length);
        for (ValueFactoryParameter parameter : parameters) {
            final Class<?> attributeTypeValue = ReflectionUtils.getClass(parameter.getType(), classLoader);
            paramTypes.add(attributeTypeValue);
            paramValues.add(new ImmediateValue<Object>(newValue(attributeTypeValue, parameter.getValue())));
        }
        final Value<Method> methodValue = new ImmediateValue<Method>(ReflectionUtils.getMethod(mBeanClassHierarchy, methodName, paramTypes.toArray(new Class<?>[0]), true));
        return cached(new MethodValue<Object>(methodValue, Values.injectedValue(), paramValues));
    }

    private static Value<?> getValue(final JBossServiceAttributeConfig attributeConfig, final List<ClassReflectionIndex<?>> mBeanClassHierarchy) {
        final String attributeName = attributeConfig.getName();
        final Method setterMethod = ReflectionUtils.getSetter(mBeanClassHierarchy, attributeName);
        final Class<?> setterType = setterMethod.getParameterTypes()[0];

        return new ImmediateValue<Object>(newValue(setterType, attributeConfig.getValue()));
    }

    private static Object newInstance(final JBossServiceConfig serviceConfig, final List<ClassReflectionIndex<?>> mBeanClassHierarchy, final ClassLoader classLoader) throws DeploymentUnitProcessingException {
        final JBossServiceConstructorConfig constructorConfig = serviceConfig.getConstructorConfig();
        final int paramCount = constructorConfig != null ? constructorConfig.getArguments().length : 0;
        final Class<?>[] types = new Class<?>[paramCount];
        final Object[] params = new Object[paramCount];

        if (constructorConfig != null) {
            final Argument[] arguments = constructorConfig.getArguments();
            for (int i = 0; i < paramCount; i++) {
                final Argument argument = arguments[i];
                types[i] = ReflectionUtils.getClass(argument.getType(), classLoader);
                params[i] = newValue(ReflectionUtils.getClass(argument.getType(), classLoader), argument.getValue());
            }
        }

        final Constructor<?> constructor = mBeanClassHierarchy.get(0).getConstructor(types);
        final Object mBeanInstance = ReflectionUtils.newInstance(constructor, params);

        return mBeanInstance;
    }

    private static Injector<Object> getPropertyInjector(final String propertyName, final List<ClassReflectionIndex<?>> mBeanClassHierarchy, final Service<?> service, final Value<?> value) {
        final Method setterMethod = ReflectionUtils.getSetter(mBeanClassHierarchy, propertyName);
        return new MethodInjector<Object>(setterMethod, service, Values.nullValue(), Collections.singletonList(value));
    }

    private static Object newValue(final Class<?> type, final String value) {
        final PropertyEditor editor = PropertyEditorManager.findEditor(type);
        if (editor == null) {
            SarLogger.DEPLOYMENT_SERVICE_LOGGER.propertyNotFound(type);
            return null;
        }
        editor.setAsText(value);

        return editor.getValue();
    }

}
TOP

Related Classes of org.jboss.as.service.ParsedServiceDeploymentProcessor

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.