]> git.argeo.org Git - gpl/argeo-slc.git/commitdiff
Implement ref spec
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 2 Jul 2009 16:43:16 +0000 (16:43 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 2 Jul 2009 16:43:16 +0000 (16:43 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@2673 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

24 files changed:
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultDescriptorConverter.java [deleted file]
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java [new file with mode: 0644]
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionSpec.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefSpecAttribute.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValue.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValueChoice.java [new file with mode: 0644]
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ExecutionThread.java [new file with mode: 0644]
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ProcessThread.java [new file with mode: 0644]
runtime/org.argeo.slc.core/src/main/resources/org/argeo/slc/core/execution/spring.xml
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/DynamicRuntime.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModularDeployedSystem.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java [new file with mode: 0644]
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java [new file with mode: 0644]
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptor.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptorConverter.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModuleDescriptor.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpec.java
runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/execution.xml
runtime/org.argeo.slc.support.castor/src/test/java/org/argeo/slc/castor/ExecutionModuleDescriptorCastorTest.java
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java
runtime/org.argeo.slc.support.osgi/src/main/resources/org/argeo/slc/osgi/execution/spring.xml
runtime/org.argeo.slc.unit/src/main/java/org/argeo/slc/unit/execution/ExecutionFlowDescriptorTestUtils.java

index 4722280d9f28663610084e58807b6fd5a40a0e8f..5fa0d015f896fc2014538f9952084aa6529fb901 100644 (file)
@@ -1,39 +1,22 @@
 package org.argeo.slc.core.execution;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.execution.ExecutionFlow;
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionModuleDescriptor;
+
+import org.argeo.slc.core.execution.internal.ProcessThread;
 import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.execution.ExecutionSpec;
-import org.argeo.slc.execution.ExecutionSpecAttribute;
-import org.argeo.slc.process.RealizedFlow;
 import org.argeo.slc.process.SlcExecution;
 import org.argeo.slc.process.SlcExecutionNotifier;
-import org.argeo.slc.process.SlcExecutionStep;
-import org.springframework.aop.scope.ScopedObject;
-import org.springframework.util.Assert;
 
 public abstract class AbstractExecutionModulesManager implements
                ExecutionModulesManager {
-       private final static Log log = LogFactory
-                       .getLog(AbstractExecutionModulesManager.class);
-
        private List<SlcExecutionNotifier> slcExecutionNotifiers = new ArrayList<SlcExecutionNotifier>();
        private ThreadGroup processesThreadGroup = new ThreadGroup("Processes");
 
        public void process(SlcExecution slcExecution) {
-               new ProcessThread(processesThreadGroup, slcExecution).start();
+               new ProcessThread(this, slcExecution).start();
        }
-
+/*
        protected void dispatchUpdateStatus(SlcExecution slcExecution,
                        String oldStatus, String newStatus) {
                for (Iterator<SlcExecutionNotifier> it = slcExecutionNotifiers
@@ -51,21 +34,16 @@ public abstract class AbstractExecutionModulesManager implements
                                .iterator(); it.hasNext();) {
                        it.next().addSteps(slcExecution, steps);
                }
-       }
+       }*/
 
        public void setSlcExecutionNotifiers(
                        List<SlcExecutionNotifier> slcExecutionNotifiers) {
                this.slcExecutionNotifiers = slcExecutionNotifiers;
        }
-
-       protected static ExecutionModuleDescriptor createDescriptor(
-                       String moduleName, String moduleVersion,
+/*
+       protected static void addFlowsToDescriptor(ExecutionModuleDescriptor md,
                        Map<String, ExecutionFlow> executionFlows) {
                // TODO: put this in a separate configurable object
-               ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
-               md.setName(moduleName);
-               md.setVersion(moduleVersion);
-
                for (String name : executionFlows.keySet()) {
                        ExecutionFlow executionFlow = executionFlows.get(name);
 
@@ -120,103 +98,81 @@ public abstract class AbstractExecutionModulesManager implements
                        // Add execution flow
                        md.getExecutionFlows().add(efd);
                }
-
-               return md;
        }
-
-       /** Thread of the SLC Process, starting the sub executions. */
-       private class ProcessThread extends Thread {
-               private final SlcExecution slcProcess;
-               private final ThreadGroup processThreadGroup;
-               private final List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
-
-               public ProcessThread(ThreadGroup processesThreadGroup,
-                               SlcExecution slcExecution) {
-                       super(processesThreadGroup, "SLC Process #"
-                                       + slcExecution.getUuid());
-                       this.slcProcess = slcExecution;
-                       processThreadGroup = new ThreadGroup("SLC Process #"
-                                       + slcExecution.getUuid() + " thread group");
-               }
-
-               public void run() {
-                       log.info("\n##\n## Process SLC Execution " + slcProcess + "\n##\n");
-
-                       slcProcess.setStatus(SlcExecution.STATUS_RUNNING);
-                       dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED,
-                                       SlcExecution.STATUS_RUNNING);
-
-                       flowsToProcess.addAll(slcProcess.getRealizedFlows());
-
-                       while (flowsToProcess.size() > 0) {
-                               RealizedFlow flow = flowsToProcess.remove(0);
-                               ExecutionThread thread = new ExecutionThread(this, flow);
-                               thread.start();
-
-                               synchronized (this) {
-                                       try {
-                                               wait();
-                                       } catch (InterruptedException e) {
-                                               // silent
-                                       }
-                               }
-                       }
-
-                       slcProcess.setStatus(SlcExecution.STATUS_FINISHED);
-                       dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING,
-                                       SlcExecution.STATUS_FINISHED);
-               }
-
-               public synchronized void flowCompleted() {
-                       notifyAll();
-               }
-
-               public SlcExecution getSlcProcess() {
-                       return slcProcess;
-               }
-
-               public ThreadGroup getProcessThreadGroup() {
-                       return processThreadGroup;
-               }
+*/
+       /**
+        * Thread of the SLC Process, starting the sub executions. private class
+        * ProcessThread extends Thread { private final SlcExecution slcProcess;
+        * private final ThreadGroup processThreadGroup; private final
+        * List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
+        * 
+        * public ProcessThread(ThreadGroup processesThreadGroup, SlcExecution
+        * slcExecution) { super(processesThreadGroup, "SLC Process #" +
+        * slcExecution.getUuid()); this.slcProcess = slcExecution;
+        * processThreadGroup = new ThreadGroup("SLC Process #" +
+        * slcExecution.getUuid() + " thread group"); }
+        * 
+        * public void run() { log.info("\n##\n## Process SLC Execution " +
+        * slcProcess + "\n##\n");
+        * 
+        * slcProcess.setStatus(SlcExecution.STATUS_RUNNING);
+        * dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED,
+        * SlcExecution.STATUS_RUNNING);
+        * 
+        * flowsToProcess.addAll(slcProcess.getRealizedFlows());
+        * 
+        * while (flowsToProcess.size() > 0) { RealizedFlow flow =
+        * flowsToProcess.remove(0); ExecutionThread thread = new
+        * ExecutionThread(this, flow); thread.start();
+        * 
+        * synchronized (this) { try { wait(); } catch (InterruptedException e) { //
+        * silent } } }
+        * 
+        * slcProcess.setStatus(SlcExecution.STATUS_FINISHED);
+        * dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING,
+        * SlcExecution.STATUS_FINISHED); }
+        * 
+        * public synchronized void flowCompleted() { notifyAll(); }
+        * 
+        * public SlcExecution getSlcProcess() { return slcProcess; }
+        * 
+        * public ThreadGroup getProcessThreadGroup() { return processThreadGroup; }
+        * }
+        */
+
+       /**
+        * Thread of a single execution private class ExecutionThread extends Thread
+        * { private final RealizedFlow realizedFlow; private final ProcessThread
+        * processThread;
+        * 
+        * public ExecutionThread(ProcessThread processThread, RealizedFlow
+        * realizedFlow) { super(processThread.getProcessThreadGroup(), "Flow " +
+        * realizedFlow.getFlowDescriptor().getName()); this.realizedFlow =
+        * realizedFlow; this.processThread = processThread; }
+        * 
+        * public void run() { ExecutionFlowDescriptor executionFlowDescriptor =
+        * realizedFlow .getFlowDescriptor(); String flowName =
+        * executionFlowDescriptor.getName();
+        * 
+        * dispatchAddStep(processThread.getSlcProcess(), new
+        * SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_START, "Flow " + flowName));
+        * 
+        * try { execute(realizedFlow); } catch (Exception e) { // TODO: re-throw
+        * exception ? String msg = "Execution of flow " + flowName + " failed.";
+        * log.error(msg, e); dispatchAddStep(processThread.getSlcProcess(), new
+        * SlcExecutionStep(msg + " " + e.getMessage())); } finally {
+        * processThread.flowCompleted();
+        * dispatchAddStep(processThread.getSlcProcess(), new
+        * SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END, "Flow " + flowName)); }
+        * } }
+        */
+
+       public List<SlcExecutionNotifier> getSlcExecutionNotifiers() {
+               return slcExecutionNotifiers;
        }
 
-       /** Thread of a single execution */
-       private class ExecutionThread extends Thread {
-               private final RealizedFlow realizedFlow;
-               private final ProcessThread processThread;
-
-               public ExecutionThread(ProcessThread processThread,
-                               RealizedFlow realizedFlow) {
-                       super(processThread.getProcessThreadGroup(), "Flow "
-                                       + realizedFlow.getFlowDescriptor().getName());
-                       this.realizedFlow = realizedFlow;
-                       this.processThread = processThread;
-               }
-
-               public void run() {
-                       ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow
-                                       .getFlowDescriptor();
-                       String flowName = executionFlowDescriptor.getName();
-
-                       dispatchAddStep(processThread.getSlcProcess(),
-                                       new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_START,
-                                                       "Flow " + flowName));
-
-                       try {
-                               execute(realizedFlow);
-                       } catch (Exception e) {
-                               // TODO: re-throw exception ?
-                               String msg = "Execution of flow " + flowName + " failed.";
-                               log.error(msg, e);
-                               dispatchAddStep(processThread.getSlcProcess(),
-                                               new SlcExecutionStep(msg + " " + e.getMessage()));
-                       } finally {
-                               processThread.flowCompleted();
-                               dispatchAddStep(processThread.getSlcProcess(),
-                                               new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END,
-                                                               "Flow " + flowName));
-                       }
-               }
+       public ThreadGroup getProcessesThreadGroup() {
+               return processesThreadGroup;
        }
 
 }
diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultDescriptorConverter.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultDescriptorConverter.java
deleted file mode 100644 (file)
index 2ae1e36..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.argeo.slc.core.execution;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.argeo.slc.execution.ExecutionFlowDescriptor;
-import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
-
-public class DefaultDescriptorConverter implements
-               ExecutionFlowDescriptorConverter {
-
-       public Map<String, Object> convertValues(
-                       ExecutionFlowDescriptor executionFlowDescriptor) {
-               // convert the values of flow.getFlowDescriptor()
-               Map<String, Object> values = executionFlowDescriptor.getValues();
-
-               Map<String, Object> convertedValues = new HashMap<String, Object>();
-
-               if (values != null) {
-                       for (String key : values.keySet()) {
-                               Object value = values.get(key);
-                               if (value instanceof PrimitiveValue) {
-                                       PrimitiveValue primitiveValue = (PrimitiveValue) value;
-
-                                       // TODO: check that the class of the the
-                                       // primitiveValue.value
-                                       // matches
-                                       // the primitiveValue.type
-                                       convertedValues.put(key, primitiveValue.getValue());
-                               } else if (value instanceof RefValue) {
-                                       // not yet implemented
-                                       
-//                                     RefValue refValue = (RefValue) value;
-//                                     convertedValues.put(key, refValue.getLabel());
-                               }
-                       }
-               }
-               return convertedValues;
-       }
-
-}
diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java
new file mode 100644 (file)
index 0000000..2b540f3
--- /dev/null
@@ -0,0 +1,171 @@
+package org.argeo.slc.core.execution;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
+import org.argeo.slc.execution.ExecutionSpec;
+import org.argeo.slc.execution.ExecutionSpecAttribute;
+import org.springframework.aop.scope.ScopedObject;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.util.Assert;
+
+public class DefaultExecutionFlowDescriptorConverter implements
+               ExecutionFlowDescriptorConverter, ApplicationContextAware {
+       private final static Log log = LogFactory
+                       .getLog(DefaultExecutionFlowDescriptorConverter.class);
+
+       private ApplicationContext applicationContext;
+
+       public Map<String, Object> convertValues(
+                       ExecutionFlowDescriptor executionFlowDescriptor) {
+               // convert the values of flow.getFlowDescriptor()
+               Map<String, Object> values = executionFlowDescriptor.getValues();
+
+               Map<String, Object> convertedValues = new HashMap<String, Object>();
+
+               if (values != null) {
+                       for (String key : values.keySet()) {
+                               Object value = values.get(key);
+                               if (value instanceof PrimitiveValue) {
+                                       PrimitiveValue primitiveValue = (PrimitiveValue) value;
+
+                                       // TODO: check that the class of the the
+                                       // primitiveValue.value
+                                       // matches
+                                       // the primitiveValue.type
+                                       convertedValues.put(key, primitiveValue.getValue());
+                               } else if (value instanceof RefValue) {
+                                       // not yet implemented
+
+                                       // RefValue refValue = (RefValue) value;
+                                       // convertedValues.put(key, refValue.getLabel());
+                               }
+                       }
+               }
+               return convertedValues;
+       }
+
+       public void addFlowsToDescriptor(ExecutionModuleDescriptor md,
+                       Map<String, ExecutionFlow> executionFlows) {
+               for (String name : executionFlows.keySet()) {
+                       ExecutionFlow executionFlow = executionFlows.get(name);
+
+                       Assert.notNull(executionFlow.getName());
+                       Assert.state(name.equals(executionFlow.getName()));
+
+                       ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
+                       Assert.notNull(executionSpec);
+                       Assert.notNull(executionSpec.getName());
+
+                       Map<String, Object> values = new TreeMap<String, Object>();
+                       for (String key : executionSpec.getAttributes().keySet()) {
+                               ExecutionSpecAttribute attribute = executionSpec
+                                               .getAttributes().get(key);
+
+                               if (attribute instanceof PrimitiveSpecAttribute) {
+                                       if (executionFlow.isSetAsParameter(key)) {
+                                               Object value = executionFlow.getParameter(key);
+                                               PrimitiveValue primitiveValue = new PrimitiveValue();
+                                               primitiveValue
+                                                               .setType(((PrimitiveSpecAttribute) attribute)
+                                                                               .getType());
+                                               primitiveValue.setValue(value);
+                                               values.put(key, primitiveValue);
+                                       } else {
+                                               // no need to add a primitive value if it is not set,
+                                               // all necessary information is in the spec
+                                       }
+                               } else if (attribute instanceof RefSpecAttribute) {
+                                       values.put(key, buildRefValue((RefSpecAttribute) attribute,
+                                                       executionFlow, key));
+                               } else {
+                                       throw new SlcException("Unkown spec attribute type "
+                                                       + attribute.getClass());
+                               }
+
+                       }
+
+                       ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name,
+                                       values, executionSpec);
+                       if (executionFlow.getPath() != null)
+                               efd.setPath(executionFlow.getPath());
+
+                       // Add execution spec if necessary
+                       if (!md.getExecutionSpecs().contains(executionSpec))
+                               md.getExecutionSpecs().add(executionSpec);
+
+                       // Add execution flow
+                       md.getExecutionFlows().add(efd);
+               }
+       }
+
+       @SuppressWarnings(value = { "unchecked" })
+       protected RefValue buildRefValue(RefSpecAttribute rsa,
+                       ExecutionFlow executionFlow, String key) {
+               RefValue refValue = new RefValue();
+
+               if (executionFlow.isSetAsParameter(key)) {
+                       String ref = null;
+                       Object value = executionFlow.getParameter(key);
+                       if (applicationContext == null) {
+                               log
+                                               .warn("No application context declared, cannot scan ref value.");
+                               ref = value.toString();
+                       } else {
+
+                               // look for a ref to the value
+                               Map<String, Object> beans = getBeanFactory().getBeansOfType(
+                                               rsa.getTargetClass(), false, false);
+                               // TODO: also check scoped beans
+                               beans: for (String beanName : beans.keySet()) {
+                                       Object obj = beans.get(beanName);
+                                       if (value instanceof ScopedObject) {
+                                               // don't call methods of the target of the scope
+                                               if (obj instanceof ScopedObject)
+                                                       if (value == obj) {
+                                                               ref = beanName;
+                                                               break beans;
+                                                       }
+                                       } else {
+                                               if (obj.equals(value)) {
+                                                       ref = beanName;
+                                                       break beans;
+                                               }
+                                       }
+                               }
+                       }
+                       if (ref == null)
+                               log.warn("Cannot define reference for ref spec attribute "
+                                               + key);
+                       refValue.setRef(ref);
+               }
+               return refValue;
+       }
+
+       private ConfigurableListableBeanFactory getBeanFactory() {
+               return ((ConfigurableApplicationContext) applicationContext)
+                               .getBeanFactory();
+       }
+
+       /** Must be use within the execution application context */
+       public void setApplicationContext(ApplicationContext applicationContext)
+                       throws BeansException {
+               this.applicationContext = applicationContext;
+       }
+
+}
index bd427395824b4f50fd7f13a750afa910d3745035..af0afc416739211df779743d4e08b3434401e346 100644 (file)
@@ -1,14 +1,31 @@
 package org.argeo.slc.core.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.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.execution.ExecutionSpec;
 import org.argeo.slc.execution.ExecutionSpecAttribute;
 import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
 
