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

org.conductor.integration.ClientIntegration Maven / Gradle / Ivy

package org.conductor.integration;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.conductor.bootstrap.IComponentGroupBootstrap;
import org.conductor.component.events.ErrorEventListener;
import org.conductor.component.types.IComponent;
import org.conductor.database.Database;
import org.conductor.database.IPropertyChangedListener;
import org.conductor.integration.factories.BootstrapFactory;
import org.conductor.util.StringUtil;
import org.reflections.Reflections;

public class ClientIntegration implements IClientIntegration {
	private static Logger log = LogManager.getLogger(ClientIntegration.class.getName());
	private Database database;
	private Map> componentsOptions = new HashMap>();
	private Map components = new HashMap();
	private Method onPropertyValueUpdated;
	private Method reportError;
	private Object caller;

	public ClientIntegration(Object caller, Method onPropertyValueUpdated, Method reportError) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		log.info("Initializing component group client.");
		this.database = new Database();
		this.caller = caller;
		this.onPropertyValueUpdated = onPropertyValueUpdated;
		this.reportError = reportError;
	}

	public void start(Map componentGroupOptions) throws Exception {
		log.info("Starting component group client.");
		this.database.addPropertyChangedListener(new IPropertyChangedListener() {
			public void onPropertyValueChanged(String componentName, String propertyName, Object propertyValue) {
				try {
					componentName = StringUtil.lowercaseFirstLetter(componentName);
					onPropertyValueUpdated.invoke(caller, componentName, propertyName, propertyValue);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});

		IComponentGroupBootstrap bootstrap = BootstrapFactory.create();
		this.components = bootstrap.start(database, componentGroupOptions, componentsOptions);
		
		for(IComponent component : this.components.values()) {
			component.addErrorEventListener(componentErrorListener);
		}
	}

	public void setInitialPropertyValue(String componentName, String propertyName, Object propertyValue) {
		componentName = StringUtil.capitalizeFirstLetter(componentName);
		log.info("Setting initial property value to '{}' for property '{}' in component '{}'.", propertyValue, propertyName, componentName);
		this.database.setValue(componentName, propertyName, propertyValue);
	}

	public void setComponentOptions(String componentName, Map options) {
		componentName = StringUtil.capitalizeFirstLetter(componentName);
		log.info("Setting component options for component '{}'.", componentName);
		this.componentsOptions.put(componentName, options);
	}

	public void setPropertyValue(String componentName, String propertyName, Object propertyValue) throws Exception {
		componentName = StringUtil.capitalizeFirstLetter(componentName);
		propertyName = StringUtil.capitalizeFirstLetter(propertyName);

		log.info("Setting property value to '{}' for property '{}' in component '{}'.", propertyValue, propertyName, componentName);
		
		IComponent component = components.get(componentName);
		component.getClass().getMethod("set" + propertyName, propertyValue.getClass()).invoke(component, propertyValue);
	}

	public void callMethod(String componentName, String methodName, Map parameters) throws Exception {
		componentName = StringUtil.capitalizeFirstLetter(componentName);
		
		log.info("Calling method '{}' in component '{}'.", methodName, componentName);
		
		IComponent component = components.get(componentName);

		Reflections reflections = new Reflections(component);
		Set methods = reflections.getMethodsAnnotatedWith(org.conductor.component.annotations.Method.class);

		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Parameter[] methodParameters = method.getParameters();

				// We need to sort the parameters, because the incoming parameters is in no specific order.
				Object[] sortedParameters = new Object[methodParameters.length];
				for (int i = 0; i < methodParameters.length; i++) {
					String parameterName = methodParameters[i].getName();
					if (!parameters.containsKey(parameterName)) {
						throw new Exception("Missing parameter '" + parameterName + "'.");
					}
					sortedParameters[i] = parameters.get(parameterName);
				}
				
				method.invoke(component, sortedParameters);
				return;
			}
		}

		throw new Exception("No method was found with the name '" + methodName + "', have you missed adding the annotation to the method?");
	}

	public void destroy() {
		for (IComponent component : components.values()) {
			log.info("Destroying component '{}'.", component.getClass().getSimpleName());
			component.destroy();
		}
	}
	
	ErrorEventListener componentErrorListener = new ErrorEventListener() {
		
		@Override
		public void onError(IComponent component, String errorMessage, String stackTrace) {
			String componentName = StringUtil.lowercaseFirstLetter(component.getClass().getSimpleName());
			
			try {
				log.error("Component '{}' reported the error '{}'", componentName, errorMessage);
				reportError.invoke(caller, componentName, errorMessage, stackTrace);
			} catch (Exception e) {
				log.error("Failed to report error to conductor client.", e);
			}
		}
	};
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy