Package org.jboss.as.pojo.service

Source Code of org.jboss.as.pojo.service.AbstractPojoPhase

/*
* 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.pojo.service;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.jboss.as.pojo.BeanState;
import org.jboss.as.pojo.PojoLogger;
import org.jboss.as.pojo.PojoMessages;
import org.jboss.as.pojo.descriptor.BeanMetaDataConfig;
import org.jboss.as.pojo.descriptor.CallbackConfig;
import org.jboss.as.pojo.descriptor.ConfigVisitor;
import org.jboss.as.pojo.descriptor.DefaultConfigVisitor;
import org.jboss.as.pojo.descriptor.InstallConfig;
import org.jboss.as.pojo.descriptor.ValueConfig;
import org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex;
import org.jboss.logging.Logger;
import org.jboss.modules.Module;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceRegistry;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.ImmediateValue;
import org.jboss.msc.value.Value;

/**
* Abstract pojo phase; it handles install/uninstall
*
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
*/
public abstract class AbstractPojoPhase implements Service<Object> {
    protected final Logger log = Logger.getLogger(getClass());

    private Module module;
    private BeanMetaDataConfig beanConfig;
    private DeploymentReflectionIndex index;
    private BeanInfo beanInfo;
    private Object bean;

    protected abstract BeanState getLifecycleState();

    protected abstract AbstractPojoPhase createNextPhase();

    public void start(StartContext context) throws StartException {
        if (module != null) {
            final ClassLoader previous = SecurityActions.getContextClassLoader();
            SecurityActions.setContextClassLoader(module.getClassLoader());
            try {
                startInternal(context);
            } finally {
                SecurityActions.setContextClassLoader(previous);
            }
        } else {
            startInternal(context);
        }
    }

    protected void startInternal(StartContext context) throws StartException {
        try {
            executeInstalls();

            // only after describe do we have a bean
            if (getLifecycleState().isAfter(BeanState.DESCRIBED)) {
                addCallbacks(true);
                addCallbacks(false);

                ServiceRegistry registry = context.getController().getServiceContainer();
                InstancesService.addInstance(registry, context.getChildTarget(), getLifecycleState(), getBean());
            }

            final AbstractPojoPhase nextPhase = createNextPhase(); // do we have a next phase
            if (nextPhase != null) {
                final BeanState state = getLifecycleState();
                final BeanState next = state.next();
                final BeanMetaDataConfig beanConfig = getBeanConfig();
                final ServiceName name = BeanMetaDataConfig.toBeanName(beanConfig.getName(), next);
                final ServiceTarget serviceTarget = context.getChildTarget();
                final ServiceBuilder serviceBuilder = serviceTarget.addService(name, nextPhase);
                registerAliases(serviceBuilder, next);
                final ConfigVisitor visitor = new DefaultConfigVisitor(serviceBuilder, state, getModule(), getIndex(), getBeanInfo());
                beanConfig.visit(visitor);
                nextPhase.setModule(getModule());
                nextPhase.setBeanConfig(getBeanConfig());
                nextPhase.setIndex(getIndex());
                nextPhase.setBeanInfo(getBeanInfo());
                nextPhase.setBean(getBean());
                serviceBuilder.install();
            }
        } catch (Throwable t) {
            throw new StartException(t);
        }
    }

