All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.petals.microkernel.api.server.FractalHelper Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
/**
 * Copyright (c) 2007-2012 EBM WebSourcing, 2012-2016 Linagora
 * 
 * This program/library 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 program/library 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 program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.microkernel.api.server;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.ContentController;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalContentException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.api.control.LifeCycleController;
import org.objectweb.fractal.api.control.NameController;
import org.objectweb.fractal.api.control.SuperController;
import org.objectweb.fractal.api.factory.Factory;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.factory.InstantiationException;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.fractal.fraclet.annotations.Interface;
import org.objectweb.fractal.fraclet.annotations.Requires;
import org.objectweb.fractal.julia.factory.ChainedInstantiationException;
import org.objectweb.fractal.julia.type.BasicInterfaceType;
import org.objectweb.fractal.juliac.helper.InterfaceTypeHelper;
import org.objectweb.fractal.juliac.runtime.Juliac;
import org.objectweb.fractal.util.Fractal;
import org.ow2.petals.basisapi.exception.PetalsException;

import com.ebmwebsourcing.easycommons.lang.UncheckedException;
import com.ebmwebsourcing.easycommons.log.LoggingUtil;

/**
 * This class helps fractal management for Petals.
 * @author Adrien Louis - EBM WebSourcing
 * @author Roland Naudin - EBM WebSourcing
 */
public class FractalHelper {

    /**
     * Fractal Petals names.
     */
    public static final String PETALS_COMPOSITE = "Petals";

    /**
     * The configuration service component name.
     */
    public static final String CONFIGURATION_COMPONENT = "ConfigurationServiceImpl";

    /**
     * The Communication component name.
     */
    public static final String COMMUNICATION_COMPOSITE = "Communication";

    /**
     * The topology service component name.
     */
    public static final String TOPOLOGY_COMPONENT = "TopologyServiceImpl";

    /**
     * The JNDI agent service component name.
     */
    public static final String JNDIAGENT_COMPONENT = "JNDIAgentServiceImpl";

    /**
     * The Jndi service component name.
     */
    public static final String JNDI_COMPONENT = "JNDIServiceImpl";

    /**
     * The JMX service component name.
     */
    public static final String JMX_COMPONENT = "JMXServiceImpl";

    /**
     * The System component name.
     */
    public static final String SYSTEM_COMPOSITE = "System";

    /**
     * The system recovery component name.
     */
    public static final String SYSTEMRECOVERY_COMPONENT = "SystemRecoveryServiceImpl";

    /**
     * The JBI Management component name.
     */
    public static final String JBI_MANAGEMENT_COMPOSITE = "JBIManagement";

    /**
     * The Admin Service component name.
     */
    public static final String ADMIN_COMPONENT = "AdminServiceImpl";

    /**
     * The deployment component name.
     */
    public static final String DEPLOYMENT_COMPONENT = "DeploymentServiceImpl";

    /**
     * The installation component name.
     */
    public static final String INSTALLATION_COMPONENT = "InstallationServiceImpl";

    /**
     * the JBI messaging composite name.
     */
    public static final String JBI_MESSAGING_COMPOSITE = "JBIMessaging";

    /**
     * The endpoint directory service component name.
     */
    public static final String ENDPOINT_DIRECTORY_COMPONENT = "EndpointDirectoryServiceImpl";

    /**
     * The shared area composite name (which contains {@link #SHARED_AREA_COMPONENT}).
     */
    public static final String SHARED_AREA_COMPOSITE = "SharedArea";

    /**
     * The shared area service component name.
     */
    public static final String SHARED_AREA_COMPONENT = "SharedAreaServiceImpl";

    /**
     * The system state service component name.
     */
    public static final String SYSTEMSTATE_COMPONENT = "SystemStateServiceImpl";

    /**
     * The Router component name.
     */
    public static final String ROUTER_COMPONENT = "RouterServiceImpl";

    /**
     * The logger component name.
     */
    public static final String LOGGER_COMPONENT = "LoggingServiceMBeanImpl";