-public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware {
+public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware,
+               ApplicationContextAware, InitializingBean {
+       private final static Log log = LogFactory
+                       .getLog(DefaultExecutionSpec.class);
+       private ApplicationContext applicationContext;
+
+       private String description;
        private Map<String, ExecutionSpecAttribute> attributes = new HashMap<String, ExecutionSpecAttribute>();
 
        private String name = getClass().getName() + "#" + UUID.randomUUID();
@@ -33,4 +50,56 @@ public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware {
                return ((ExecutionSpec) obj).getName().equals(name);
        }
 
+       public String getDescription() {
+               return description;
+       }
+
+       private ConfigurableListableBeanFactory getBeanFactory() {
+               return ((ConfigurableApplicationContext) applicationContext)
+                               .getBeanFactory();
+       }
+
+       public void setApplicationContext(ApplicationContext applicationContext) {
+               this.applicationContext = applicationContext;
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               if (description == null) {
+                       try {
+                               description = getBeanFactory().getBeanDefinition(name)
+                                               .getDescription();
+                       } catch (NoSuchBeanDefinitionException e) {
+                               // silent
+                       }
+               }
+
+               for (String key : attributes.keySet()) {
+                       ExecutionSpecAttribute attr = attributes.get(key);
+                       if (attr instanceof RefSpecAttribute) {
+                               RefSpecAttribute rsa = (RefSpecAttribute) attr;
+                               if (rsa.getChoices() == null) {
+                                       rsa.setChoices(buildRefValueChoices(rsa));
+                               }
+                       }
+               }
+       }
+
+       protected List<RefValueChoice> buildRefValueChoices(RefSpecAttribute rsa) {
+               List<RefValueChoice> choices = new ArrayList<RefValueChoice>();
+               if (applicationContext == null) {
+                       log.warn("No application context declared,"
+                                       + " cannot scan ref value choices.");
+                       return choices;
+               }
+
+               for (String beanName : getBeanFactory().getBeanNamesForType(
+                               rsa.getTargetClass(), true, false)) {
+                       BeanDefinition bd = getBeanFactory().getBeanDefinition(beanName);
+                       RefValueChoice choice = new RefValueChoice();
+                       choice.setName(beanName);
+                       choice.setDescription(bd.getDescription());
+               }
+               return choices;
+       }
+
 }
index 7cc59f1b99cce111d61e0c8eff97115bf9ee819f..eebb660400a12c31be9755227def1f6217663e0f 100644 (file)
@@ -1,11 +1,16 @@
 package org.argeo.slc.core.execution;
 
-public class RefSpecAttribute extends AbstractSpecAttribute {
+import java.util.List;
+
+public class RefSpecAttribute extends AbstractSpecAttribute implements
+               Cloneable {
        private Class<?> targetClass;
        /** Read only. */
        private String targetClassName;
        private Object value = null;
 
+       private List<RefValueChoice> choices = null;
+
        public Object getValue() {
                return value;
        }
@@ -27,4 +32,21 @@ public class RefSpecAttribute extends AbstractSpecAttribute {
                return targetClassName;
        }
 
+       /** @return can be null */
+       public List<RefValueChoice> getChoices() {
+               return choices;
+       }
+
+       public void setChoices(List<RefValueChoice> choices) {
+               this.choices = choices;
+       }
+
+       @Override
+       protected Object clone() throws CloneNotSupportedException {
+               RefSpecAttribute rsa = new RefSpecAttribute();
+               rsa.setTargetClass(targetClass);
+               rsa.setChoices(choices);
+               return rsa;
+       }
+
 }
index 516a15e3b301c4db9494ce39ba1346e6b9d07110..61abcb84940b9b374ad80e7053e7ea03a50e74ef 100644 (file)
@@ -1,22 +1,23 @@
 package org.argeo.slc.core.execution;
 
+
 public class RefValue extends AbstractExecutionValue {
-       private String label;
+       private String ref;
 
        public RefValue() {
        }
 
-       public RefValue(String label) {
+       public RefValue(String ref) {
                super();
-               this.label = label;
+               this.ref = ref;
        }
 
-       public String getLabel() {
-               return label;
+       public String getRef() {
+               return ref;
        }
 
-       public void setLabel(String label) {
-               this.label = label;
+       public void setRef(String ref) {
+               this.ref = ref;
        }
 
 }
diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValueChoice.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/RefValueChoice.java
new file mode 100644 (file)
index 0000000..6803a84
--- /dev/null
@@ -0,0 +1,31 @@
+package org.argeo.slc.core.execution;
+
+public class RefValueChoice {
+       private String name;
+       private String description;
+
+       public RefValueChoice() {
+       }
+
+       public RefValueChoice(String name, String description) {
+               this.name = name;
+               this.description = description;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ExecutionThread.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ExecutionThread.java
new file mode 100644 (file)
index 0000000..043f74b
--- /dev/null
@@ -0,0 +1,66 @@
+package org.argeo.slc.core.execution.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.process.RealizedFlow;
+import org.argeo.slc.process.SlcExecution;
+import org.argeo.slc.process.SlcExecutionNotifier;
+import org.argeo.slc.process.SlcExecutionStep;
+
+/** Thread of a single execution */
+public class ExecutionThread extends Thread {
+       private final static Log log = LogFactory.getLog(ExecutionThread.class);
+
+       private final RealizedFlow realizedFlow;
+       private final ProcessThread processThread;
+
+       public ExecutionThread(ProcessThread processThread,
+                       RealizedFlow realizedFlow) {
+               super(processThread.getProcessThreadGroup(), "Flow "
+                               + realizedFlow.getFlowDescriptor().getName());
+               this.realizedFlow = realizedFlow;
+               this.processThread = processThread;
+       }
+
+       public void run() {
+               ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow
+                               .getFlowDescriptor();
+               String flowName = executionFlowDescriptor.getName();
+
+               dispatchAddStep(processThread.getSlcProcess(), new SlcExecutionStep(
+                               SlcExecutionStep.TYPE_PHASE_START, "Flow " + flowName));
+
+               try {
+                       processThread.getExecutionModulesManager().execute(realizedFlow);
+               } catch (Exception e) {
+                       // TODO: re-throw exception ?
+                       String msg = "Execution of flow " + flowName + " failed.";
+                       log.error(msg, e);
+                       dispatchAddStep(processThread.getSlcProcess(),
+                                       new SlcExecutionStep(msg + " " + e.getMessage()));
+               } finally {
+                       processThread.flowCompleted();
+                       dispatchAddStep(processThread.getSlcProcess(),
+                                       new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END,
+                                                       "Flow " + flowName));
+               }
+       }
+
+       protected void dispatchAddStep(SlcExecution slcExecution,
+                       SlcExecutionStep step) {
+               slcExecution.getSteps().add(step);
+               List<SlcExecutionStep> steps = new ArrayList<SlcExecutionStep>();
+               steps.add(step);
+               for (Iterator<SlcExecutionNotifier> it = processThread
+                               .getExecutionModulesManager().getSlcExecutionNotifiers()
+                               .iterator(); it.hasNext();) {
+                       it.next().addSteps(slcExecution, steps);
+               }
+       }
+
+}
diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ProcessThread.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/internal/ProcessThread.java
new file mode 100644 (file)
index 0000000..0bfca64
--- /dev/null
@@ -0,0 +1,85 @@
+package org.argeo.slc.core.execution.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.core.execution.AbstractExecutionModulesManager;
+import org.argeo.slc.process.RealizedFlow;
+import org.argeo.slc.process.SlcExecution;
+import org.argeo.slc.process.SlcExecutionNotifier;
+
+/** Thread of the SLC Process, starting the sub executions. */
+public class ProcessThread extends Thread {
+       private final static Log log = LogFactory.getLog(ProcessThread.class);
+
+       private final AbstractExecutionModulesManager executionModulesManager;
+       private final SlcExecution slcProcess;
+       private final ThreadGroup processThreadGroup;
+       private final List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
+
+       public ProcessThread(
+                       AbstractExecutionModulesManager executionModulesManager,
+                       SlcExecution slcExecution) {
+               super(executionModulesManager.getProcessesThreadGroup(),
+                               "SLC Process #" + slcExecution.getUuid());
+               this.executionModulesManager = executionModulesManager;
+               this.slcProcess = slcExecution;
+               processThreadGroup = new ThreadGroup("SLC Process #"
+                               + slcExecution.getUuid() + " thread group");
+       }
+
+       public void run() {
+               log.info("\n##\n## Process SLC Execution " + slcProcess + "\n##\n");
+
+               slcProcess.setStatus(SlcExecution.STATUS_RUNNING);
+               dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED,
+                               SlcExecution.STATUS_RUNNING);
+
+               flowsToProcess.addAll(slcProcess.getRealizedFlows());
+
+               while (flowsToProcess.size() > 0) {
+                       RealizedFlow flow = flowsToProcess.remove(0);
+                       ExecutionThread thread = new ExecutionThread(this, flow);
+                       thread.start();
+
+                       synchronized (this) {
+                               try {
+                                       wait();
+                               } catch (InterruptedException e) {
+                                       // silent
+                               }
+                       }
+               }
+
+               slcProcess.setStatus(SlcExecution.STATUS_FINISHED);
+               dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING,
+                               SlcExecution.STATUS_FINISHED);
+       }
+
+       protected void dispatchUpdateStatus(SlcExecution slcExecution,
+                       String oldStatus, String newStatus) {
+               for (Iterator<SlcExecutionNotifier> it = executionModulesManager
+                               .getSlcExecutionNotifiers().iterator(); it.hasNext();) {
+                       it.next().updateStatus(slcExecution, oldStatus, newStatus);
+               }
+       }
+
+       public synchronized void flowCompleted() {
+               notifyAll();
+       }
+
+       public SlcExecution getSlcProcess() {
+               return slcProcess;
+       }
+
+       public ThreadGroup getProcessThreadGroup() {
+               return processThreadGroup;
+       }
+
+       public AbstractExecutionModulesManager getExecutionModulesManager() {
+               return executionModulesManager;
+       }
+}
index 6548f8a3c8ba17e574d43ae22efbb1efdd46b59a..3188e58fdc7ff9a6f428123ba974e65f269a701c 100644 (file)
@@ -21,6 +21,9 @@
                <aop:scoped-proxy />
        </bean>
 
+       <bean id="executionFlowDescriptorConverter"
+               class="org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter"></bean>
+
        <bean
                class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
index 16d727a2cca137cc836c6d2505d10c11e649cad4..e2552732abebcb2d3f170f820df3095363287a58 100644 (file)
@@ -1,6 +1,5 @@
 package org.argeo.slc.deploy;
 
-@SuppressWarnings("unchecked")
 public interface DynamicRuntime<M extends Module> extends
                ModularDeployedSystem<M> {
        public void shutdown();
index 177fac83dd67248dc220b668b474630f08ee7507..18fd4fe6d8958436a54e30335b4f7391e50fdfe9 100644 (file)
@@ -2,7 +2,6 @@ package org.argeo.slc.deploy;
 
 import java.util.List;
 
-@SuppressWarnings("unchecked")
 public interface ModularDeployedSystem<M extends Module> extends DeployedSystem {
        /** List the underlying deployed modules (in real time) */
        public List<M> listModules();
diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModuleDescriptor.java
new file mode 100644 (file)
index 0000000..a3a101f
--- /dev/null
@@ -0,0 +1,28 @@
+package org.argeo.slc.deploy;
+
+import java.io.Serializable;
+
+import org.argeo.slc.build.BasicNameVersion;
+
+public class ModuleDescriptor extends BasicNameVersion implements Serializable {
+       private static final long serialVersionUID = 1L;
+       private String label;
+       private String description;
+
+       public String getLabel() {
+               return label;
+       }
+
+       public void setLabel(String label) {
+               this.label = label;
+       }
+
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/ModulesManager.java
new file mode 100644 (file)
index 0000000..93d325f
--- /dev/null
@@ -0,0 +1,15 @@
+package org.argeo.slc.deploy;
+
+import java.util.List;
+
+/** Provides access to modules */
+public interface ModulesManager {
+       /** @return a full fledged module descriptor. */
+       public ModuleDescriptor getModuleDescriptor(String moduleName,
+                       String version);
+
+       /**
+        * @return a list of minimal module descriptors
+        */
+       public List<ModuleDescriptor> listModules();
+}
index aeacfca187d59797c8ad6653f72faa6d65c3e39a..f63703c88e45f27c760083ad441dc5a49bad2f55 100644 (file)
@@ -4,6 +4,7 @@ import java.util.Map;
 
 public class ExecutionFlowDescriptor {
        private String name;
+       private String description;
        private String path;
        private Map<String, Object> values;
        private ExecutionSpec executionSpec;
@@ -50,4 +51,12 @@ public class ExecutionFlowDescriptor {
                this.executionSpec = executionSpec;
        }
 
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
 }
index 511d9da9b998fe6b993f319289339a2e9b599100..b33c94cdef96f5e08ea32c9c469d25ace0447f4a 100644 (file)
@@ -5,4 +5,7 @@ import java.util.Map;
 public interface ExecutionFlowDescriptorConverter {
        public Map<String, Object> convertValues(
                        ExecutionFlowDescriptor executionFlowDescriptor);
+
+       public void addFlowsToDescriptor(ExecutionModuleDescriptor md,
+                       Map<String, ExecutionFlow> executionFlows);
 }
index 555ef40d749ed768e8eaad726b57b0096a3e5e78..3aa28e690a561731f838e7499a7e8c46fdf6c1a8 100644 (file)
@@ -1,15 +1,13 @@
 package org.argeo.slc.execution;
 
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.argeo.slc.SlcException;
+import org.argeo.slc.deploy.ModuleDescriptor;
 
-public class ExecutionModuleDescriptor implements Serializable {
+public class ExecutionModuleDescriptor extends ModuleDescriptor {
        private static final long serialVersionUID = 1L;
-       private String name;
-       private String version;
+
        private List<ExecutionSpec> executionSpecs = new ArrayList<ExecutionSpec>();
        private List<ExecutionFlowDescriptor> executionFlows = new ArrayList<ExecutionFlowDescriptor>();
 
@@ -28,21 +26,4 @@ public class ExecutionModuleDescriptor implements Serializable {
        public void setExecutionFlows(List<ExecutionFlowDescriptor> executionFlows) {
                this.executionFlows = executionFlows;
        }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public String getVersion() {
-               return version;
-       }
-
-       public void setVersion(String version) {
-               this.version = version;
-       }
-
 }
index 66ddc9cf4c0da6327d95f858553e8d66e1f9f5eb..f1155cc8e7fad464490895cff329c3cb800a23f5 100644 (file)
@@ -2,11 +2,12 @@ package org.argeo.slc.execution;
 
 import java.util.List;
 
+import org.argeo.slc.deploy.ModulesManager;
 import org.argeo.slc.process.RealizedFlow;
 import org.argeo.slc.process.SlcExecution;
 
 /** Provides access to the execution modules */
-public interface ExecutionModulesManager {
+public interface ExecutionModulesManager extends ModulesManager {
        /** @return a full fledged module descriptor. */
        public ExecutionModuleDescriptor getExecutionModuleDescriptor(
                        String moduleName, String version);
index 60924768bb851bf9863f5623580c0afde1af0a62..c2c61daafd6945fc1b824f42b4164fd4e37af74d 100644 (file)
@@ -6,4 +6,6 @@ public interface ExecutionSpec {
        public Map<String, ExecutionSpecAttribute> getAttributes();
 
        public String getName();
+       
+       public String getDescription();
 }
index 7e903d26f3bdfcbd3d2d7416ca5ec4a1ed2a1df1..2fdfb7e4a43ca7cdaa30715686219288b58bac84 100644 (file)
@@ -10,6 +10,8 @@
                        ns-prefix="slc" />\r
                <field name="name" />\r
                <field name="version" />\r
+               <field name="label" />\r
+               <field name="description" />\r
                <field name="executionFlows" collection="arraylist"\r
                        type="org.argeo.slc.execution.ExecutionFlowDescriptor">\r
                        <bind-xml auto-naming="deriveByClass" location="execution-flows" />\r
                <field name="targetClassName">\r
                        <bind-xml name="targetClassName" node="attribute" />\r
                </field>\r
+               <field name="choices" collection="arraylist"\r
+                       type="org.argeo.slc.core.execution.RefValueChoice">\r
+                       <bind-xml auto-naming="deriveByClass" location="choices" />\r
+               </field>\r
        </class>\r
 \r
        <!-- Values -->\r
        <class name="org.argeo.slc.core.execution.RefValue" extends="org.argeo.slc.core.execution.AbstractExecutionValue">\r
                <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
                        ns-prefix="slc" />\r
-               <field name="label" />\r
+               <field name="ref">\r
+                       <bind-xml name="ref" node="attribute" />\r
+               </field>\r
+       </class>\r
+\r
+       <class name="org.argeo.slc.core.execution.RefValueChoice">\r
+               <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
+                       ns-prefix="slc" />\r
+               <field name="name">\r
+                       <bind-xml name="name" node="attribute" />\r
+               </field>\r
+               <field name="description" />\r
        </class>\r
 </mapping>
\ No newline at end of file
index 0ee30625664b6930da71e18d55c70ee3bd467995..09c6617eb82096973973ad25a3b5b326ff02a49d 100644 (file)
@@ -6,14 +6,15 @@ import java.util.List;
 import org.argeo.slc.execution.ExecutionFlowDescriptor;\r
 import org.argeo.slc.execution.ExecutionModuleDescriptor;\r
 import org.argeo.slc.execution.ExecutionSpec;\r
-import org.argeo.slc.msg.ObjectList;\r
 import org.argeo.slc.unit.execution.ExecutionFlowDescriptorTestUtils;\r
 \r
 public class ExecutionModuleDescriptorCastorTest extends AbstractCastorTestCase {\r
        public void testMarshUnmarsh() throws Exception {\r
                ExecutionModuleDescriptor moduleDescriptor = new ExecutionModuleDescriptor();\r
-               moduleDescriptor.setName("test.moodule");\r
+               moduleDescriptor.setName("test.module");\r
                moduleDescriptor.setVersion("1.0.0");\r
+               moduleDescriptor.setLabel("Test Module");\r
+               moduleDescriptor.setDescription("module descriptor");\r
 \r
                ExecutionFlowDescriptor flowDescriptor = ExecutionFlowDescriptorTestUtils\r
                                .createSimpleExecutionFlowDescriptor();\r
index 2d3ce046522023ecee79841ade540b5aadf0b603..5e61ddba08ad68aebb24dd56cb20d5be48435791 100644 (file)
@@ -9,13 +9,16 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.core.execution.AbstractExecutionModulesManager;
-import org.argeo.slc.core.execution.DefaultDescriptorConverter;
+import org.argeo.slc.core.execution.DefaultExecutionFlowDescriptorConverter;
+import org.argeo.slc.deploy.ModuleDescriptor;
 import org.argeo.slc.execution.ExecutionContext;
 import org.argeo.slc.execution.ExecutionFlow;
 import org.argeo.slc.execution.ExecutionFlowDescriptor;
 import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
 import org.argeo.slc.execution.ExecutionModuleDescriptor;
 import org.argeo.slc.process.RealizedFlow;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.util.tracker.ServiceTracker;
@@ -30,12 +33,17 @@ public class OsgiExecutionModulesManager extends
 
        private BundlesManager bundlesManager;
        private ServiceTracker executionContexts;
-       private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultDescriptorConverter();
+       private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultExecutionFlowDescriptorConverter();
 
        public ExecutionModuleDescriptor getExecutionModuleDescriptor(
                        String moduleName, String version) {
-               return createDescriptor(moduleName, version, listFlows(moduleName,
-                               version));
+               ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
+               md.setName(moduleName);
+               md.setVersion(version);
+               setMetadataFromBundle(md, null);
+               getExecutionFlowDescriptorConverter(moduleName, version)
+                               .addFlowsToDescriptor(md, listFlows(moduleName, version));
+               return md;
        }
 
        public List<ExecutionModuleDescriptor> listExecutionModules() {
@@ -43,12 +51,8 @@ public class OsgiExecutionModulesManager extends
 
                ServiceReference[] srs = executionContexts.getServiceReferences();
                for (ServiceReference sr : srs) {
-                       String moduleName = sr.getBundle().getSymbolicName();
-                       String moduleVersion = sr.getBundle().getHeaders().get(
-                                       "Bundle-Version").toString();
                        ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
-                       md.setName(moduleName);
-                       md.setVersion(moduleVersion);
+                       setMetadataFromBundle(md, sr.getBundle());
                        descriptors.add(md);
                }
                return descriptors;
@@ -164,6 +168,17 @@ public class OsgiExecutionModulesManager extends
                execute(realizedFlow);
        }
 
+       protected ExecutionFlowDescriptorConverter getExecutionFlowDescriptorConverter(
+                       String moduleName, String moduleVersion) {
+               // Check whether a descriptor converter is published by this module
+               ExecutionFlowDescriptorConverter descriptorConverter = findExecutionFlowDescriptorConverter(
+                               moduleName, moduleVersion);
+               if (descriptorConverter == null)
+                       return defaultDescriptorConverter;
+               else
+                       return descriptorConverter;
+       }
+
        public void execute(RealizedFlow realizedFlow) {
                if (log.isTraceEnabled())
                        log.trace("Executing " + realizedFlow);
@@ -171,18 +186,9 @@ public class OsgiExecutionModulesManager extends
                String moduleName = realizedFlow.getModuleName();
                String moduleVersion = realizedFlow.getModuleVersion();
 
-               // Check whether a descriptor converter is published by this module
-               ExecutionFlowDescriptorConverter descriptorConverter = findExecutionFlowDescriptorConverter(
-                               moduleName, moduleVersion);
-
-               final Map<? extends String, ? extends Object> variablesToAdd;
-               if (descriptorConverter != null)
-                       variablesToAdd = descriptorConverter.convertValues(realizedFlow
-                                       .getFlowDescriptor());
-               else
-                       variablesToAdd = defaultDescriptorConverter
-                                       .convertValues(realizedFlow.getFlowDescriptor());
-
+               Map<? extends String, ? extends Object> variablesToAdd = getExecutionFlowDescriptorConverter(
+                               moduleName, moduleVersion).convertValues(
+                               realizedFlow.getFlowDescriptor());
                ExecutionContext executionContext = findExecutionContext(moduleName,
                                moduleVersion);
                for (String key : variablesToAdd.keySet())
@@ -200,4 +206,54 @@ public class OsgiExecutionModulesManager extends
                //
        }
 
+       public ModuleDescriptor getModuleDescriptor(String moduleName,
+                       String version) {
+               return getExecutionModuleDescriptor(moduleName, version);
+       }
+
+       public List<ModuleDescriptor> listModules() {
+               Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
+               List<ModuleDescriptor> lst = new ArrayList<ModuleDescriptor>();
+               for (Bundle bundle : bundles) {
+                       ModuleDescriptor moduleDescriptor = new ModuleDescriptor();
+                       setMetadataFromBundle(moduleDescriptor, bundle);
+                       lst.add(moduleDescriptor);
+               }
+               return lst;
+       }
+
+       protected void setMetadataFromBundle(ModuleDescriptor md, Bundle bundle) {
+               Bundle bdl = bundle;
+               if (bdl == null) {
+                       if (md.getName() == null || md.getVersion() == null)
+                               throw new SlcException("Name and version not available.");
+
+                       Bundle[] bundles = bundlesManager.getBundleContext().getBundles();
+                       for (Bundle b : bundles) {
+                               if (b.getSymbolicName().equals(md.getName())
+                                               && md.getVersion().equals(
+                                                               getHeaderSafe(b, Constants.BUNDLE_VERSION))) {
+                                       bdl = b;
+                                       break;
+                               }
+                       }
+
+               }
+
+               if (bdl == null)
+                       throw new SlcException("Cannot find bundle.");
+
+               md.setName(bdl.getSymbolicName());
+               md.setVersion(getHeaderSafe(bdl, Constants.BUNDLE_VERSION));
+               md.setLabel(getHeaderSafe(bdl, Constants.BUNDLE_NAME));
+               md.setDescription(getHeaderSafe(bdl, Constants.BUNDLE_DESCRIPTION));
+       }
+
+       private String getHeaderSafe(Bundle bundle, Object key) {
+               Object obj = bundle.getHeaders().get(key);
+               if (obj == null)
+                       return null;
+               else
+                       return obj.toString();
+       }
 }
index 32de167505361d6f273b4eb0e5820b05617b490d..f64b0abfb5d986504c7433c8c6e900bb26491317 100644 (file)
@@ -8,6 +8,8 @@
 
        <osgi:service interface="org.argeo.slc.execution.ExecutionContext"
                ref="executionContext" />
+       <osgi:service interface="org.argeo.slc.execution.ExecutionFlowDescriptorConverter"
+               ref="executionFlowDescriptorConverter" />
 
        <bean class="org.argeo.slc.osgi.MultipleServiceExporterPostProcessor">
                <property name="interfaces">
index 14a34c7fbee9dc4992c0c6aff37fdb0aa3d22879..d2aaf5810b8c676971c2a8a449ad5480e3400e0d 100644 (file)
@@ -1,14 +1,15 @@
 package org.argeo.slc.unit.execution;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.argeo.slc.core.deploy.SimpleExecutables;
 import org.argeo.slc.core.execution.DefaultExecutionSpec;
 import org.argeo.slc.core.execution.PrimitiveSpecAttribute;
 import org.argeo.slc.core.execution.PrimitiveValue;
 import org.argeo.slc.core.execution.RefSpecAttribute;
 import org.argeo.slc.core.execution.RefValue;
+import org.argeo.slc.core.execution.RefValueChoice;
 import org.argeo.slc.core.test.BasicTestData;
 import org.argeo.slc.execution.ExecutionFlowDescriptor;
 import org.argeo.slc.execution.ExecutionSpecAttribute;
@@ -17,10 +18,14 @@ public class ExecutionFlowDescriptorTestUtils {
        public static ExecutionFlowDescriptor createSimpleExecutionFlowDescriptor() {
                ExecutionFlowDescriptor flowDescriptor = new ExecutionFlowDescriptor();
                flowDescriptor.setName("simpleFlow");
+               flowDescriptor.setDescription("my description");
+
                Map<String, Object> values = new HashMap<String, Object>();
                values.put("primitiveInteger", new PrimitiveValue(
                                PrimitiveSpecAttribute.TYPE_INTEGER, 100));
-               values.put("ref1", new RefValue("Just a label"));
+
+               RefValue refValue = new RefValue("002");
+               values.put("ref1", refValue);
                flowDescriptor.setValues(values);
 
                flowDescriptor.setExecutionSpec(createRelatedSimpleSpec());
@@ -39,6 +44,10 @@ public class ExecutionFlowDescriptorTestUtils {
 
                RefSpecAttribute ref1 = new RefSpecAttribute();
                ref1.setTargetClass(BasicTestData.class);
+               ref1.setChoices(new ArrayList<RefValueChoice>());
+               ref1.getChoices().add(new RefValueChoice("001", "desc"));
+               ref1.getChoices().add(new RefValueChoice("002", null));
+               ref1.getChoices().add(new RefValueChoice("003", null));
                attributes.put("ref1", ref1);
 
                spec.setAttributes(attributes);