    protected void registerAliases(ServiceBuilder serviceBuilder, BeanState next) {
        final Set<String> aliases = beanConfig.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                ServiceName asn = BeanMetaDataConfig.toBeanName(alias, next);
                serviceBuilder.addAliases(asn);
            }
        }
    }

    @Override
    public Object getValue() throws IllegalStateException, IllegalArgumentException {
        return getBean();
    }

    public void stop(StopContext context) {
        if (module != null) {
            final ClassLoader previous = SecurityActions.getContextClassLoader();
            SecurityActions.setContextClassLoader(module.getClassLoader());
            try {
                stopInternal(context);
            } finally {
                SecurityActions.setContextClassLoader(previous);
            }
        } else {
            stopInternal(context);
        }
    }

    protected void stopInternal(StopContext context) {
        if (getLifecycleState().isAfter(BeanState.DESCRIBED)) {
            InstancesService.removeInstance(context.getController().getServiceContainer(), getLifecycleState(), getBean());

            removeCallbacks(true);
            removeCallbacks(false);
        }
        executeUninstalls();
    }

    private List<Joinpoint> getInstalls() {
        List<InstallConfig> installs = getBeanConfig().getInstalls();
        return (installs != null) ? toJoinpoints(installs) : Collections.<Joinpoint>emptyList();
    }

    private List<Joinpoint> getUninstalls() {
        List<InstallConfig> uninstalls = getBeanConfig().getUninstalls();
        return (uninstalls != null) ? toJoinpoints(uninstalls) : Collections.<Joinpoint>emptyList();
    }

    private List<Joinpoint> toJoinpoints(List<InstallConfig> installs) {
        List<Joinpoint> joinpoints = new ArrayList<Joinpoint>();
        for (InstallConfig ic : installs) {
            if (ic.getWhenRequired() == getLifecycleState())
                joinpoints.add(createJoinpoint(ic));
        }
        return joinpoints;
    }

    protected Joinpoint createJoinpoint(InstallConfig config) {
        String methodName = config.getMethodName();
        if (methodName == null)
            throw PojoMessages.MESSAGES.nullMethodName();

        ValueConfig[] parameters = config.getParameters();
        String[] types = Configurator.getTypes(parameters);
        String dependency = config.getDependency();
        Value<Object> target = (dependency != null) ? config.getBean() : new ImmediateValue<Object>(getBean());
        BeanInfo beanInfo = (dependency != null) ? config.getBeanInfo().getValue() : getBeanInfo();
        Method method = beanInfo.findMethod(methodName, types);
        MethodJoinpoint joinpoint = new MethodJoinpoint(method);
        joinpoint.setTarget(target);
        joinpoint.setParameters(parameters);
        return joinpoint;
    }

    protected void executeInstalls() throws StartException {
        List<Joinpoint> installs = getInstalls();
        if (installs.isEmpty())
            return;

        int i = 0;
        try {
            for (i = 0; i < installs.size(); i++)
                installs.get(i).dispatch();
        } catch (Throwable t) {
            considerUninstalls(getUninstalls(), i);
            throw new StartException(t);
        }
    }

    /**
     * Consider the uninstalls.
     * <p/>
     * This method is here to be able to override
     * the behavior after installs failed.
     * e.g. perhaps only running uninstalls from the index.
     * <p/>
     * By default we run all uninstalls in the case
     * at least one install failed.
     *
     * @param uninstalls the uninstalls
     * @param index      current installs index
     */
    protected void considerUninstalls(List<Joinpoint> uninstalls, int index) {
        if (uninstalls == null)
            return;

        for (int j = Math.min(index, uninstalls.size() - 1); j >= 0; j--) {
            try {
                uninstalls.get(j).dispatch();
            } catch (Throwable t) {
                PojoLogger.ROOT_LOGGER.ignoreUninstallError(uninstalls.get(j), t);
            }
        }
    }

    protected void executeUninstalls() {
        considerUninstalls(getUninstalls(), Integer.MAX_VALUE);
    }

    protected void addCallbacks(boolean install) {
        List<CallbackConfig> configs = (install ? getBeanConfig().getIncallbacks() : getBeanConfig().getUncallbacks());
        if (configs != null) {
            for (CallbackConfig cc : configs) {
                if (cc.getWhenRequired() == getLifecycleState()) {
                    Callback callback = new Callback(getBeanInfo(), getBean(), cc);
                    if (install)
                        InstancesService.addIncallback(callback);
                    else
                        InstancesService.addUncallback(callback);
                }
            }
        }
    }

    protected void removeCallbacks(boolean install) {
        List<CallbackConfig> configs = (install ? getBeanConfig().getIncallbacks() : getBeanConfig().getUncallbacks());
        if (configs != null) {
            for (CallbackConfig cc : configs) {
                if (cc.getWhenRequired() == getLifecycleState()) {
                    Callback callback = new Callback(getBeanInfo(), getBean(), cc);
                    if (install)
                        InstancesService.removeIncallback(callback);
                    else
                        InstancesService.removeUncallback(callback);
                }
            }
        }
    }

    protected Module getModule() {
        return module;
    }

    protected void setModule(Module module) {
        this.module = module;
    }

    protected BeanMetaDataConfig getBeanConfig() {
        return beanConfig;
    }

    protected DeploymentReflectionIndex getIndex() {
        return index;
    }

    protected void setBeanConfig(BeanMetaDataConfig beanConfig) {
        this.beanConfig = beanConfig;
    }

    protected void setIndex(DeploymentReflectionIndex index) {
        this.index = index;
    }

    protected BeanInfo getBeanInfo() {
        return beanInfo;
    }

    protected void setBeanInfo(BeanInfo beanInfo) {
        this.beanInfo = beanInfo;
    }

    protected Object getBean() {
        return bean;
    }

    protected void setBean(Object bean) {
        this.bean = bean;
    }
}
TOP

Related Classes of org.jboss.as.pojo.service.AbstractPojoPhase

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.