]> git.argeo.org Git - gpl/argeo-slc.git/commitdiff
Flows automatically registered in JCR
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 17 Apr 2011 07:59:36 +0000 (07:59 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 17 Apr 2011 07:59:36 +0000 (07:59 +0000)
NEW - bug 17: Generalize agent management and registration beyond JMS
https://bugzilla.argeo.org/show_bug.cgi?id=17

git-svn-id: https://svn.argeo.org/slc/trunk@4444 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

14 files changed:
demo/log4j.properties
demo/slc_demo_rcp.properties
modules/agent/org.argeo.slc.agent/META-INF/spring/agent.xml
modules/agent/org.argeo.slc.agent/META-INF/spring/osgi.xml
modules/server/org.argeo.slc.server.jcr/META-INF/MANIFEST.MF
modules/server/org.argeo.slc.server.jcr/META-INF/spring/jcr-osgi.xml
modules/server/org.argeo.slc.server.jcr/META-INF/spring/jcr.xml
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/ExecutionAspect.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ProcessThread.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlow.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionFlowDescriptor.java
runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java [new file with mode: 0644]
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java

index d56398aadce7f59cc415b7d518830fba52b5cd8d..7fe0f0cba09d7f49a22af41c795a711f2c0bbf1d 100644 (file)
@@ -3,18 +3,7 @@ log4j.rootLogger=WARN, development
 
 ## Levels
 log4j.logger.org.argeo=DEBUG
-log4j.logger.org.argeo.slc.execution.ExecutionParameterPostProcessor=TRACE
-log4j.logger.org.argeo.slc.execution.ExecutionContext=DEBUG
-log4j.logger.org.argeo.slc.execution.SimpleExecutionSpec=DEBUG
-log4j.logger.org.argeo.security.mvc.ArgeoRememberMeServices=WARN
-log4j.logger.org.argeo.server.jackrabbit.webdav.ExtendedDispatcherServlet=WARN
-#log4j.logger.org.argeo.server.jcr.mvc.OpenSessionInViewJcrInterceptor=TRACE
-
-log4j.logger.org.argeo.slc.client.ui.views.ExecutionModulesContentProvider=TRACE
-
-#log4j.logger.org.argeo.slc.web.mvc=TRACE
-#log4j.logger.org.argeo.slc.jms=TRACE
-#log4j.logger.org.argeo.server.json=TRACE
+log4j.logger.org.argeo.slc.osgi.OsgiExecutionModulesManager=TRACE
 
 log4j.logger.org.eclipse.rap=INFO
 
@@ -22,10 +11,6 @@ log4j.logger.org.hibernate=WARN
 
 log4j.logger.org.springframework=WARN
 #log4j.logger.org.springframework.web=DEBUG
-#log4j.logger.org.springframework.jms=WARN
-#log4j.logger.org.springframework.security=DEBUG
-#log4j.logger.org.springframework.ldap=TRACE
-#log4j.logger.org.springframework.osgi=INFO
 
 log4j.logger.org.apache.activemq=INFO
 #log4j.logger.org.apache.activemq.transport=WARN
index c3b5c3e19e4cc2323b2b83250a013d5caf8744d5..247b07ec67bbfbeae96f9298b9de8f0ba88d3468 100644 (file)
@@ -1,6 +1,7 @@
 argeo.osgi.start=\
 org.springframework.osgi.extender,\
 org.argeo.slc.client.rcp,\
+org.argeo.slc.server.jcr,\
 org.argeo.slc.demo.ant,\
 org.argeo.slc.demo.basic,\
 
index a6e5f00e58e2737a61b0ff289c1bb9cce6ec1eae..1125ab80aef703dc22e5d7957677c63e8ee25305 100644 (file)
@@ -7,7 +7,6 @@
        <!-- Manager -->\r
        <bean id="modulesManager" class="org.argeo.slc.osgi.OsgiExecutionModulesManager">\r
                <property name="slcExecutionNotifiers" ref="slcExecutionListeners" />\r
-               <property name="executionModulesListeners" ref="executionModulesListeners" />\r
                <property name="bundlesManager" ref="bundlesManager" />\r
        </bean>\r
 \r
index df4759d8b9bb8b96c4654604e29b1f8f9f574a2b..873f6f2424bd18fdc6a589dbe3a918fd8962d040 100644 (file)
@@ -8,11 +8,30 @@
 \r
        <beans:import resource="classpath:org/argeo/slc/osgi/manager.xml" />\r
 \r
-       <service ref="modulesManager" interface="org.argeo.slc.execution.ExecutionModulesManager" />\r
+       <!-- REFERENCES -->\r
+       <list id="executionContexts" interface="org.argeo.slc.execution.ExecutionContext"\r
+               cardinality="0..N">\r
+               <listener ref="modulesManager" bind-method="register"\r
+                       unbind-method="unregister" />\r
+       </list>\r
+\r
+       <list id="executionFlows" interface="org.argeo.slc.execution.ExecutionFlow"\r
+               cardinality="0..N">\r
+               <listener ref="modulesManager" bind-method="register"\r
+                       unbind-method="unregister" />\r
+       </list>\r
 \r
-       <list id="slcExecutionListeners" interface="org.argeo.slc.process.SlcExecutionNotifier"\r
-               cardinality="0..N" />\r
        <list id="executionModulesListeners" interface="org.argeo.slc.execution.ExecutionModulesListener"\r
+               cardinality="0..N">\r
+               <listener ref="modulesManager" bind-method="register"\r
+                       unbind-method="unregister" />\r
+       </list>\r
+\r
+       <list id="slcExecutionListeners" interface="org.argeo.slc.process.SlcExecutionNotifier"\r
                cardinality="0..N" />\r
 \r
+       <!-- SERVICES -->\r
+       <service ref="modulesManager" interface="org.argeo.slc.execution.ExecutionModulesManager" />\r
+\r
+\r
 </beans:beans>
\ No newline at end of file
index e7a1cf6ee9440cf64128c02ad73d0fad13227796..e0cdde8c14914964d60a81124ebfdc2d3d27725c 100644 (file)
@@ -5,6 +5,9 @@ Bundle-Name: Server JCR
 Import-Package: javax.jcr,
  org.argeo.jcr,
  org.argeo.jcr.mvc,
+ org.argeo.jcr.spring,
+ org.argeo.security,
+ org.argeo.security.jcr,
  org.argeo.slc.core.attachment,
  org.argeo.slc.core.execution,
  org.argeo.slc.core.structure,
@@ -17,6 +20,7 @@ Import-Package: javax.jcr,
  org.argeo.slc.dao.test.tree,
  org.argeo.slc.execution,
  org.argeo.slc.jcr.dao,
+ org.argeo.slc.jcr.execution,
  org.argeo.slc.process,
  org.argeo.slc.runtime,
  org.argeo.slc.test,
index ccb910c93e77163699ed5b8761ca9cb2fc4495aa..d1a550c180dd56a01d13f764ca4d8cc9762a9e6d 100644 (file)
@@ -6,20 +6,27 @@
        http://www.springframework.org/schema/beans   \r
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
 \r
-       <reference id="jcrRepository" interface="javax.jcr.Repository" />\r
+       <!-- REFERENCES -->\r
+       <reference id="nodeRepository" interface="javax.jcr.Repository"\r
+               filter="(argeo.jcr.repository.alias=slc)" />\r
+       <reference id="systemExecutionService" interface="org.argeo.security.SystemExecutionService" />\r
 \r
-       <service interface="org.argeo.slc.dao.process.SlcExecutionDao"\r
-               ref="slcExecutionDao" />\r
-       <service interface="org.argeo.slc.dao.test.tree.TreeTestResultDao"\r
-               ref="testResultDao" />\r
-       <service interface="org.argeo.slc.dao.test.tree.TreeTestResultCollectionDao"\r
-               ref="testResultCollectionDao" />\r
-       <service interface="org.argeo.slc.dao.test.TestRunDescriptorDao"\r
-               ref="testRunDescriptorDao" />\r
-       <service interface="org.argeo.slc.dao.runtime.SlcAgentDescriptorDao"\r
-               ref="slcAgentDescriptorDao" />\r
+       <!-- SERVICES -->\r
+       <service interface="org.argeo.slc.execution.ExecutionModulesListener"\r
+               ref="executionModulesListener" />\r
 \r
-       <service\r
-               interface="org.springframework.web.context.request.WebRequestInterceptor"\r
-               ref="osivInterceptor" />\r
+       <!-- <service interface="org.argeo.slc.dao.process.SlcExecutionDao" -->\r
+       <!-- ref="slcExecutionDao" /> -->\r
+       <!-- <service interface="org.argeo.slc.dao.test.tree.TreeTestResultDao" -->\r
+       <!-- ref="testResultDao" /> -->\r
+       <!-- <service interface="org.argeo.slc.dao.test.tree.TreeTestResultCollectionDao" -->\r
+       <!-- ref="testResultCollectionDao" /> -->\r
+       <!-- <service interface="org.argeo.slc.dao.test.TestRunDescriptorDao" -->\r
+       <!-- ref="testRunDescriptorDao" /> -->\r
+       <!-- <service interface="org.argeo.slc.dao.runtime.SlcAgentDescriptorDao" -->\r
+       <!-- ref="slcAgentDescriptorDao" /> -->\r
+\r
+       <!-- <service -->\r
+       <!-- interface="org.springframework.web.context.request.WebRequestInterceptor" -->\r
+       <!-- ref="osivInterceptor" /> -->\r
 </beans:beans>
\ No newline at end of file
index 3286d73ca063c120d8be7dba8c1b552caf90bdbb..4d9983cfd4f9a27c8f9880c50a4d61cd83aa2340 100644 (file)
@@ -3,79 +3,80 @@
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
 \r
-       <bean\r
-               class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">\r
-               <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />\r
-               <property name="ignoreUnresolvablePlaceholders" value="true" />\r
-       </bean>\r
+       <!-- <bean -->\r
+       <!-- class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> -->\r
+       <!-- <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" \r
+               /> -->\r
+       <!-- <property name="locations"> -->\r
+       <!-- <value>osgibundle:jcr.properties</value> -->\r
+       <!-- </property> -->\r
+       <!-- </bean> -->\r
 \r
-       <bean id="slcAgentDescriptorDao" class="org.argeo.slc.jcr.dao.SlcAgentDescriptorDaoJcr"\r
-               init-method="init">\r
-               <property name="session" ref="jcrSession" />\r
-               <property name="nodeMapperProvider" ref="nodeMapperProvider" />\r
+       <bean id="executionModulesListener" class="org.argeo.slc.jcr.execution.JcrExecutionModulesListener"\r
+               init-method="init" destroy-method="dispose">\r
+               <property name="session" ref="session" />\r
        </bean>\r
 \r
-       <bean id="testRunDescriptorDao" class="org.argeo.slc.jcr.dao.TestRunDescriptorDaoJcr"\r
-               init-method="init">\r
-               <property name="session" ref="jcrSession" />\r
-               <property name="nodeMapperProvider" ref="nodeMapperProvider" />\r
+       <bean id="session" class="org.argeo.security.jcr.SystemSession">\r
+               <property name="repository" ref="nodeRepository" />\r
+               <property name="systemExecutionService" ref="systemExecutionService" />\r
        </bean>\r
 \r
-       <bean id="slcExecutionDao" class="org.argeo.slc.jcr.dao.SlcExecutionDaoJcr"\r
-               init-method="init">\r
-               <property name="session" ref="jcrSession" />\r
-               <property name="nodeMapperProvider" ref="nodeMapperProvider" />\r
-       </bean>\r
+       <!-- <bean id="slcAgentDescriptorDao" class="org.argeo.slc.jcr.dao.SlcAgentDescriptorDaoJcr" -->\r
+       <!-- init-method="init"> -->\r
+       <!-- <property name="session" ref="jcrSession" /> -->\r
+       <!-- <property name="nodeMapperProvider" ref="nodeMapperProvider" /> -->\r
+       <!-- </bean> -->\r
 \r
-       <bean id="nodeMapperProvider" class="org.argeo.slc.jcr.dao.SlcNodeMapperProvider"\r
-               init-method="init">\r
-               <property name="defaultNodeMapper" ref="nodeMapper" />\r
-               <property name="treeTestResultNodeMapper" ref="treeTestResultNodeMapper" />\r
-       </bean>\r
+       <!-- <bean id="testRunDescriptorDao" class="org.argeo.slc.jcr.dao.TestRunDescriptorDaoJcr" -->\r
+       <!-- init-method="init"> -->\r
+       <!-- <property name="session" ref="jcrSession" /> -->\r
+       <!-- <property name="nodeMapperProvider" ref="nodeMapperProvider" /> -->\r
+       <!-- </bean> -->\r
 \r
-       <bean id="testResultDao" class="org.argeo.slc.jcr.dao.TreeTestResultDaoJcr"\r
-               init-method="init">\r
-               <property name="session" ref="jcrSession" />\r
-               <property name="nodeMapperProvider" ref="nodeMapperProvider" />\r
-       </bean>\r
+       <!-- <bean id="slcExecutionDao" class="org.argeo.slc.jcr.dao.SlcExecutionDaoJcr" -->\r
+       <!-- init-method="init"> -->\r
+       <!-- <property name="session" ref="jcrSession" /> -->\r
+       <!-- <property name="nodeMapperProvider" ref="nodeMapperProvider" /> -->\r
+       <!-- </bean> -->\r
 \r
-       <bean id="testResultCollectionDao" class="org.argeo.slc.jcr.dao.TreeTestResultCollectionDaoJcr"\r
-               init-method="init">\r
-               <property name="session" ref="jcrSession" />\r
-               <property name="nodeMapperProvider" ref="nodeMapperProvider" />\r
-       </bean>\r
+       <!-- <bean id="nodeMapperProvider" class="org.argeo.slc.jcr.dao.SlcNodeMapperProvider" -->\r
+       <!-- init-method="init"> -->\r
+       <!-- <property name="defaultNodeMapper" ref="nodeMapper" /> -->\r
+       <!-- <property name="treeTestResultNodeMapper" ref="treeTestResultNodeMapper" \r
+               /> -->\r
+       <!-- </bean> -->\r
 \r
-       <bean id="osivInterceptor"\r
-               class="org.argeo.server.jcr.mvc.OpenSessionInViewJcrInterceptor">\r
-               <property name="session" ref="jcrSession" />\r
-       </bean>\r
+       <!-- <bean id="testResultDao" class="org.argeo.slc.jcr.dao.TreeTestResultDaoJcr" -->\r
+       <!-- init-method="init"> -->\r
+       <!-- <property name="session" ref="jcrSession" /> -->\r
+       <!-- <property name="nodeMapperProvider" ref="nodeMapperProvider" /> -->\r
+       <!-- </bean> -->\r
 \r
-       <!--  JCR node mappers -->\r
-       <bean id="bundleClassLoader"\r
-               class="org.springframework.osgi.util.BundleDelegatingClassLoader"\r
-               factory-method="createBundleClassLoaderFor">\r
-               <constructor-arg>\r
-                       <bean factory-bean="bundleContext" factory-method="getBundle" />\r
-               </constructor-arg>\r
-       </bean>\r
+       <!-- <bean id="testResultCollectionDao" class="org.argeo.slc.jcr.dao.TreeTestResultCollectionDaoJcr" -->\r
+       <!-- init-method="init"> -->\r
+       <!-- <property name="session" ref="jcrSession" /> -->\r
+       <!-- <property name="nodeMapperProvider" ref="nodeMapperProvider" /> -->\r
+       <!-- </bean> -->\r
 \r
-       <bean id="nodeMapper" class="org.argeo.jcr.BeanNodeMapper">\r
-               <property name="classLoader" ref="bundleClassLoader" />\r
-       </bean>\r
+       <!-- <bean id="osivInterceptor" -->\r
+       <!-- class="org.argeo.server.jcr.mvc.OpenSessionInViewJcrInterceptor"> -->\r
+       <!-- <property name="session" ref="jcrSession" /> -->\r
+       <!-- </bean> -->\r
 \r
-       <bean id="treeTestResultNodeMapper" class="org.argeo.slc.jcr.dao.TreeTestResultNodeMapper">\r
-               <property name="classLoader" ref="bundleClassLoader" />\r
-       </bean>\r
-       <!--\r
+       <!-- <bean id="bundleClassLoader" -->\r
+       <!-- class="org.springframework.osgi.util.BundleDelegatingClassLoader" -->\r
+       <!-- factory-method="createBundleClassLoaderFor"> -->\r
+       <!-- <constructor-arg> -->\r
+       <!-- <bean factory-bean="bundleContext" factory-method="getBundle" /> -->\r
+       <!-- </constructor-arg> -->\r
+       <!-- </bean> -->\r
 \r
-               <bean id="jcrSession" factory-bean="argeo.jcr.repository.inMemory"\r
-               factory-method="login" destroy-method="logout" scope="request">\r
-               <constructor-arg> <bean\r
-               class="org.argeo.server.jcr.security.SpringSecurityCredentials" />\r
-               </constructor-arg> </bean>\r
-       -->\r
-       <bean id="jcrSession"\r
-               class="org.argeo.jcr.ThreadBoundJcrSessionFactory">\r
-               <property name="repository" ref="jcrRepository" />\r
-       </bean>\r
+       <!-- <bean id="nodeMapper" class="org.argeo.jcr.BeanNodeMapper"> -->\r
+       <!-- <property name="classLoader" ref="bundleClassLoader" /> -->\r
+       <!-- </bean> -->\r
+\r
+       <!-- <bean id="treeTestResultNodeMapper" class="org.argeo.slc.jcr.dao.TreeTestResultNodeMapper"> -->\r
+       <!-- <property name="classLoader" ref="bundleClassLoader" /> -->\r
+       <!-- </bean> -->\r
 </beans>
\ No newline at end of file
index 4e9856fe6f2745bd0d2cc5ab2ffa42c51592b633..e16ad65f79edc2e81bc8dd73433bd9a7eead1736 100644 (file)
@@ -26,7 +26,6 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.execution.ExecutionContext;
 import org.argeo.slc.execution.ExecutionFlow;
 import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
-import org.argeo.slc.execution.ExecutionModulesListener;
 import org.argeo.slc.execution.ExecutionModulesManager;
 import org.argeo.slc.process.RealizedFlow;
 import org.argeo.slc.process.SlcExecution;
@@ -40,7 +39,6 @@ public abstract class AbstractExecutionModulesManager implements
                        .getLog(AbstractExecutionModulesManager.class);
 
        private List<SlcExecutionNotifier> slcExecutionNotifiers = new ArrayList<SlcExecutionNotifier>();
-       private List<ExecutionModulesListener> executionModulesListeners = new ArrayList<ExecutionModulesListener>();
 
        private ThreadGroup processesThreadGroup = new ThreadGroup("Processes");
 
@@ -114,13 +112,4 @@ public abstract class AbstractExecutionModulesManager implements
                return processesThreadGroup;
        }
 