    /**
     * The Transporter composite.
     */
    public static final String TRANSPORTERS_COMPOSITE = "Transporter";

    public static final String LOCAL_TRANSPORTER_COMPONENT = "LocalTransporter";

    public static final String LOCAL_TRANSPORTER_MONITORING_COMPONENT = "LocalTransporterMonitoring";

    public static final String TCP_TRANSPORTER_COMPONENT = "TcpTransporter";

    public static final String TCP_TRANSPORTER_MONITORING_COMPONENT = "TcpTransporterMonitoring";

    /**
     * The Container composite name.
     */
    public static final String CONTAINER_COMPOSITE = "Container";

    /**
     * The Container Service component name.
     */
    public static final String CONTAINER_SERVICE_COMPONENT = "ContainerServiceImpl";

    /**
     * The Container Controller component name.
     */
    public static final String CONTAINER_CONTROLLER_COMPONENT = "ContainerControllerImpl";

    /**
     * The Petals composite controller component name
     */
    public static final String PETALS_COMPOSITE_CTRL_COMPONENT = "PetalsCompositeControllerImpl";

    /**
     * The Petals admin service component name.
     */
    public static final String PETALSADMIN_COMPONENT = "PetalsAdminServiceImpl";

    /**
     * The PreExtensionsManager composite name.
     */
    public static final String PRE_EXTENSIONSMANAGER_COMPOSITE = "PreExtensionsManager";

    /**
     * The PreExtensionsManagerImpl component name.
     */
    public static final String PRE_EXTENSIONSMANAGER_COMPONENT = "PreExtensionsManagerImpl";

    /**
     * The PostExtensionsManager composite name.
     */
    public static final String POST_EXTENSIONSMANAGER_COMPOSITE = "PostExtensionsManager";

    /**
     * The PostExtensionsManagerImpl component name.
     */
    public static final String POST_EXTENSIONSMANAGER_COMPONENT = "PostExtensionsManagerImpl";

    /**
     * the fractal factory.
     */
    private static GenericFactory factory;

    private static TypeFactory typeFactory;

    /**
     * Initialize the Fractal Factory at the loading of the Class
     */
    static {
        // check required fractal properties
        System.setProperty("fractal.provider", Juliac.class.getName());
    	
        // Create Fractal factory
        try {
            final Component boostrap = Fractal.getBootstrapComponent();
            factory = Fractal.getGenericFactory(boostrap);
            typeFactory = Fractal.getTypeFactory(boostrap);
        } catch (InstantiationException | NoSuchInterfaceException e) {
            // this should never happen, so it's best we fail at class initialization
            throw new UncheckedException(e);
        }

    }

    /**
     * Create a new component.
     * 
     * @param name
     *            The class name of the component
     * @return the new component
     * @throws NoSuchInterfaceException
     * @throws
     * @throws InstantiationException
     */
    public static final synchronized Component createCompositeComponent(final String name)
            throws InstantiationException {
        try {
            Object factory = FractalHelper.class.getClassLoader().loadClass(name).newInstance();
            if (factory instanceof Factory) {
                return ((Factory) factory).newFcInstance();
            } else {
                throw new InstantiationException(name + " is not a fractal Factory");
            }
        } catch (ClassNotFoundException e) {
            throw new ChainedInstantiationException(e, null, name + " is not a valid class name");
        } catch (IllegalAccessException | java.lang.InstantiationException e) {
            throw new ChainedInstantiationException(e, null, name + " can't be instantiated");
        }
    }

    /**
     * Doesn't work if the class use LifeCycle DESTROY because the class name will be different...
     * 
     * @param clazz
     * @return
     * @throws InstantiationException
     */
    public static final synchronized Component createPrimitiveComponent(final Class clazz)
            throws InstantiationException {
        final org.objectweb.fractal.fraclet.annotations.Component component = clazz
                .getAnnotation(org.objectweb.fractal.fraclet.annotations.Component.class);
        if (component != null) {
            final List lits = new ArrayList<>();
            for(Interface itf: component.provides()) {
                lits.add(new BasicInterfaceType(itf.name(), itf.signature().getName(), false, false, false));
            }
            for (Field field : clazz.getDeclaredFields()) {
                final Requires requires = field.getAnnotation(Requires.class);
                if (requires != null) {
                    lits.add(InterfaceTypeHelper.toInterfaceType(field, requires));
                }
            }
            final ComponentType ct = typeFactory.createFcType(lits.toArray(new InterfaceType[lits.size()]));
            return factory.newFcInstance(ct, "primitive", clazz.getName());
        } else {
            throw new InstantiationException(clazz.getName() + " is not annotated with Component");
        }
    }

    /**
     * A utility function allowing to get a component from any content
     * controller.
     * 
     * @param parentContentController
     *            parentContentController
     * @param name
     *            component name
     * @return the component, null if not found
     */
    public static final Component getRecursiveComponentByName(
            final ContentController parentContentController, final String name) {

        // List content controller subcomponents
        for (Component component : parentContentController.getFcSubComponents()) {

            // if it is the researched component, return it
            try {
                final String componentName = Fractal.getNameController(component).getFcName();
                if (componentName.equals(name)) {
                    return component;
                }
            } catch (NoSuchInterfaceException e) {
                // do nothing, return null
            }

            // else let's look recursively recursively
            try {
                final Component subComponent = getRecursiveComponentByName(Fractal.getContentController(component),
                        name);
                if (subComponent != null) {
                    return subComponent;
                }
            } catch (NoSuchInterfaceException e1) {
                // do nothing
            }
        }

        return null;
    }

    public static Component getComponentByName(final ContentController parentContentController,
            final String name) {
        // List content controller subcomponents
        for (final Component component : parentContentController.getFcSubComponents()) {

            try {
                final String componentName = Fractal.getNameController(component).getFcName();
                if (name.equals(componentName)) {
                    return component;
                }
            } catch (final NoSuchInterfaceException e) {
                // do nothing
            }
        }

        return null;
    }

    public static List getComponentListByPrefix(
            final ContentController parentContentController, final String prefix) {
        List components = new ArrayList<>();
        // List content controller subcomponents
        for (Component component : parentContentController.getFcSubComponents()) {

            try {
                String componentName = Fractal.getNameController(component).getFcName();
                if (componentName.startsWith(prefix)) {
                    components.add(component);
                }
            } catch (NoSuchInterfaceException e) {
                // do nothing
            }
        }

        return components;
    }

    /**
     * A utility function to start the given fractal component.
     * 
     * @param component
     *            the fractal component
     * @param logger
     *            can be null
     * 
     * @return true if the component was found and stopped, false otherwise
     * @throws IllegalLifeCycleException
     *             : impossible to stop the component
     */
    public static boolean startComponent(final Component component, final LoggingUtil logger)
            throws IllegalLifeCycleException {

        final LifeCycleController lifeCycleController = getLifeCycleController(component);

        final String name;
        if (logger != null && logger.isDebugEnabled()) {
            name = getNameController(component).getFcName();
            final StringBuilder sb = new StringBuilder();
            getComponentState(component, "", sb);
            logger.debug(
                    String.format("Starting fractal component '%s' ...%n%s", name, sb.toString()));
        } else {
            name = null;
        }

        final boolean stopped = LifeCycleController.STOPPED.equals(lifeCycleController.getFcState());
        if (stopped) {
            lifeCycleController.startFc();
        }

        if (logger != null && logger.isDebugEnabled()) {
            logger.debug(String.format("Fractal component '%s' started", name));
        }

        return stopped;
    }

    public static boolean startComponent(final Component component) throws IllegalLifeCycleException {
        return startComponent(component, null);
    }
    
