<enableImports><![CDATA[true]]></enableImports>
<configs>
<config>src/slc/conf/main.xml</config>
+ <config>src/slc/conf/testCases/basic-001.xml</config>
+ <config>src/slc/conf/testCases/basic-002.xml</config>
+ <config>src/slc/conf/basic.xml</config>
+ <config>src/slc/conf/common.xml</config>
+ <config>src/slc/conf/test.xml</config>
</configs>
<configSets>
</configSets>
--- /dev/null
+package org.argeo.slc.execution;
+
+public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute {
+ private Boolean isParameter = true;
+
+ public Boolean getIsParameter() {
+ return isParameter;
+ }
+
+ public void setIsParameter(Boolean isParameter) {
+ this.isParameter = isParameter;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+
+public class ConsoleContextDescriber implements ContextDescriber {
+ private final static Log log = LogFactory
+ .getLog(ConsoleContextDescriber.class);
+
+ public void describeContext(BeanDefinitionRegistry registry) {
+ String[] beanNames = registry.getBeanDefinitionNames();
+ for (String beanName : beanNames) {
+ log("\n## BEAN: " + beanName);
+ describeBean(registry.getBeanDefinition(beanName));
+ }
+ }
+
+ public void describeBean(BeanDefinition beanDefinition) {
+ log("BeanDefinition class: "+beanDefinition.getClass());
+ log("# ATTRIBUTES");
+ for(String attr:beanDefinition.attributeNames()){
+ log(attr+"="+beanDefinition.getAttribute(attr));
+ }
+ log("# PROPERTIES");
+ MutablePropertyValues pValues = beanDefinition.getPropertyValues();
+ for (PropertyValue pv : pValues.getPropertyValues()) {
+ log(pv.getName() + "= (" + pv.getValue().getClass() + ") "
+ + pv.getValue());
+ }
+ }
+
+ protected void log(Object obj){
+ System.out.println(obj);
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+
+public interface ContextDescriber {
+ public void describeContext(BeanDefinitionRegistry registry);
+ public void describeBean(BeanDefinition bd);
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.logging.Log4jUtils;
+import org.argeo.slc.process.SlcExecution;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionParser;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.support.FileSystemXmlApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+
+public class EfLauncher implements ApplicationListener {
+ private final Log log;
+
+ private boolean running = false;
+
+ public EfLauncher() {
+ Properties userProperties = new Properties();
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream("src/slc/conf/slc.properties");
+ userProperties.load(in);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+
+ // Set as System properties
+ for (Object obj : userProperties.keySet()) {
+ String key = obj.toString();
+ System.setProperty(key, userProperties.getProperty(key));
+ }
+
+ // Logging
+ System.setProperty("log4j.defaultInitOverride", "true");
+
+ Log4jUtils.initLog4j(null);
+ log = LogFactory.getLog(EfLauncher.class);
+ }
+
+ public void launch(String script) {
+ // describe(script);
+
+ GenericApplicationContext context = new GenericApplicationContext();
+ XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(context);
+ reader.loadBeanDefinitions(script);
+ // FileSystemXmlApplicationContext context = new
+ // FileSystemXmlApplicationContext(
+ // script);
+ context.addApplicationListener(this);
+ context.refresh();
+ context.start();
+ log.debug("Context initialized");
+
+ SlcExecution slcExecution = new SlcExecution();
+ slcExecution.getAttributes().put("slc.flows", "main");
+
+ running = true;
+ context.publishEvent(new NewExecutionEvent(this, slcExecution));
+
+ synchronized (this) {
+ while (running)
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ // silent
+ }
+ }
+ }
+
+ public synchronized boolean isRunning() {
+ return running;
+ }
+
+ public synchronized void setRunning(boolean running) {
+ this.running = running;
+ }
+
+ public void onApplicationEvent(ApplicationEvent event) {
+ if (event instanceof ExecutionFinishedEvent) {
+ ExecutionContext executionContext = ((ExecutionFinishedEvent) event)
+ .getExecutionContext();
+ log.debug("Execution " + executionContext.getUuid()
+ + " finished, stopping launcher...");
+ synchronized (this) {
+ running = false;
+ notifyAll();
+ }
+ }
+
+ }
+
+ public static void main(String[] args) {
+ String script = "file:src/slc/conf/main.xml";
+ new EfLauncher().launch(script);
+ }
+
+ private static void describe(String script) {
+ SimpleBeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
+ XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
+ reader.loadBeanDefinitions(script);
+ new ConsoleContextDescriber().describeContext(registry);
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+
+@Aspect
+public class ExecutionAspect {
+ private static Log log = LogFactory.getLog(ExecutionAspect.class);
+
+ @Before("flowExecution()")
+ public void beforeFlow(JoinPoint jp) throws Throwable {
+ //log.debug("this " + jp.getThis().getClass());
+ //log.debug("target " + jp.getTarget().getClass());
+ // Thread.dumpStack();
+ ExecutionFlow executionFlow = (ExecutionFlow) jp.getTarget();
+ ExecutionContext.enterFlow(executionFlow);
+ }
+
+ @After("flowExecution()")
+ public void afterFlow(JoinPoint jp) throws Throwable {
+ //log.debug("this " + jp.getThis().getClass());
+ //log.debug("target " + jp.getTarget().getClass());
+ ExecutionFlow executionFlow = (ExecutionFlow) jp.getTarget();
+ ExecutionContext.leaveFlow(executionFlow);
+ }
+
+ @Pointcut("execution(void org.argeo.slc.execution.ExecutionFlow.execute())")
+ public void flowExecution() {
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.process.SlcExecution;
+import org.springframework.beans.factory.ObjectFactory;
+
+public class ExecutionContext {
+ private final static Log log = LogFactory.getLog(ExecutionContext.class);
+
+ private final static ThreadLocal<ExecutionContext> executionContext = new ThreadLocal<ExecutionContext>();
+
+ private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
+
+ // TODO: make it thread safe?
+ private final Map<String, Object> variables = new HashMap<String, Object>();
+
+ private final String uuid = UUID.randomUUID().toString();
+
+ public static Map<String, Object> getVariables() {
+ if (executionContext.get() == null)
+ return null;
+ return executionContext.get().variables;
+ }
+
+ public static ExecutionContext getCurrent() {
+ return executionContext.get();
+ }
+
+ public static String getExecutionUuid() {
+ if (executionContext.get() == null)
+ return null;
+ return executionContext.get().getUuid();
+ }
+
+ public static void registerExecutionContext(ExecutionContext context) {
+ if (executionContext.get() != null)
+ throw new SlcException("Context #" + executionContext.get().uuid
+ + " already registered.");
+ executionContext.set(context);
+ }
+
+ public static void enterFlow(ExecutionFlow executionFlow) {
+ Stack<ExecutionFlowRuntime> stack = executionContext.get().stack;
+
+ ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
+ stack.push(runtime);
+
+ if (log.isTraceEnabled())
+ log.debug(depthSpaces(stack.size()) + "=> " + executionFlow + " #"
+ + getCurrentStackUuid() + ", depth=" + stack.size());
+
+ Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
+ .getExecutionSpec().getAttributes();
+ for (String key : specAttrs.keySet()) {
+ ExecutionSpecAttribute esa = specAttrs.get(key);
+ if (esa.getIsParameter()) {
+ runtime.getLocalVariables().put(key,
+ executionFlow.getParameter(key));
+ if (log.isTraceEnabled())
+ log.trace(depthSpaces(stack.size()) + "Add '" + key
+ + "' as local variable.");
+ }
+ }
+
+ }
+
+ public static Object getVariable(String key) {
+ Object obj = getWithCheck().findVariable(key);
+ if (obj == null)
+ throw new SlcException("Variable '" + key + "' not found.");
+ return obj;
+ }
+
+ protected Object findVariable(String key) {
+ Object obj = null;
+ for (int i = stack.size() - 1; i >= 0; i--) {
+ if (stack.get(i).getLocalVariables().containsKey(key)) {
+ obj = stack.get(i).getLocalVariables().get(key);
+ break;
+ }
+ }
+
+ // Look into global execution variables
+ if (obj == null) {
+ if (variables.containsKey(key))
+ obj = variables.get(key);
+ }
+
+ return obj;
+ }
+
+ private static String depthSpaces(int depth) {
+ StringBuffer buf = new StringBuffer(depth * 2);
+ for (int i = 0; i < depth; i++)
+ buf.append(" ");
+ return buf.toString();
+ }
+
+ public static void leaveFlow(ExecutionFlow executionFlow) {
+ Stack<ExecutionFlowRuntime> stack = executionContext.get().stack;
+ if (log.isTraceEnabled())
+ log.debug(depthSpaces(stack.size()) + "<= " + executionFlow + " #"
+ + getCurrentStackUuid() + ", depth=" + stack.size());
+
+ ExecutionFlowRuntime leftEf = stack.pop();
+ if (!leftEf.getExecutionFlow().getUuid()
+ .equals(executionFlow.getUuid()))
+ throw new SlcException("Asked to leave " + executionFlow
+ + " but last is " + leftEf);
+
+ leftEf.getScopedObjects().clear();
+ leftEf.getLocalVariables().clear();
+
+ }
+
+ public static String getCurrentStackUuid() {
+ return getWithCheck().stack.peek().uuid;
+ }
+
+ // public static ExecutionFlow getCurrentFlow() {
+ // return getWithCheck().stack.peek().executionFlow;
+ // }
+
+ public static Boolean isExecuting() {
+ return executionContext.get() != null;
+ }
+
+ protected static ExecutionContext getWithCheck() {
+ if (executionContext.get() == null)
+ throw new SlcException("No execution context");
+ return executionContext.get();
+ }
+
+ public static Object findOrAddScopedObject(String name,
+ ObjectFactory objectFactory) {
+ ExecutionContext executionContext = getWithCheck();
+ Object obj = executionContext.findScopedObject(name);
+ if (obj == null) {
+ obj = objectFactory.getObject();
+ executionContext.stack.peek().getScopedObjects().put(name, obj);
+ }
+ return obj;
+ }
+
+ /** return null if not found */
+ protected Object findScopedObject(String key) {
+ Object obj = null;
+ for (int i = stack.size() - 1; i >= 0; i--) {
+ if (stack.get(i).getScopedObjects().containsKey(key)) {
+ obj = stack.get(i).getScopedObjects().get(key);
+ break;
+ }
+ }
+ return obj;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ private static class ExecutionFlowRuntime {
+ private final ExecutionFlow executionFlow;
+ private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
+ private final Map<String, Object> localVariables = new HashMap<String, Object>();
+ private final String uuid = UUID.randomUUID().toString();
+
+ public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
+ this.executionFlow = executionFlow;
+ }
+
+ public ExecutionFlow getExecutionFlow() {
+ return executionFlow;
+ }
+
+ public Map<String, Object> getScopedObjects() {
+ return scopedObjects;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public Map<String, Object> getLocalVariables() {
+ return localVariables;
+ }
+
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.springframework.context.ApplicationEvent;
+
+public class ExecutionFinishedEvent extends ApplicationEvent {
+ static final long serialVersionUID = 012;
+
+ private final ExecutionContext executionContext;
+
+ public ExecutionFinishedEvent(Object source, ExecutionContext executionContext) {
+ super(source);
+ this.executionContext = executionContext;
+ }
+
+ public ExecutionContext getExecutionContext() {
+ return executionContext;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.util.Map;
+
+import org.argeo.slc.process.Executable;
+
+public interface ExecutionFlow extends Executable{
+ public Object getParameter(String name);
+ public ExecutionSpec getExecutionSpec();
+ public String getUuid();
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.argeo.slc.process.Executable;
+
+public class ExecutionFlowFactory {
+ private List<Executable> executables = new ArrayList<Executable>();
+
+
+ public ExecutionFlow createExecutionFlow(Map<String, Object> attributes){
+ SimpleExecutionFlow executionFlow = new SimpleExecutionFlow();
+ executionFlow.setExecutables(executables);
+ return executionFlow;
+ }
+
+
+ public void setExecutables(List<Executable> executables) {
+ this.executables = executables;
+ }
+
+
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.beans.PropertyDescriptor;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.PropertyValues;
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+import org.springframework.beans.factory.config.TypedStringValue;
+
+public class ExecutionParameterPostProcessor extends
+ InstantiationAwareBeanPostProcessorAdapter {
+ private final static Log log = LogFactory
+ .getLog(ExecutionParameterPostProcessor.class);
+
+ private String placeholderPrefix = "@{";
+ private String placeholderSuffix = "}";
+ private String nullValue;
+
+ @Override
+ public PropertyValues postProcessPropertyValues(PropertyValues pvs,
+ PropertyDescriptor[] pds, Object bean, String beanName)
+ throws BeansException {
+ if (!ExecutionContext.isExecuting())
+ return pvs;
+
+// ExecutionFlow currentFlow = ExecutionContext.getCurrentFlow();
+//
+// Properties props = new Properties();
+// Map<String, Object> attributes = currentFlow.getAttributes();
+// Map<String, ExecutionSpecAttribute> specAttributes = currentFlow
+// .getExecutionSpec().getAttributes();
+//
+// for (String key : specAttributes.keySet()) {
+// ExecutionSpecAttribute obj = specAttributes.get(key);
+// if (!(obj instanceof RefSpecAttribute)) {
+// if (!attributes.containsKey(key))
+// throw new SlcException("Specified attribute " + key
+// + " is not set in " + currentFlow);
+//
+// props.setProperty(key, attributes.get(key).toString());
+// // if (log.isTraceEnabled())
+// // log.trace("Use attribute " + key);
+// }
+// }
+
+ Properties props = new Properties();
+ CustomPpc ppc = new CustomPpc(props);
+
+ for (PropertyValue pv : pvs.getPropertyValues()) {
+ if (pv.getValue() instanceof TypedStringValue) {
+ TypedStringValue tsv = (TypedStringValue) pv.getValue();
+ String originalValue = tsv.getValue();
+ String convertedValue = ppc.process(originalValue);
+ tsv.setValue(convertedValue);
+ if (log.isTraceEnabled()) {
+ if (!originalValue.equals(convertedValue))
+ log.trace("Converted field '" + pv.getName() + "': '"
+ + originalValue + "' to '" + convertedValue
+ + "' in bean " + beanName);
+ }
+ } else {
+ // if (log.isTraceEnabled())
+ // log.trace(beanName + "[" + pv.getName() + "]: "
+ // + pv.getValue().getClass());
+ }
+ }
+
+ return pvs;
+ }
+
+ public void setPlaceholderPrefix(String placeholderPrefix) {
+ this.placeholderPrefix = placeholderPrefix;
+ }
+
+ public void setPlaceholderSuffix(String placeholderSuffix) {
+ this.placeholderSuffix = placeholderSuffix;
+ }
+
+ public void setNullValue(String nullValue) {
+ this.nullValue = nullValue;
+ }
+
+ private class CustomPpc extends PropertyPlaceholderConfigurer {
+ private final Properties props;
+
+ public CustomPpc(Properties props) {
+ super();
+ this.props = props;
+ setPlaceholderPrefix(placeholderPrefix);
+ setPlaceholderSuffix(placeholderSuffix);
+ setSystemPropertiesMode(SYSTEM_PROPERTIES_MODE_NEVER);
+ }
+
+ public String process(String strVal) {
+ String value = parseStringValue(strVal, this.props,
+ new HashSet<String>());
+ return (value.equals(nullValue) ? null : value);
+ }
+
+ @Override
+ protected String resolvePlaceholder(String placeholder, Properties props) {
+ if (ExecutionContext.isExecuting())
+ return ExecutionContext.getVariable(placeholder).toString();
+ else if (SimpleExecutionSpec.isInFlowInitialization())
+ return SimpleExecutionSpec.getInitializingFlowParameter(
+ placeholder).toString();
+ else
+ return super.resolvePlaceholder(placeholder, props);
+ }
+
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class ExecutionRegister implements InitializingBean {
+ private final static Log log = LogFactory.getLog(ExecutionRegister.class);
+
+ @Autowired
+ private Set<ExecutionFlow> executionFlows;
+
+ @Autowired
+ private Set<ExecutionSpec> executionSpecs;
+
+ public void afterPropertiesSet() throws Exception {
+ log.debug("Register: " + executionSpecs.size() + " specs");
+ for (ExecutionSpec spec : executionSpecs) {
+ log.debug(spec);
+ Map<String, ExecutionSpecAttribute> attributes = spec
+ .getAttributes();
+ log.debug("Spec attributes: ");
+ for (String key : attributes.keySet()) {
+ log.debug(" " + key + "\t" + attributes.get(key));
+ }
+ }
+
+ log.debug("Register: " + executionFlows.size() + " flows");
+ for (ExecutionFlow flow : executionFlows) {
+ log.debug(flow);
+// Map<String, Object> attributes = flow.getAttributes();
+// log.debug("Specified parameters: ");
+// for (String key : flow.getExecutionSpec().getAttributes().keySet()) {
+// log.debug(" "
+// + key
+// + "\t"
+// + (attributes.containsKey(key) ? "SPECIFIED"
+// : "TO SPECIFY"));
+// }
+ }
+
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.config.Scope;
+
+public class ExecutionScope implements Scope {
+ private final static Log log = LogFactory.getLog(ExecutionScope.class);
+
+ public Object get(String name, ObjectFactory objectFactory) {
+
+ if (log.isTraceEnabled())
+ log.trace("Getting scoped bean " + name);
+ return ExecutionContext.findOrAddScopedObject(name, objectFactory);
+
+ // if (ExecutionContext.getScopedObjects().containsKey(name)) {
+ // // returns cached instance
+ // Object obj = ExecutionContext.getScopedObjects().get(name);
+ // if (log.isTraceEnabled())
+ // log.trace("Return cached scoped object " + obj);
+ // return obj;
+ // } else {
+ // // creates instance
+ // Object obj = objectFactory.getObject();
+ // ExecutionContext.getScopedObjects().put(name, obj);
+ // if (log.isTraceEnabled())
+ // log.trace("Created regular scoped object " + obj);
+ // return obj;
+ // }
+ }
+
+ public String getConversationId() {
+ return ExecutionContext.getCurrentStackUuid();
+ }
+
+ public void registerDestructionCallback(String name, Runnable callback) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object remove(String name) {
+ log.debug("Remove object " + name);
+ throw new UnsupportedOperationException();
+ }
+
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.util.Map;
+
+public interface ExecutionSpec {
+ public Map<String, ExecutionSpecAttribute> getAttributes();
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+public interface ExecutionSpecAttribute {
+ public Object getValue();
+ public Boolean getIsParameter();
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.aop.TargetSource;
+
+public class ExecutionTargetSource implements TargetSource {
+ private final static Log log = LogFactory
+ .getLog(ExecutionTargetSource.class);
+
+ private final String name;
+ private final Class<?> targetClass;
+ private final ExecutionFlow executionFlow;
+
+ public ExecutionTargetSource(ExecutionFlow executionFlow,
+ Class<?> targetClass, String name) {
+ this.executionFlow = executionFlow;
+ this.targetClass = targetClass;
+ this.name = name;
+ }
+
+ public Object getTarget() throws Exception {
+ if (log.isTraceEnabled())
+ log.trace("Getting object " + name);
+ Object obj = executionFlow.getParameter(name);
+ if (log.isTraceEnabled())
+ log.trace("Target object " + obj);
+ return obj;
+ }
+
+ public Class getTargetClass() {
+ return targetClass;
+ }
+
+ public boolean isStatic() {
+ return false;
+ }
+
+ public void releaseTarget(Object target) throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.process.SlcExecution;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationListener;
+
+public class Executor implements ApplicationListener, ApplicationContextAware {
+ private final static Log log = LogFactory.getLog(Executor.class);
+
+ private ApplicationContext applicationContext;
+
+ public void onApplicationEvent(ApplicationEvent event) {
+ if (event instanceof NewExecutionEvent) {
+ SlcExecution slcExecution = ((NewExecutionEvent) event)
+ .getSlcExecution();
+ ExecutionContext executionContext = new ExecutionContext();
+ ExecutionThread thread = new ExecutionThread(executionContext,
+ slcExecution);
+ thread.start();
+ }
+
+ }
+
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ private class ExecutionThread extends Thread {
+ private final SlcExecution slcExecution;
+ private final ExecutionContext executionContext;
+
+ public ExecutionThread(ExecutionContext executionContext,
+ SlcExecution slcExecution) {
+ super("SLC Execution #" + executionContext.getUuid());
+ this.slcExecution = slcExecution;
+ this.executionContext = executionContext;
+ }
+
+ public void run() {
+ // Initialize from SlcExecution
+ ExecutionContext.registerExecutionContext(executionContext);
+ ExecutionContext.getVariables()
+ .putAll(slcExecution.getAttributes());
+
+ try {
+ log.info("Start execution #"
+ + ExecutionContext.getExecutionUuid());
+ String executionBean = slcExecution.getAttributes().get(
+ "slc.flows");
+ ExecutionFlow main = (ExecutionFlow) applicationContext
+ .getBean(executionBean);
+ main.execute();
+ } catch (Exception e) {
+ log.error("Execution " + executionContext.getUuid()
+ + " failed.", e);
+ } finally {
+ applicationContext.publishEvent(new ExecutionFinishedEvent(
+ this, executionContext));
+ }
+
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
+
+public class InstantiationPostProcessor extends
+ InstantiationAwareBeanPostProcessorAdapter {
+ private final static Log log = LogFactory
+ .getLog(InstantiationPostProcessor.class);
+
+ @Override
+ public boolean postProcessAfterInstantiation(Object bean, String beanName)
+ throws BeansException {
+ if (bean instanceof ExecutionFlow)
+ SimpleExecutionSpec.flowInitializationStarted((ExecutionFlow) bean);
+ return true;
+ }
+
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName)
+ throws BeansException {
+ if (bean instanceof ExecutionFlow)
+ SimpleExecutionSpec
+ .flowInitializationFinished((ExecutionFlow) bean);
+ return bean;
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import org.argeo.slc.process.SlcExecution;
+import org.springframework.context.ApplicationEvent;
+
+public class NewExecutionEvent extends ApplicationEvent {
+ static final long serialVersionUID = 012;
+
+ private final SlcExecution slcExecution;
+
+ public NewExecutionEvent(Object source, SlcExecution slcExecution) {
+ super(source);
+ this.slcExecution = slcExecution;
+ }
+
+ public SlcExecution getSlcExecution() {
+ return slcExecution;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+public class RefSpecAttribute extends AbstractSpecAttribute {
+ private Class targetClass;
+ private Object value = null;
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ public Class getTargetClass() {
+ return targetClass;
+ }
+
+ public void setTargetClass(Class targetClass) {
+ this.targetClass = targetClass;
+ }
+
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.commons.lang.math.RandomUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.process.Executable;
+import org.argeo.slc.test.ExecutableTestRun;
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.validation.MapBindingResult;
+
+public class SimpleExecutionFlow implements ExecutionFlow, InitializingBean,
+ BeanNameAware {
+ private ExecutionSpec executionSpec = new SimpleExecutionSpec();
+ private String name = null;
+ private Map<String, Object> parameters = new HashMap<String, Object>();
+ private List<Executable> executables = new ArrayList<Executable>();
+
+ private final String uuid = UUID.randomUUID().toString();
+
+ public void execute() {
+ for (Executable executable : executables) {
+ executable.execute();
+ }
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ // Validate execution specs
+ if (executionSpec == null)
+ return;
+
+ MapBindingResult errors = new MapBindingResult(parameters, "execution#"
+ + getUuid());
+ for (String key : executionSpec.getAttributes().keySet()) {
+ ExecutionSpecAttribute executionSpecAttr = executionSpec
+ .getAttributes().get(key);
+ if (!parameters.containsKey(key)) {
+ Object defaultValue = executionSpecAttr.getValue();
+ if (defaultValue == null)
+ errors.rejectValue(key, "Not set and no default value");
+ else
+ parameters.put(key, defaultValue);
+ } else {// contains key
+ Object obj = parameters.get(key);
+ if (executionSpecAttr instanceof RefSpecAttribute) {
+ RefSpecAttribute rsa = (RefSpecAttribute) executionSpecAttr;
+ Class targetClass = rsa.getTargetClass();
+ if (!targetClass.isAssignableFrom(obj.getClass())) {
+ errors.reject(key
+ + " not compatible with target class "
+ + targetClass);
+ }
+ }
+ }
+ }
+
+ if (errors.hasErrors())
+ throw new SlcException("Could not prepare execution flow: "
+ + errors.toString());
+ }
+
+ public void setBeanName(String name) {
+ this.name = name;
+ }
+
+ public void setExecutables(List<Executable> executables) {
+ this.executables = executables;
+ }
+
+ public void setExecutionSpec(ExecutionSpec executionSpec) {
+ this.executionSpec = executionSpec;
+ }
+
+ public void setParameters(Map<String, Object> attributes) {
+ this.parameters = attributes;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public ExecutionSpec getExecutionSpec() {
+ return executionSpec;
+ }
+
+ public Object getParameter(String name) {
+ if (parameters.containsKey(name)) {
+ return parameters.get(name);
+ } else {
+ if (executionSpec.getAttributes().containsKey(name)) {
+ ExecutionSpecAttribute esa = executionSpec.getAttributes().get(
+ name);
+ if (esa.getValue() != null)
+ return esa.getValue();
+ } else {
+ throw new SlcException("Key " + name
+ + " is not define in the specifications of "
+ + toString());
+ }
+ }
+ throw new SlcException("Key " + name + " is not set as parameter in "
+ + toString());
+ }
+
+ public String toString() {
+ return new StringBuffer("Flow ").append(name).toString();// .append(" [#")
+ // .append(uuid).append(']').toString();
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.argeo.slc.SlcException;
+import org.springframework.aop.framework.ProxyFactory;
+import org.springframework.beans.factory.BeanNameAware;
+
+public class SimpleExecutionSpec implements ExecutionSpec, BeanNameAware {
+ private final static ThreadLocal<ExecutionFlow> initializingFlow = new ThreadLocal<ExecutionFlow>();
+
+ private Map<String, ExecutionSpecAttribute> attributes = new HashMap<String, ExecutionSpecAttribute>();
+
+ private String name = null;
+
+ public Map<String, ExecutionSpecAttribute> getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map<String, ExecutionSpecAttribute> attributes) {
+ this.attributes = attributes;
+ }
+
+ public Object createRef(String name) {
+ ExecutionFlow flow = initializingFlow.get();
+ if (flow == null)
+ throw new SlcException("No flow is currently initializing."
+ + " Declare flow refs as inner beans or prototypes.");
+
+ RefSpecAttribute refSpecAttribute = (RefSpecAttribute) attributes
+ .get(name);
+ Class<?> targetClass = refSpecAttribute.getTargetClass();
+ ExecutionTargetSource targetSource = new ExecutionTargetSource(flow,
+ targetClass, name);
+ ProxyFactory proxyFactory = new ProxyFactory();
+ proxyFactory.setTargetClass(targetClass);
+ proxyFactory.setProxyTargetClass(true);
+ proxyFactory.setTargetSource(targetSource);
+
+ return proxyFactory.getProxy();
+ }
+
+ public void setBeanName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static void flowInitializationStarted(ExecutionFlow flow) {
+ initializingFlow.set(flow);
+ }
+
+ public static void flowInitializationFinished(ExecutionFlow flow) {
+ ExecutionFlow registeredFlow = initializingFlow.get();
+ if (registeredFlow == null)
+ throw new SlcException("No flow registered");
+ if (!flow.getUuid().equals(registeredFlow.getUuid()))
+ throw new SlcException("Current flow is " + flow);
+ initializingFlow.set(null);
+ }
+
+ public static Object getInitializingFlowParameter(String key) {
+ if (initializingFlow.get() == null)
+ throw new SlcException("No initializing flow available.");
+ return initializingFlow.get().getParameter(key);
+ }
+
+ public static Boolean isInFlowInitialization() {
+ return initializingFlow.get() != null;
+ }
+}
--- /dev/null
+package org.argeo.slc.execution;
+
+public class SimpleSpecAttribute extends AbstractSpecAttribute {
+ private Object value = null;
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute {
- private Boolean isParameter = true;
-
- public Boolean getIsParameter() {
- return isParameter;
- }
-
- public void setIsParameter(Boolean isParameter) {
- this.isParameter = isParameter;
- }
-
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.PropertyValue;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-
-public class ConsoleContextDescriber implements ContextDescriber {
- private final static Log log = LogFactory
- .getLog(ConsoleContextDescriber.class);
-
- public void describeContext(BeanDefinitionRegistry registry) {
- String[] beanNames = registry.getBeanDefinitionNames();
- for (String beanName : beanNames) {
- log("\n## BEAN: " + beanName);
- describeBean(registry.getBeanDefinition(beanName));
- }
- }
-
- public void describeBean(BeanDefinition beanDefinition) {
- log("BeanDefinition class: "+beanDefinition.getClass());
- log("# ATTRIBUTES");
- for(String attr:beanDefinition.attributeNames()){
- log(attr+"="+beanDefinition.getAttribute(attr));
- }
- log("# PROPERTIES");
- MutablePropertyValues pValues = beanDefinition.getPropertyValues();
- for (PropertyValue pv : pValues.getPropertyValues()) {
- log(pv.getName() + "= (" + pv.getValue().getClass() + ") "
- + pv.getValue());
- }
- }
-
- protected void log(Object obj){
- System.out.println(obj);
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-
-public interface ContextDescriber {
- public void describeContext(BeanDefinitionRegistry registry);
- public void describeBean(BeanDefinition bd);
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.logging.Log4jUtils;
-import org.argeo.slc.process.SlcExecution;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.PropertyValue;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
-import org.springframework.beans.factory.xml.XmlBeanDefinitionParser;
-import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.context.ApplicationEvent;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.support.FileSystemXmlApplicationContext;
-import org.springframework.context.support.GenericApplicationContext;
-
-public class EfLauncher implements ApplicationListener {
- private final Log log;
-
- private boolean running = false;
-
- public EfLauncher() {
- Properties userProperties = new Properties();
- FileInputStream in = null;
- try {
- in = new FileInputStream("src/slc/conf/slc.properties");
- userProperties.load(in);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- IOUtils.closeQuietly(in);
- }
-
- // Set as System properties
- for (Object obj : userProperties.keySet()) {
- String key = obj.toString();
- System.setProperty(key, userProperties.getProperty(key));
- }
-
- // Logging
- System.setProperty("log4j.defaultInitOverride", "true");
-
- Log4jUtils.initLog4j(null);
- log = LogFactory.getLog(EfLauncher.class);
- }
-
- public void launch(String script) {
- // describe(script);
-
- GenericApplicationContext context = new GenericApplicationContext();
- XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(context);
- reader.loadBeanDefinitions(script);
- // FileSystemXmlApplicationContext context = new
- // FileSystemXmlApplicationContext(
- // script);
- context.addApplicationListener(this);
- context.refresh();
- context.start();
- log.debug("Context initialized");
-
- SlcExecution slcExecution = new SlcExecution();
- slcExecution.getAttributes().put("slc.flows", "main");
-
- running = true;
- context.publishEvent(new NewExecutionEvent(this, slcExecution));
-
- synchronized (this) {
- while (running)
- try {
- wait();
- } catch (InterruptedException e) {
- // silent
- }
- }
- }
-
- public synchronized boolean isRunning() {
- return running;
- }
-
- public synchronized void setRunning(boolean running) {
- this.running = running;
- }
-
- public void onApplicationEvent(ApplicationEvent event) {
- if (event instanceof ExecutionFinishedEvent) {
- ExecutionContext executionContext = ((ExecutionFinishedEvent) event)
- .getExecutionContext();
- log.debug("Execution " + executionContext.getUuid()
- + " finished, stopping launcher...");
- synchronized (this) {
- running = false;
- notifyAll();
- }
- }
-
- }
-
- public static void main(String[] args) {
- String script = "file:src/slc/conf/main.xml";
- new EfLauncher().launch(script);
- }
-
- private static void describe(String script) {
- SimpleBeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
- XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
- reader.loadBeanDefinitions(script);
- new ConsoleContextDescriber().describeContext(registry);
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.After;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.annotation.Pointcut;
-
-@Aspect
-public class ExecutionAspect {
- private static Log log = LogFactory.getLog(ExecutionAspect.class);
-
- // @Around("execution(void org.argeo.slc.executionflow.ExecutionFlow.execute()) && target(org.argeo.slc.executionflow.ExecutionFlow)")
- public void registerFlow(ProceedingJoinPoint pjp) throws Throwable {
- try {
- log.debug("registerFlow " + pjp.getTarget().getClass());
- ExecutionContext.enterFlow((ExecutionFlow) pjp.getTarget());
- pjp.proceed();
- } finally {
- ExecutionContext.leaveFlow((ExecutionFlow) pjp.getTarget());
- }
- }
-
- @Before("flowExecution()")
- public void beforeFlow(JoinPoint jp) throws Throwable {
- //log.debug("this " + jp.getThis().getClass());
- //log.debug("target " + jp.getTarget().getClass());
- // Thread.dumpStack();
- ExecutionFlow executionFlow = (ExecutionFlow) jp.getTarget();
- ExecutionContext.enterFlow(executionFlow);
- }
-
- @After("flowExecution()")
- public void afterFlow(JoinPoint jp) throws Throwable {
- //log.debug("this " + jp.getThis().getClass());
- //log.debug("target " + jp.getTarget().getClass());
- ExecutionFlow executionFlow = (ExecutionFlow) jp.getTarget();
- ExecutionContext.leaveFlow(executionFlow);
- }
-
- @Pointcut("execution(void org.argeo.slc.executionflow.ExecutionFlow.execute())")
- public void flowExecution() {
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-import java.util.UUID;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.process.SlcExecution;
-import org.springframework.beans.factory.ObjectFactory;
-
-public class ExecutionContext {
- private final static Log log = LogFactory.getLog(ExecutionContext.class);
-
- private final static ThreadLocal<ExecutionContext> executionContext = new ThreadLocal<ExecutionContext>();
-
- private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
-
- // TODO: make it thread safe?
- private final Map<String, Object> variables = new HashMap<String, Object>();
-
- private final String uuid = UUID.randomUUID().toString();
-
- public static Map<String, Object> getVariables() {
- if (executionContext.get() == null)
- return null;
- return executionContext.get().variables;
- }
-
- public static ExecutionContext getCurrent() {
- return executionContext.get();
- }
-
- public static String getExecutionUuid() {
- if (executionContext.get() == null)
- return null;
- return executionContext.get().getUuid();
- }
-
- public static void registerExecutionContext(ExecutionContext context) {
- if (executionContext.get() != null)
- throw new SlcException("Context #" + executionContext.get().uuid
- + " already registered.");
- executionContext.set(context);
- }
-
- public static void enterFlow(ExecutionFlow executionFlow) {
- Stack<ExecutionFlowRuntime> stack = executionContext.get().stack;
-
- ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
- stack.push(runtime);
-
- if (log.isTraceEnabled())
- log.debug(depthSpaces(stack.size()) + "=> " + executionFlow + " #"
- + getCurrentStackUuid() + ", depth=" + stack.size());
-
- Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
- .getExecutionSpec().getAttributes();
- for (String key : specAttrs.keySet()) {
- ExecutionSpecAttribute esa = specAttrs.get(key);
- if (esa.getIsParameter()) {
- runtime.getLocalVariables().put(key,
- executionFlow.getParameter(key));
- if (log.isTraceEnabled())
- log.trace(depthSpaces(stack.size()) + "Add '" + key
- + "' as local variable.");
- }
- }
-
- }
-
- public static Object getVariable(String key) {
- Object obj = getWithCheck().findVariable(key);
- if (obj == null)
- throw new SlcException("Variable '" + key + "' not found.");
- return obj;
- }
-
- protected Object findVariable(String key) {
- Object obj = null;
- for (int i = stack.size() - 1; i >= 0; i--) {
- if (stack.get(i).getLocalVariables().containsKey(key)) {
- obj = stack.get(i).getLocalVariables().get(key);
- break;
- }
- }
-
- // Look into global execution variables
- if (obj == null) {
- if (variables.containsKey(key))
- obj = variables.get(key);
- }
-
- return obj;
- }
-
- private static String depthSpaces(int depth) {
- StringBuffer buf = new StringBuffer(depth * 2);
- for (int i = 0; i < depth; i++)
- buf.append(" ");
- return buf.toString();
- }
-
- public static void leaveFlow(ExecutionFlow executionFlow) {
- Stack<ExecutionFlowRuntime> stack = executionContext.get().stack;
- if (log.isTraceEnabled())
- log.debug(depthSpaces(stack.size()) + "<= " + executionFlow + " #"
- + getCurrentStackUuid() + ", depth=" + stack.size());
-
- ExecutionFlowRuntime leftEf = stack.pop();
- if (!leftEf.getExecutionFlow().getUuid()
- .equals(executionFlow.getUuid()))
- throw new SlcException("Asked to leave " + executionFlow
- + " but last is " + leftEf);
-
- leftEf.getScopedObjects().clear();
- leftEf.getLocalVariables().clear();
-
- }
-
- public static String getCurrentStackUuid() {
- return getWithCheck().stack.peek().uuid;
- }
-
- // public static ExecutionFlow getCurrentFlow() {
- // return getWithCheck().stack.peek().executionFlow;
- // }
-
- public static Boolean isExecuting() {
- return executionContext.get() != null;
- }
-
- protected static ExecutionContext getWithCheck() {
- if (executionContext.get() == null)
- throw new SlcException("No execution context");
- return executionContext.get();
- }
-
- public static Object findOrAddScopedObject(String name,
- ObjectFactory objectFactory) {
- ExecutionContext executionContext = getWithCheck();
- Object obj = executionContext.findScopedObject(name);
- if (obj == null) {
- obj = objectFactory.getObject();
- executionContext.stack.peek().getScopedObjects().put(name, obj);
- }
- return obj;
- }
-
- /** return null if not found */
- protected Object findScopedObject(String key) {
- Object obj = null;
- for (int i = stack.size() - 1; i >= 0; i--) {
- if (stack.get(i).getScopedObjects().containsKey(key)) {
- obj = stack.get(i).getScopedObjects().get(key);
- break;
- }
- }
- return obj;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- private static class ExecutionFlowRuntime {
- private final ExecutionFlow executionFlow;
- private final Map<String, Object> scopedObjects = new HashMap<String, Object>();
- private final Map<String, Object> localVariables = new HashMap<String, Object>();
- private final String uuid = UUID.randomUUID().toString();
-
- public ExecutionFlowRuntime(ExecutionFlow executionFlow) {
- this.executionFlow = executionFlow;
- }
-
- public ExecutionFlow getExecutionFlow() {
- return executionFlow;
- }
-
- public Map<String, Object> getScopedObjects() {
- return scopedObjects;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- public Map<String, Object> getLocalVariables() {
- return localVariables;
- }
-
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.springframework.context.ApplicationEvent;
-
-public class ExecutionFinishedEvent extends ApplicationEvent {
- static final long serialVersionUID = 012;
-
- private final ExecutionContext executionContext;
-
- public ExecutionFinishedEvent(Object source, ExecutionContext executionContext) {
- super(source);
- this.executionContext = executionContext;
- }
-
- public ExecutionContext getExecutionContext() {
- return executionContext;
- }
-
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.util.Map;
-
-import org.argeo.slc.process.Executable;
-
-public interface ExecutionFlow extends Executable{
- public Object getParameter(String name);
- public ExecutionSpec getExecutionSpec();
- public String getUuid();
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.argeo.slc.process.Executable;
-
-public class ExecutionFlowFactory {
- private List<Executable> executables = new ArrayList<Executable>();
-
-
- public ExecutionFlow createExecutionFlow(Map<String, Object> attributes){
- SimpleExecutionFlow executionFlow = new SimpleExecutionFlow();
- executionFlow.setExecutables(executables);
- return executionFlow;
- }
-
-
- public void setExecutables(List<Executable> executables) {
- this.executables = executables;
- }
-
-
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.beans.PropertyDescriptor;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.PropertyValue;
-import org.springframework.beans.PropertyValues;
-import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
-import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
-import org.springframework.beans.factory.config.TypedStringValue;
-
-public class ExecutionParameterPostProcessor extends
- InstantiationAwareBeanPostProcessorAdapter {
- private final static Log log = LogFactory
- .getLog(ExecutionParameterPostProcessor.class);
-
- private String placeholderPrefix = "@{";
- private String placeholderSuffix = "}";
- private String nullValue;
-
- @Override
- public PropertyValues postProcessPropertyValues(PropertyValues pvs,
- PropertyDescriptor[] pds, Object bean, String beanName)
- throws BeansException {
- if (!ExecutionContext.isExecuting())
- return pvs;
-
-// ExecutionFlow currentFlow = ExecutionContext.getCurrentFlow();
-//
-// Properties props = new Properties();
-// Map<String, Object> attributes = currentFlow.getAttributes();
-// Map<String, ExecutionSpecAttribute> specAttributes = currentFlow
-// .getExecutionSpec().getAttributes();
-//
-// for (String key : specAttributes.keySet()) {
-// ExecutionSpecAttribute obj = specAttributes.get(key);
-// if (!(obj instanceof RefSpecAttribute)) {
-// if (!attributes.containsKey(key))
-// throw new SlcException("Specified attribute " + key
-// + " is not set in " + currentFlow);
-//
-// props.setProperty(key, attributes.get(key).toString());
-// // if (log.isTraceEnabled())
-// // log.trace("Use attribute " + key);
-// }
-// }
-
- Properties props = new Properties();
- CustomPpc ppc = new CustomPpc(props);
-
- for (PropertyValue pv : pvs.getPropertyValues()) {
- if (pv.getValue() instanceof TypedStringValue) {
- TypedStringValue tsv = (TypedStringValue) pv.getValue();
- String originalValue = tsv.getValue();
- String convertedValue = ppc.process(originalValue);
- tsv.setValue(convertedValue);
- if (log.isTraceEnabled()) {
- if (!originalValue.equals(convertedValue))
- log.trace("Converted field '" + pv.getName() + "': '"
- + originalValue + "' to '" + convertedValue
- + "' in bean " + beanName);
- }
- } else {
- // if (log.isTraceEnabled())
- // log.trace(beanName + "[" + pv.getName() + "]: "
- // + pv.getValue().getClass());
- }
- }
-
- return pvs;
- }
-
- public void setPlaceholderPrefix(String placeholderPrefix) {
- this.placeholderPrefix = placeholderPrefix;
- }
-
- public void setPlaceholderSuffix(String placeholderSuffix) {
- this.placeholderSuffix = placeholderSuffix;
- }
-
- public void setNullValue(String nullValue) {
- this.nullValue = nullValue;
- }
-
- private class CustomPpc extends PropertyPlaceholderConfigurer {
- private final Properties props;
-
- public CustomPpc(Properties props) {
- super();
- this.props = props;
- setPlaceholderPrefix(placeholderPrefix);
- setPlaceholderSuffix(placeholderSuffix);
- setSystemPropertiesMode(SYSTEM_PROPERTIES_MODE_NEVER);
- }
-
- public String process(String strVal) {
- String value = parseStringValue(strVal, this.props,
- new HashSet<String>());
- return (value.equals(nullValue) ? null : value);
- }
-
- @Override
- protected String resolvePlaceholder(String placeholder, Properties props) {
- if (ExecutionContext.isExecuting())
- return ExecutionContext.getVariable(placeholder).toString();
- else if (SimpleExecutionSpec.isInFlowInitialization())
- return SimpleExecutionSpec.getInitializingFlowParameter(
- placeholder).toString();
- else
- return super.resolvePlaceholder(placeholder, props);
- }
-
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class ExecutionRegister implements InitializingBean {
- private final static Log log = LogFactory.getLog(ExecutionRegister.class);
-
- @Autowired
- private Set<ExecutionFlow> executionFlows;
-
- @Autowired
- private Set<ExecutionSpec> executionSpecs;
-
- public void afterPropertiesSet() throws Exception {
- log.debug("Register: " + executionSpecs.size() + " specs");
- for (ExecutionSpec spec : executionSpecs) {
- log.debug(spec);
- Map<String, ExecutionSpecAttribute> attributes = spec
- .getAttributes();
- log.debug("Spec attributes: ");
- for (String key : attributes.keySet()) {
- log.debug(" " + key + "\t" + attributes.get(key));
- }
- }
-
- log.debug("Register: " + executionFlows.size() + " flows");
- for (ExecutionFlow flow : executionFlows) {
- log.debug(flow);
-// Map<String, Object> attributes = flow.getAttributes();
-// log.debug("Specified parameters: ");
-// for (String key : flow.getExecutionSpec().getAttributes().keySet()) {
-// log.debug(" "
-// + key
-// + "\t"
-// + (attributes.containsKey(key) ? "SPECIFIED"
-// : "TO SPECIFY"));
-// }
- }
-
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.beans.factory.ObjectFactory;
-import org.springframework.beans.factory.config.Scope;
-
-public class ExecutionScope implements Scope {
- private final static Log log = LogFactory.getLog(ExecutionScope.class);
-
- public Object get(String name, ObjectFactory objectFactory) {
-
- if (log.isTraceEnabled())
- log.trace("Getting scoped bean " + name);
- return ExecutionContext.findOrAddScopedObject(name, objectFactory);
-
- // if (ExecutionContext.getScopedObjects().containsKey(name)) {
- // // returns cached instance
- // Object obj = ExecutionContext.getScopedObjects().get(name);
- // if (log.isTraceEnabled())
- // log.trace("Return cached scoped object " + obj);
- // return obj;
- // } else {
- // // creates instance
- // Object obj = objectFactory.getObject();
- // ExecutionContext.getScopedObjects().put(name, obj);
- // if (log.isTraceEnabled())
- // log.trace("Created regular scoped object " + obj);
- // return obj;
- // }
- }
-
- public String getConversationId() {
- return ExecutionContext.getCurrentStackUuid();
- }
-
- public void registerDestructionCallback(String name, Runnable callback) {
- throw new UnsupportedOperationException();
- }
-
- public Object remove(String name) {
- log.debug("Remove object " + name);
- throw new UnsupportedOperationException();
- }
-
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.util.Map;
-
-public interface ExecutionSpec {
- public Map<String, ExecutionSpecAttribute> getAttributes();
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-public interface ExecutionSpecAttribute {
- public Object getValue();
- public Boolean getIsParameter();
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.aop.TargetSource;
-
-public class ExecutionTargetSource implements TargetSource {
- private final static Log log = LogFactory
- .getLog(ExecutionTargetSource.class);
-
- private final String name;
- private final Class<?> targetClass;
- private final ExecutionFlow executionFlow;
-
- public ExecutionTargetSource(ExecutionFlow executionFlow,
- Class<?> targetClass, String name) {
- this.executionFlow = executionFlow;
- this.targetClass = targetClass;
- this.name = name;
- }
-
- public Object getTarget() throws Exception {
- if (log.isTraceEnabled())
- log.trace("Getting object " + name);
- Object obj = executionFlow.getParameter(name);
- if (log.isTraceEnabled())
- log.trace("Target object " + obj);
- return obj;
- }
-
- public Class getTargetClass() {
- return targetClass;
- }
-
- public boolean isStatic() {
- return false;
- }
-
- public void releaseTarget(Object target) throws Exception {
- // TODO Auto-generated method stub
-
- }
-
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.process.SlcExecution;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ApplicationEvent;
-import org.springframework.context.ApplicationListener;
-
-public class Executor implements ApplicationListener, ApplicationContextAware {
- private final static Log log = LogFactory.getLog(Executor.class);
-
- private ApplicationContext applicationContext;
-
- public void onApplicationEvent(ApplicationEvent event) {
- if (event instanceof NewExecutionEvent) {
- SlcExecution slcExecution = ((NewExecutionEvent) event)
- .getSlcExecution();
- ExecutionContext executionContext = new ExecutionContext();
- ExecutionThread thread = new ExecutionThread(executionContext,
- slcExecution);
- thread.start();
- }
-
- }
-
- public void setApplicationContext(ApplicationContext applicationContext)
- throws BeansException {
- this.applicationContext = applicationContext;
- }
-
- private class ExecutionThread extends Thread {
- private final SlcExecution slcExecution;
- private final ExecutionContext executionContext;
-
- public ExecutionThread(ExecutionContext executionContext,
- SlcExecution slcExecution) {
- super("SLC Execution #" + executionContext.getUuid());
- this.slcExecution = slcExecution;
- this.executionContext = executionContext;
- }
-
- public void run() {
- // Initialize from SlcExecution
- ExecutionContext.registerExecutionContext(executionContext);
- ExecutionContext.getVariables()
- .putAll(slcExecution.getAttributes());
-
- try {
- log.info("Start execution #"
- + ExecutionContext.getExecutionUuid());
- String executionBean = slcExecution.getAttributes().get(
- "slc.flows");
- ExecutionFlow main = (ExecutionFlow) applicationContext
- .getBean(executionBean);
- main.execute();
- } catch (Exception e) {
- log.error("Execution " + executionContext.getUuid()
- + " failed.", e);
- } finally {
- applicationContext.publishEvent(new ExecutionFinishedEvent(
- this, executionContext));
- }
-
- }
- }
-
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
-
-public class InstantiationPostProcessor extends
- InstantiationAwareBeanPostProcessorAdapter {
- private final static Log log = LogFactory
- .getLog(InstantiationPostProcessor.class);
-
- @Override
- public boolean postProcessAfterInstantiation(Object bean, String beanName)
- throws BeansException {
- if (bean instanceof ExecutionFlow)
- SimpleExecutionSpec.flowInitializationStarted((ExecutionFlow) bean);
- return true;
- }
-
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName)
- throws BeansException {
- if (bean instanceof ExecutionFlow)
- SimpleExecutionSpec
- .flowInitializationFinished((ExecutionFlow) bean);
- return bean;
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import org.argeo.slc.process.SlcExecution;
-import org.springframework.context.ApplicationEvent;
-
-public class NewExecutionEvent extends ApplicationEvent {
- static final long serialVersionUID = 012;
-
- private final SlcExecution slcExecution;
-
- public NewExecutionEvent(Object source, SlcExecution slcExecution) {
- super(source);
- this.slcExecution = slcExecution;
- }
-
- public SlcExecution getSlcExecution() {
- return slcExecution;
- }
-
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-public class RefSpecAttribute extends AbstractSpecAttribute {
- private Class targetClass;
- private Object value = null;
-
- public Object getValue() {
- return value;
- }
-
- public void setValue(Object value) {
- this.value = value;
- }
-
- public Class getTargetClass() {
- return targetClass;
- }
-
- public void setTargetClass(Class targetClass) {
- this.targetClass = targetClass;
- }
-
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.apache.commons.lang.math.RandomUtils;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.process.Executable;
-import org.argeo.slc.test.ExecutableTestRun;
-import org.springframework.beans.factory.BeanNameAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.validation.MapBindingResult;
-
-public class SimpleExecutionFlow implements ExecutionFlow, InitializingBean,
- BeanNameAware {
- private ExecutionSpec executionSpec = new SimpleExecutionSpec();
- private String name = null;
- private Map<String, Object> parameters = new HashMap<String, Object>();
- private List<Executable> executables = new ArrayList<Executable>();
-
- private final String uuid = UUID.randomUUID().toString();
-
- public void execute() {
- for (Executable executable : executables) {
- executable.execute();
- }
- }
-
- public void afterPropertiesSet() throws Exception {
- // Validate execution specs
- if (executionSpec == null)
- return;
-
- MapBindingResult errors = new MapBindingResult(parameters, "execution#"
- + getUuid());
- for (String key : executionSpec.getAttributes().keySet()) {
- ExecutionSpecAttribute executionSpecAttr = executionSpec
- .getAttributes().get(key);
- if (!parameters.containsKey(key)) {
- Object defaultValue = executionSpecAttr.getValue();
- if (defaultValue == null)
- errors.rejectValue(key, "Not set and no default value");
- else
- parameters.put(key, defaultValue);
- } else {// contains key
- Object obj = parameters.get(key);
- if (executionSpecAttr instanceof RefSpecAttribute) {
- RefSpecAttribute rsa = (RefSpecAttribute) executionSpecAttr;
- Class targetClass = rsa.getTargetClass();
- if (!targetClass.isAssignableFrom(obj.getClass())) {
- errors.reject(key
- + " not compatible with target class "
- + targetClass);
- }
- }
- }
- }
-
- if (errors.hasErrors())
- throw new SlcException("Could not prepare execution flow: "
- + errors.toString());
- }
-
- public void setBeanName(String name) {
- this.name = name;
- }
-
- public void setExecutables(List<Executable> executables) {
- this.executables = executables;
- }
-
- public void setExecutionSpec(ExecutionSpec executionSpec) {
- this.executionSpec = executionSpec;
- }
-
- public void setParameters(Map<String, Object> attributes) {
- this.parameters = attributes;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- public ExecutionSpec getExecutionSpec() {
- return executionSpec;
- }
-
- public Object getParameter(String name) {
- if (parameters.containsKey(name)) {
- return parameters.get(name);
- } else {
- if (executionSpec.getAttributes().containsKey(name)) {
- ExecutionSpecAttribute esa = executionSpec.getAttributes().get(
- name);
- if (esa.getValue() != null)
- return esa.getValue();
- } else {
- throw new SlcException("Key " + name
- + " is not define in the specifications of "
- + toString());
- }
- }
- throw new SlcException("Key " + name + " is not set as parameter in "
- + toString());
- }
-
- public String toString() {
- return new StringBuffer("Flow ").append(name).toString();// .append(" [#")
- // .append(uuid).append(']').toString();
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.argeo.slc.SlcException;
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.beans.factory.BeanNameAware;
-
-public class SimpleExecutionSpec implements ExecutionSpec, BeanNameAware {
- private final static ThreadLocal<ExecutionFlow> initializingFlow = new ThreadLocal<ExecutionFlow>();
-
- private Map<String, ExecutionSpecAttribute> attributes = new HashMap<String, ExecutionSpecAttribute>();
-
- private String name = null;
-
- public Map<String, ExecutionSpecAttribute> getAttributes() {
- return attributes;
- }
-
- public void setAttributes(Map<String, ExecutionSpecAttribute> attributes) {
- this.attributes = attributes;
- }
-
- public Object createRef(String name) {
- ExecutionFlow flow = initializingFlow.get();
- if (flow == null)
- throw new SlcException("No flow is currently initializing."
- + " Declare flow refs as inner beans or prototypes.");
-
- RefSpecAttribute refSpecAttribute = (RefSpecAttribute) attributes
- .get(name);
- Class<?> targetClass = refSpecAttribute.getTargetClass();
- ExecutionTargetSource targetSource = new ExecutionTargetSource(flow,
- targetClass, name);
- ProxyFactory proxyFactory = new ProxyFactory();
- proxyFactory.setTargetClass(targetClass);
- proxyFactory.setProxyTargetClass(true);
- proxyFactory.setTargetSource(targetSource);
-
- return proxyFactory.getProxy();
- }
-
- public void setBeanName(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public static void flowInitializationStarted(ExecutionFlow flow) {
- initializingFlow.set(flow);
- }
-
- public static void flowInitializationFinished(ExecutionFlow flow) {
- ExecutionFlow registeredFlow = initializingFlow.get();
- if (registeredFlow == null)
- throw new SlcException("No flow registered");
- if (!flow.getUuid().equals(registeredFlow.getUuid()))
- throw new SlcException("Current flow is " + flow);
- initializingFlow.set(null);
- }
-
- public static Object getInitializingFlowParameter(String key) {
- if (initializingFlow.get() == null)
- throw new SlcException("No initializing flow available.");
- return initializingFlow.get().getParameter(key);
- }
-
- public static Boolean isInFlowInitialization() {
- return initializingFlow.get() != null;
- }
-}
+++ /dev/null
-package org.argeo.slc.executionflow;
-
-public class SimpleSpecAttribute extends AbstractSpecAttribute {
- private Object value = null;
-
- public Object getValue() {
- return value;
- }
-
- public void setValue(Object value) {
- this.value = value;
- }
-}
\r
<import resource="common.xml" />\r
\r
- <bean id="basic.executionSpec" class="org.argeo.slc.executionflow.SimpleExecutionSpec">\r
+ <bean id="basic.executionSpec" class="org.argeo.slc.execution.SimpleExecutionSpec">\r
<property name="attributes">\r
<map>\r
<entry key="testedComponentId">\r
<bean id="basic.ref" factory-bean="basic.executionSpec"\r
factory-method="createRef" abstract="true" />\r
\r
- <bean id="basic.executionFlowTemplate" class="org.argeo.slc.executionflow.SimpleExecutionFlow"\r
+ <bean id="basic.executionFlowTemplate" class="org.argeo.slc.execution.SimpleExecutionFlow"\r
abstract="true">\r
<property name="executionSpec" ref="basic.executionSpec" />\r
<property name="executables">\r
<import\r
resource="classpath:/org/argeo/slc/core/test/spring/applicationContext.xml" />\r
\r
- <bean id="specAttribute" class="org.argeo.slc.executionflow.SimpleSpecAttribute"\r
+ <bean id="specAttribute" class="org.argeo.slc.execution.SimpleSpecAttribute"\r
abstract="true" />\r
\r
- <bean id="refAttribute" class="org.argeo.slc.executionflow.RefSpecAttribute"\r
+ <bean id="refAttribute" class="org.argeo.slc.execution.RefSpecAttribute"\r
abstract="true" />\r
\r
</beans>
\ No newline at end of file
<import resource="testCases/basic-001.xml" />\r
<import resource="testCases/basic-002.xml" />\r
\r
- <bean id="main" class="org.argeo.slc.executionflow.SimpleExecutionFlow">\r
+ <bean id="main" class="org.argeo.slc.execution.SimpleExecutionFlow">\r
<property name="executionSpec">\r
- <bean class="org.argeo.slc.executionflow.SimpleExecutionSpec">\r
+ <bean class="org.argeo.slc.execution.SimpleExecutionSpec">\r
<property name="attributes">\r
<map>\r
<entry key="testKey">\r
</bean>\r
\r
<context:annotation-config />\r
- <bean class="org.argeo.slc.executionflow.ExecutionRegister" />\r
+ <bean class="org.argeo.slc.execution.ExecutionRegister" />\r
\r
\r
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">\r
<property name="scopes">\r
<map>\r
<entry key="execution">\r
- <bean class="org.argeo.slc.executionflow.ExecutionScope" />\r
+ <bean class="org.argeo.slc.execution.ExecutionScope" />\r
</entry>\r
</map>\r
</property>\r
\r
<bean\r
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />\r
- <bean class="org.argeo.slc.executionflow.ExecutionParameterPostProcessor" />\r
- <bean class="org.argeo.slc.executionflow.InstantiationPostProcessor" />\r
- <bean class="org.argeo.slc.executionflow.Executor" />\r
+ <bean class="org.argeo.slc.execution.ExecutionParameterPostProcessor" />\r
+ <bean class="org.argeo.slc.execution.InstantiationPostProcessor" />\r
+ <bean class="org.argeo.slc.execution.Executor" />\r
\r
- <bean class="org.argeo.slc.executionflow.ExecutionAspect"></bean>\r
+ <bean class="org.argeo.slc.execution.ExecutionAspect"></bean>\r
<aop:aspectj-autoproxy />\r
\r
</beans>
\ No newline at end of file