-       protected List<ExecutionModulesListener> getExecutionModulesListeners() {
-               return executionModulesListeners;
-       }
-
-       public void setExecutionModulesListeners(
-                       List<ExecutionModulesListener> executionModulesListeners) {
-               this.executionModulesListeners = executionModulesListeners;
-       }
-
 }
index e9e5b4cddd89967d62724500b61aaec332dfa24d..cdafe446d9a33727307ec9019049aad1893e1e94 100644 (file)
@@ -27,6 +27,7 @@ import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
 
 @Aspect
+/** Aspect intercepting calls on execution flows and contexts. */
 public class ExecutionAspect {
        private final static Log log = LogFactory.getLog(ExecutionAspect.class);
 
@@ -60,16 +61,6 @@ public class ExecutionAspect {
                }
        }
 
-       @Around("runnableExecution()")
-       public void aroundRunnable(ProceedingJoinPoint pjp) throws Throwable {
-               ExecutionFlow executionFlow = (ExecutionFlow) pjp.getTarget();
-               Runnable runnable = (Runnable) pjp.getArgs()[0];
-               if (log.isDebugEnabled())
-                       logRunnableExecution(executionFlow, runnable);
-               // Actually execute the runnable
-               pjp.proceed();
-       }
-
        @Around("getVariable()")
        public Object aroundGetVariable(ProceedingJoinPoint pjp) throws Throwable {
                Object obj = pjp.proceed();
@@ -86,10 +77,6 @@ public class ExecutionAspect {
        public void flowExecution() {
        }
 
-       @Pointcut("execution(void org.argeo.slc.execution.ExecutionFlow.doExecuteRunnable(..))")
-       public void runnableExecution() {
-       }
-
        @Pointcut("execution(* org.argeo.slc.execution.ExecutionContext.getVariable(..))")
        public void getVariable() {
        }
index 7c0e7b10db0a4d3a7111916041b1f134d3676c77..5af3262d57cb4923a76ce2e6a738154876ff12aa 100644 (file)
@@ -47,7 +47,8 @@ public class ProcessThread extends Thread {
        }
 
        public void run() {
-               log.info("\n##\n## SLC Process " + slcProcess + " STARTED\n##");
+               log.info("\n##\n## SLC Process #" + slcProcess.getUuid()
+                               + " STARTED\n##\n");
 
                slcProcess.setStatus(SlcExecution.STATUS_RUNNING);
                executionModulesManager.dispatchUpdateStatus(slcProcess,
@@ -83,7 +84,7 @@ public class ProcessThread extends Thread {
                executionModulesManager.dispatchUpdateStatus(slcProcess,
                                SlcExecution.STATUS_RUNNING, slcProcess.getStatus());
 
-               log.info("## SLC Process " + slcProcess + " COMPLETED");
+               log.info("\n## SLC Process #" + slcProcess.getUuid() + " COMPLETED\n");
        }
 
        public void notifyError() {
index b27f4efc1328f6ea595666ad906298b4d15ff4b5..992a974866ac8a8a101e07f499f79293190d7dde 100644 (file)
 
 package org.argeo.slc.execution;
 
+/** Abstraction of an execution that can be identified and configured. */
 public interface ExecutionFlow extends Runnable {
+       /** Retrieve an immutable parameter */
        public Object getParameter(String key);
 
+       /** Whether this immutable parameter is set */
        public Boolean isSetAsParameter(String key);
 
+       /** The specifications of the execution flow. */
        public ExecutionSpec getExecutionSpec();
 
+       /**
+        * The name of this execution flow. Can contains '/' which will be
+        * interpreted by UIs as a hierarchy;
+        */
        public String getName();
 
-       public String getPath();
-
        /**
-        * Actually performs the execution of the Runnable. This method should never
-        * be called directly. The implementation should provide a reasonable
-        * default, but it is meant to be intercepted either to analyze what is run
-        * or to override the default behavior.
+        * @deprecated will be removed in SLC 2.0, the path should be the part of
+        *             the name with '/'
         */
-       public void doExecuteRunnable(Runnable runnable);
+       public String getPath();
 }
index f4329309996bc9fd6ee855be9731415953bcf446..77cc268169f81d0845b0f083f23049e357f02b69 100644 (file)
@@ -39,10 +39,6 @@ import java.util.Map;
  * 
  * Generally, values object are either a <code>PrimitiveAccessor</code> or a
  * <code>RefValue</code> but can be other objects.
- * 
- * @author bsinou
- * 
- * 
  */
 public class ExecutionFlowDescriptor implements Serializable {
        private static final long serialVersionUID = 7101944857038041216L;
@@ -66,10 +62,18 @@ public class ExecutionFlowDescriptor implements Serializable {
                return name;
        }
 
+       /**
+        * @deprecated will be removed in SLC 2.0, the path should be the part of
+        *             the name with '/'
+        */
        public String getPath() {
                return path;
        }
 
+       /**
+        * @deprecated will be removed in SLC 2.0, the path should be the part of
+        *             the name with '/'
+        */
        public void setPath(String path) {
                this.path = path;
        }
diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java
new file mode 100644 (file)
index 0000000..dd91d5d
--- /dev/null
@@ -0,0 +1,166 @@
+package org.argeo.slc.jcr.execution;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.deploy.Module;
+import org.argeo.slc.execution.ExecutionContext;
+import org.argeo.slc.execution.ExecutionFlow;
+import org.argeo.slc.execution.ExecutionModulesListener;
+
+/**
+ * Synchronizes the execution runtime with JCR. For the time being the state is
+ * completely reset from one start to another.
+ */
+public class JcrExecutionModulesListener implements ExecutionModulesListener {
+       private final static Log log = LogFactory
+                       .getLog(JcrExecutionModulesListener.class);
+
+       private String modulesPath = "/slc/modules";
+
+       private Session session;
+
+       public void init() {
+               try {
+                       // clean up previous state
+                       if (session.nodeExists(modulesPath))
+                               session.getNode(modulesPath).remove();
+                       JcrUtils.mkdirs(session, modulesPath);
+                       session.save();
+               } catch (RepositoryException e) {
+                       throw new SlcException(
+                                       "Cannot initialize JCR execution module listener", e);
+               } finally {
+                       JcrUtils.discardQuietly(session);
+               }
+       }
+
+       public void dispose() {
+               try {
+                       // clean up previous state
+                       if (session.nodeExists(modulesPath))
+                               session.getNode(modulesPath).remove();
+                       session.save();
+               } catch (RepositoryException e) {
+                       throw new SlcException(
+                                       "Cannot dispose JCR execution module listener", e);
+               } finally {
+                       JcrUtils.discardQuietly(session);
+               }
+       }
+
+       public void executionModuleAdded(Module module,
+                       ExecutionContext executionContext) {
+               try {
+                       Node base = session.getNode(modulesPath);
+                       Node moduleName = base.hasNode(module.getName()) ? base
+                                       .getNode(module.getName()) : base.addNode(module.getName());
+                       Node moduleVersion = moduleName.hasNode(module.getVersion()) ? moduleName
+                                       .getNode(module.getVersion()) : moduleName.addNode(module
+                                       .getVersion());
+                       session.save();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot add module " + module, e);
+               }
+
+       }
+
+       public void executionModuleRemoved(Module module,
+                       ExecutionContext executionContext) {
+               try {
+                       Node base = session.getNode(modulesPath);
+                       if (base.hasNode(module.getName())) {
+                               Node moduleName = base.getNode(module.getName());
+                               if (moduleName.hasNode(module.getVersion()))
+                                       moduleName.getNode(module.getVersion()).remove();
+                               if (!moduleName.hasNodes())
+                                       moduleName.remove();
+                               session.save();
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot remove module " + module, e);
+               }
+       }
+
+       public void executionFlowAdded(Module module, ExecutionFlow executionFlow) {
+               String path = getExecutionFlowPath(module, executionFlow);
+               log.debug("path=" + path);
+               try {
+                       Node flowNode;
+                       if (!session.nodeExists(path)) {
+                               Node base = session.getNode(modulesPath);
+                               Node moduleNode = base.getNode(module.getName() + '/'
+                                               + module.getVersion());
+                               String relativePath = getExecutionFlowRelativePath(executionFlow);
+                               log.debug("relativePath='" + relativePath + "'");
+                               Iterator<String> names = Arrays.asList(relativePath.split("/"))
+                                               .iterator();
+                               Node currNode = moduleNode;
+                               while (names.hasNext()) {
+                                       String name = names.next();
+                                       if (currNode.hasNode(name))
+                                               currNode = currNode.getNode(name);
+                                       else {
+                                               if (names.hasNext())
+                                                       currNode = currNode.addNode(name);
+                                               else
+                                                       flowNode = currNode.addNode(name);
+                                       }
+                               }
+                               session.save();
+                       } else {
+                               flowNode = session.getNode(path);
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot add flow " + executionFlow
+                                       + " from module " + module, e);
+               }
+
+       }
+
+       public void executionFlowRemoved(Module module, ExecutionFlow executionFlow) {
+               String path = getExecutionFlowPath(module, executionFlow);
+               try {
+                       if (session.nodeExists(path)) {
+                               Node flowNode = session.getNode(path);
+                               flowNode.remove();
+                               session.save();
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot remove flow " + executionFlow
+                                       + " from module " + module, e);
+               }
+       }
+
+       protected String getExecutionFlowPath(Module module,
+                       ExecutionFlow executionFlow) {
+               String relativePath = getExecutionFlowRelativePath(executionFlow);
+               return modulesPath + '/' + module.getName() + '/' + module.getVersion()
+                               + '/' + relativePath;
+       }
+
+       /** @return the relative path, never starts with '/' */
+       @SuppressWarnings("deprecation")
+       protected String getExecutionFlowRelativePath(ExecutionFlow executionFlow) {
+               String relativePath = executionFlow.getPath() == null ? executionFlow
+                               .getName() : executionFlow.getPath() + '/'
+                               + executionFlow.getName();
+               // we assume that it is more than one char long
+               if (relativePath.charAt(0) == '/')
+                       relativePath = relativePath.substring(1);
+               return relativePath;
+       }
+
+       public void setSession(Session session) {
+               this.session = session;
+       }
+
+}
index fe311c8dd586e341983471408a48b636f19faf65..45a65eae2486fe9de1c9d20d3069228b39d9070a 100644 (file)
@@ -43,6 +43,7 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.springframework.osgi.service.importer.OsgiServiceLifecycleListener;
 
+/** Execution modules manager implementation based on an OSGi runtime. */
 public class OsgiExecutionModulesManager extends
                AbstractExecutionModulesManager implements OsgiServiceLifecycleListener {
 
@@ -55,6 +56,8 @@ public class OsgiExecutionModulesManager extends
        private Map<OsgiBundle, Set<ExecutionFlow>> executionFlows = new HashMap<OsgiBundle, Set<ExecutionFlow>>();
        private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultExecutionFlowDescriptorConverter();
 
+       private List<ExecutionModulesListener> executionModulesListeners = new ArrayList<ExecutionModulesListener>();
+
        public synchronized ExecutionModuleDescriptor getExecutionModuleDescriptor(
                        String moduleName, String version) {
                ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
@@ -137,10 +140,6 @@ public class OsgiExecutionModulesManager extends
                                ExecutionFlowDescriptorConverter.class, filter);
        }
 
-       public void setBundlesManager(BundlesManager bundlesManager) {
-               this.bundlesManager = bundlesManager;
-       }
-
        /**
         * Builds a minimal realized flow, based on the provided information
         * (typically from the command line).
@@ -247,36 +246,102 @@ public class OsgiExecutionModulesManager extends
                        return obj.toString();
        }
 
-       @SuppressWarnings({ "rawtypes", "unchecked" })
-       public synchronized void bind(Object service, Map properties)
-                       throws Exception {
-               if (service instanceof ExecutionContext) {
-                       ExecutionContext executionContext = (ExecutionContext) service;
-                       OsgiBundle osgiBundle = asOsgiBundle(properties);
-                       Bundle bundle = bundlesManager.findRelatedBundle(osgiBundle);
-                       osgiBundle.setLabel(getHeaderSafe(bundle, Constants.BUNDLE_NAME));
-                       osgiBundle.setDescription(getHeaderSafe(bundle,
-                                       Constants.BUNDLE_DESCRIPTION));
-                       executionContexts.put(osgiBundle, executionContext);
+       /*
+        * REGISTRATION
+        */
+
+       /** Registers an execution context. */
+       public synchronized void register(ExecutionContext executionContext,
+                       Map<String, String> properties) {
+               OsgiBundle osgiBundle = asOsgiBundle(properties);
+               Bundle bundle = bundlesManager.findRelatedBundle(osgiBundle);
+               osgiBundle.setLabel(getHeaderSafe(bundle, Constants.BUNDLE_NAME));
+               osgiBundle.setDescription(getHeaderSafe(bundle,
+                               Constants.BUNDLE_DESCRIPTION));
+               executionContexts.put(osgiBundle, executionContext);
+               if (log.isTraceEnabled())
+                       log.trace("Registered execution context from " + osgiBundle);
+               // Notify
+               for (ExecutionModulesListener listener : executionModulesListeners)
+                       listener.executionModuleAdded(osgiBundle, executionContext);
+       }
+
+       /** Unregisters an execution context. */
+       public synchronized void unregister(ExecutionContext executionContext,
+                       Map<String, String> properties) {
+               OsgiBundle osgiBundle = asOsgiBundle(properties);
+               if (executionContexts.containsKey(osgiBundle)) {
+                       executionContexts.remove(osgiBundle);
                        if (log.isTraceEnabled())
-                               log.debug("Registered execution context from " + osgiBundle);
+                               log.trace("Removed execution context from " + osgiBundle);
                        // Notify
-                       for (ExecutionModulesListener listener : getExecutionModulesListeners())
-                               listener.executionModuleAdded(osgiBundle, executionContext);
+                       for (ExecutionModulesListener listener : executionModulesListeners)
+                               listener.executionModuleRemoved(osgiBundle, executionContext);
+               }
+       }
 
-               } else if (service instanceof ExecutionFlow) {
-                       ExecutionFlow executionFlow = (ExecutionFlow) service;
-                       OsgiBundle osgiBundle = asOsgiBundle(properties);
-                       if (!executionFlows.containsKey(osgiBundle)) {
-                               executionFlows.put(osgiBundle, new HashSet());
-                       }
-                       executionFlows.get(osgiBundle).add(executionFlow);
+       /** Registers an execution flow. */
+       public synchronized void register(ExecutionFlow executionFlow,
+                       Map<String, String> properties) {
+               OsgiBundle osgiBundle = asOsgiBundle(properties);
+               if (!executionFlows.containsKey(osgiBundle)) {
+                       executionFlows.put(osgiBundle, new HashSet<ExecutionFlow>());
+               }
+               executionFlows.get(osgiBundle).add(executionFlow);
+               if (log.isTraceEnabled())
+                       log.trace("Registered " + executionFlow + " from " + osgiBundle);
+
+               for (ExecutionModulesListener listener : executionModulesListeners)
+                       listener.executionFlowAdded(osgiBundle, executionFlow);
+       }
+
+       /** Unregisters an execution flow. */
+       public synchronized void unregister(ExecutionFlow executionFlow,
+                       Map<String, String> properties) {
+               OsgiBundle osgiBundle = asOsgiBundle(properties);
+               if (executionFlows.containsKey(osgiBundle)) {
+                       Set<ExecutionFlow> flows = executionFlows.get(osgiBundle);
+                       flows.remove(executionFlow);
                        if (log.isTraceEnabled())
-                               log.debug("Registered " + executionFlow + " from " + osgiBundle);
-                       for (ExecutionModulesListener listener : getExecutionModulesListeners())
-                               listener.executionFlowAdded(osgiBundle, executionFlow);
+                               log.debug("Removed " + executionFlow + " from " + osgiBundle);
+                       if (flows.size() == 0) {
+                               executionFlows.remove(osgiBundle);
+                               if (log.isTraceEnabled())
+                                       log.trace("Removed flows set from " + osgiBundle);
+                       }
+                       for (ExecutionModulesListener listener : executionModulesListeners)
+                               listener.executionFlowRemoved(osgiBundle, executionFlow);
+               }
+       }
+
+       /** Registers an execution module listener. */
+       public synchronized void register(
+                       ExecutionModulesListener executionModulesListener,
+                       Map<String, String> properties) {
+               // sync with current state
+               for (OsgiBundle osgiBundle : executionContexts.keySet()) {
+                       executionModulesListener.executionModuleAdded(osgiBundle,
+                                       executionContexts.get(osgiBundle));
+               }
+               for (OsgiBundle osgiBundle : executionFlows.keySet()) {
+                       for (ExecutionFlow executionFlow : executionFlows.get(osgiBundle))
+                               executionModulesListener.executionFlowAdded(osgiBundle,
+                                               executionFlow);
+               }
+               executionModulesListeners.add(executionModulesListener);
+       }
 
-               } else if (service instanceof ExecutionFlowDescriptorConverter) {
+       /** Unregisters an execution module listener. */
+       public synchronized void unregister(
+                       ExecutionModulesListener executionModulesListener,
+                       Map<String, String> properties) {
+               executionModulesListeners.remove(executionModulesListener);
+       }
+
+       @SuppressWarnings({ "rawtypes" })
+       public synchronized void bind(Object service, Map properties)
+                       throws Exception {
+               if (service instanceof ExecutionFlowDescriptorConverter) {
                        ExecutionFlowDescriptorConverter executionFlowDescriptorConverter = (ExecutionFlowDescriptorConverter) service;
                        OsgiBundle osgiBundle = asOsgiBundle(properties);
                        executionFlowDescriptorConverters.put(osgiBundle,
@@ -292,36 +357,7 @@ public class OsgiExecutionModulesManager extends
        @SuppressWarnings("rawtypes")
        public synchronized void unbind(Object service, Map properties)
                        throws Exception {
-               if (service instanceof ExecutionContext) {
-                       OsgiBundle osgiBundle = asOsgiBundle(properties);
-                       if (executionContexts.containsKey(osgiBundle)) {
-                               ExecutionContext executionContext = executionContexts
-                                               .remove(osgiBundle);
-                               if (log.isTraceEnabled())
-                                       log.debug("Removed execution context from " + osgiBundle);
-                               // Notify
-                               for (ExecutionModulesListener listener : getExecutionModulesListeners())
-                                       listener.executionModuleRemoved(osgiBundle,
-                                                       executionContext);
-                       }
-               } else if (service instanceof ExecutionFlow) {
-                       ExecutionFlow executionFlow = (ExecutionFlow) service;
-                       OsgiBundle osgiBundle = asOsgiBundle(properties);
-                       if (executionFlows.containsKey(osgiBundle)) {
-                               Set flows = executionFlows.get(osgiBundle);
-                               flows.remove(executionFlow);
-                               if (log.isTraceEnabled())
-                                       log.debug("Removed " + executionFlow + " from "
-                                                       + osgiBundle);
-                               if (flows.size() == 0) {
-                                       executionFlows.remove(osgiBundle);
-                                       if (log.isTraceEnabled())
-                                               log.debug("Removed flows set from " + osgiBundle);
-                               }
-                               for (ExecutionModulesListener listener : getExecutionModulesListeners())
-                                       listener.executionFlowRemoved(osgiBundle, executionFlow);
-                       }
-               } else if (service instanceof ExecutionFlowDescriptorConverter) {
+               if (service instanceof ExecutionFlowDescriptorConverter) {
                        OsgiBundle osgiBundle = asOsgiBundle(properties);
                        if (executionFlowDescriptorConverters.containsKey(osgiBundle)) {
                                executionFlowDescriptorConverters.remove(osgiBundle);
@@ -350,8 +386,13 @@ public class OsgiExecutionModulesManager extends
                        return properties.get(key).toString();
        }
 
+       public void setBundlesManager(BundlesManager bundlesManager) {
+               this.bundlesManager = bundlesManager;
+       }
+
        public void setDefaultDescriptorConverter(
                        ExecutionFlowDescriptorConverter defaultDescriptorConverter) {
                this.defaultDescriptorConverter = defaultDescriptorConverter;
        }
+
 }