
org.ow2.petals.microkernel.api.server.FractalHelper Maven / Gradle / Ivy
/**
* 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