    /**
     * A utility function to stop the given fractal component.
     * 
     * @param component
     *            the fractal component to stop
     * @param logger
     *            can be null
     * 
     * @return true if the component was found and stopped, false otherwise
     * @throws IllegalLifeCycleException
     *             : impossible to stop the component
     */
    public static boolean stopComponent(final Component component, final LoggingUtil logger)
            throws IllegalLifeCycleException {

        final LifeCycleController lifeCycleController = getLifeCycleController(component);

        final String name;
        if (logger != null && logger.isDebugEnabled()) {
            name = getNameController(component).getFcName();
            final StringBuilder sb = new StringBuilder();
            getComponentState(component, "", sb);
            logger.debug(String.format("Stopping fractal component '%s' ...%n%s", name, sb.toString()));
        } else {
            name = null;
        }

        final boolean started = LifeCycleController.STARTED.equals(lifeCycleController.getFcState());
        if (started) {
            lifeCycleController.stopFc();
        }

        if (logger != null && logger.isDebugEnabled()) {
            logger.debug(String.format("Fractal component '%s' stopped", name));
        }

        return started;
    }

    public static boolean stopComponent(final Component component) throws IllegalLifeCycleException {
        return stopComponent(component, null);
    }

    /**
     * Log the component status (started or stopped) of a Fractal component.
     * 
     * @param component
     * @throws NoSuchInterfaceException
     */
    public static void getComponentState(final Component component, final String space, final StringBuilder sb) {

        final LifeCycleController componentLC = getLifeCycleController(component);
        final NameController componentNC = getNameController(component);

        sb.append(space + "- " + componentNC.getFcName() + " is " + componentLC.getFcState() + System.lineSeparator());

        ContentController componentCC = null;
        try {
            componentCC = Fractal.getContentController(component);
        } catch (final NoSuchInterfaceException e) {
            // No content controller (ie. no sub components)
        }

        if (componentCC != null) {
            final Component[] componentSubComponents = componentCC.getFcSubComponents();
            for (final Component componentSubComponent : componentSubComponents) {
                getComponentState(componentSubComponent, space + "\t", sb);
            }
        }
    }

    /**
     * Add a component in a composite component.
     * 
     * @param newComponent
     *            The new component
     * @param parentComponent
     *            The parent component
     * @param listOfBindings
     *            the list of binding to create between this new component and
     *            the others
     * @throws NoSuchInterfaceException
     *             : Impossible to add a component
     * @throws IllegalLifeCycleException
     *             : Impossible to add a component
     * @throws IllegalContentException
     *             : Impossible to add a component
     * @throws IllegalBindingException
     *             : Impossible to add a component
     */
    public static final void addComponent(final Component newComponent, final Component parentComponent,
            final String newComponentName, Binding... bindings) throws NoSuchInterfaceException,
            IllegalContentException, IllegalLifeCycleException, IllegalBindingException {
        // Get the parent controller
        final ContentController parentContentController = Fractal.getContentController(parentComponent);

        Fractal.getNameController(newComponent).setFcName(newComponentName);

        parentContentController.addFcSubComponent(newComponent);

        // Get the binding controller of the new component
        final BindingController cBindingController = Fractal.getBindingController(newComponent);

        // Add all the bindings
        for (final Binding b : bindings) {
            cBindingController.bindFc(b.getClientInterfaceName(), b.getServerInterface());
        }
    }

    /**
     * Return the component that contains the parameter component.
     * 
     * We make the assumption this component is owned by only one component.
     * 
     * @param component
     * @return the (unique) parent component
     * @throws NoSuchInterfaceException
     * @throws PetalsException
     */
    public static final Component getParentComponent(Component component) throws NoSuchInterfaceException,
            PetalsException {
        final SuperController sc = Fractal.getSuperController(component);
        if (sc.getFcSuperComponents().length != 1) {
            throw new PetalsException("Error in fractal architecture");
        }
        return sc.getFcSuperComponents()[0];
    }

    public static LifeCycleController getLifeCycleController(final Component component) {
        try {
            return Fractal.getLifeCycleController(component);
        } catch (NoSuchInterfaceException e) {
            throw new UncheckedException("This can't happen", e);
        }
    }

    public static NameController getNameController(final Component component) {
        try {
            return Fractal.getNameController(component);
        } catch (NoSuchInterfaceException e) {
            throw new UncheckedException("This can't happen", e);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy