Package org.rioproject.impl.servicebean

Source Code of org.rioproject.impl.servicebean.DefaultServiceBeanFactory

/*
* Copyright to the original author or authors.
*
* 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 org.rioproject.impl.servicebean;

import com.sun.jini.start.LifeCycle;
import com.sun.jini.start.ServiceProxyAccessor;
import net.jini.export.ProxyAccessor;
import org.rioproject.impl.bean.BeanFactory;
import org.rioproject.impl.config.ConfigHelper;
import org.rioproject.servicebean.ServiceBean;
import org.rioproject.servicebean.ServiceBeanContext;
import org.rioproject.servicebean.ServiceBeanFactory;
import org.rioproject.impl.container.ServiceBeanLoader;
import org.rioproject.deploy.ServiceBeanInstantiationException;
import org.rioproject.opstring.ClassBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
* The DefaultServiceBeanFactory will load and create a ServiceBean.
*
* @author Dennis Reedy
*/
public class DefaultServiceBeanFactory implements ServiceBeanFactory {
    /** Component name logging */
    static String COMPONENT = "org.rioproject.impl.servicebean";
    /** A Logger */
    static final Logger logger = LoggerFactory.getLogger(COMPONENT);
    /** Constructor types for a JSK service */
    private static final Class[] activationTypes = {String[].class,
                                                    LifeCycle.class};
    /** ServiceBean start method type */
    private static final Class[] startType = {ServiceBeanContext.class};

    /* (non-Javadoc)
     * @see org.rioproject.cybernode.ServiceBeanFactory#create(org.rioproject.core.servicebean.ServiceBeanContext)
     */
    public Created create(ServiceBeanContext context) throws ServiceBeanInstantiationException {

        final Thread currentThread = Thread.currentThread();
        final ClassLoader jsbCL = currentThread.getContextClassLoader();
        Created created;
        try {
            ClassBundle jsbBundle = context.getServiceElement().getComponentBundle();
            logger.trace("Loading class [{}], using ClassLoader: {}", jsbBundle.getClassName(), jsbCL.toString());
            Class<?> implClass = jsbCL.loadClass(jsbBundle.getClassName());
            if(useActivationConstructor(implClass) && !isServiceBean(implClass)) {
                Constructor constructor = implClass.getDeclaredConstructor(activationTypes);
                logger.trace("Obtained implementation constructor: {}", constructor);
                constructor.setAccessible(true);
                LifeCycle lifeCycle = (LifeCycle)context.getServiceBeanManager().getDiscardManager();
                String[] args = ConfigHelper.getConfigArgs(context.getServiceElement());
                Object impl = constructor.newInstance(args, lifeCycle);
                Object proxy;
                logger.trace("Obtained implementation instance: {}", impl);
                if(impl instanceof ServiceProxyAccessor) {
                    proxy = ((ServiceProxyAccessor)impl).getServiceProxy();
                } else if(impl instanceof ProxyAccessor) {
                    proxy = ((ProxyAccessor)impl).getProxy();
                } else {
                    proxy = null; // just for insurance
                }
                created = new Created(impl, proxy);

            } else {
                if(isServiceBean(implClass)) {
                    logger.trace("Activating as ServiceBean");
                    Constructor constructor = implClass.getConstructor((Class[])null);
                    logger.trace("Obtained implementation constructor: {}", constructor);
                    Object impl = constructor.newInstance((Object[])null);
                    ServiceBean instance = (ServiceBean)impl;
                    logger.trace("Obtained implementation instance: {}", instance);
                    Object proxy = instance.start(context);
                    created = new Created(impl, proxy);
                } else {
                    BeanFactory beanFactory = new BeanFactory();
                    created = beanFactory.create(context);
                }
            }

        } catch(Throwable t) {
            logger.warn("Could not create service", t);
            ServiceBeanLoader.unload(jsbCL, context.getServiceElement());
            if(t instanceof ServiceBeanInstantiationException)
                throw (ServiceBeanInstantiationException)t;
            /* Get the cause if we have an InvocationTargetException, it will allow the thrown exception
             * to have a more meaningful cause. */
             if(t instanceof InvocationTargetException) {
                 t = t.getCause()==null? ((InvocationTargetException)t).getTargetException(): t.getCause();
            }
            throw new ServiceBeanInstantiationException("Service Instantiation Exception", t, true);
        }
        return created;
    }

    /*
     * Determine if a class has a declared constructor matching that required by
     * an activation constructor
     */
    static boolean useActivationConstructor(Class<?> clazz) {
        try {
            clazz.getDeclaredConstructor(activationTypes);
            return (true);
        } catch(NoSuchMethodException e) {
            return (false);
        }
    }

    /*
     * Determine if a class has method signatures as those found in the
     * ServiceBean
     */
    static boolean isServiceBean(Class<?> clazz) {
        try {
            clazz.getMethod("start", startType);
            return (true);
        } catch(NoSuchMethodException e) {
            return (false);
        }
    }
}
TOP

Related Classes of org.rioproject.impl.servicebean.DefaultServiceBeanFactory

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.