]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/execution/JcrExecutionModulesListener.java
Fix execution spec node added twice
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.jcr / src / main / java / org / argeo / slc / jcr / execution / JcrExecutionModulesListener.java
index 4d0c55cb0ed76e4f2915850e7e8945037a3112d5..9e866dfc79051f37f303cb5239d30bb4f7d3dcb3 100644 (file)
@@ -1,11 +1,28 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.argeo.slc.jcr.execution;
 
 import java.util.Arrays;
 import java.util.Iterator;
+import java.util.List;
 
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.Property;
+import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
@@ -15,11 +32,14 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.slc.SlcException;
 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.RefValueChoice;
 import org.argeo.slc.deploy.ModuleDescriptor;
 import org.argeo.slc.execution.ExecutionFlowDescriptor;
+import org.argeo.slc.execution.ExecutionModuleDescriptor;
 import org.argeo.slc.execution.ExecutionModulesListener;
+import org.argeo.slc.execution.ExecutionModulesManager;
 import org.argeo.slc.execution.ExecutionSpec;
 import org.argeo.slc.execution.ExecutionSpecAttribute;
 import org.argeo.slc.jcr.SlcJcrUtils;
@@ -32,10 +52,15 @@ import org.argeo.slc.jcr.SlcTypes;
  */
 public class JcrExecutionModulesListener implements ExecutionModulesListener,
                SlcNames {
+       private final static String SLC_EXECUTION_MODULES_PROPERTY = "slc.executionModules";
+
        private final static Log log = LogFactory
                        .getLog(JcrExecutionModulesListener.class);
        private JcrAgent agent;
 
+       private ExecutionModulesManager modulesManager;
+
+       private Repository repository;
        /**
         * We don't use a thread bound session because many different threads will
         * call this critical component and we don't want to login each time. We
@@ -47,12 +72,80 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
         * LIFECYCLE
         */
        public void init() {
-               clearAgent();
+               try {
+                       session = repository.login();
+                       clearAgent();
+                       if (modulesManager != null) {
+                               Node agentNode = session.getNode(agent.getNodePath());
+
+                               List<ModuleDescriptor> moduleDescriptors = modulesManager
+                                               .listModules();
+
+                               // scan SLC-ExecutionModule metadata
+                               for (ModuleDescriptor md : moduleDescriptors) {
+                                       if (md.getMetadata().containsKey(
+                                                       ExecutionModuleDescriptor.SLC_EXECUTION_MODULE)) {
+                                               String moduleNodeName = SlcJcrUtils
+                                                               .getModuleNodeName(md);
+                                               Node moduleNode = agentNode.hasNode(moduleNodeName) ? agentNode
+                                                               .getNode(moduleNodeName) : agentNode
+                                                               .addNode(moduleNodeName);
+                                               moduleNode.addMixin(SlcTypes.SLC_EXECUTION_MODULE);
+                                               moduleNode.setProperty(SLC_NAME, md.getName());
+                                               moduleNode.setProperty(SLC_VERSION, md.getVersion());
+                                               moduleNode.setProperty(Property.JCR_TITLE,
+                                                               md.getTitle());
+                                               moduleNode.setProperty(Property.JCR_DESCRIPTION,
+                                                               md.getDescription());
+                                               moduleNode.setProperty(SLC_STARTED, md.getStarted());
+                                       }
+                               }
+
+                               // scan execution modules property
+                               String executionModules = System
+                                               .getProperty(SLC_EXECUTION_MODULES_PROPERTY);
+                               if (executionModules != null) {
+                                       for (String executionModule : executionModules.split(",")) {
+                                               allModules: for (ModuleDescriptor md : moduleDescriptors) {
+                                                       String moduleNodeName = SlcJcrUtils
+                                                                       .getModuleNodeName(md);
+                                                       if (md.getName().equals(executionModule)) {
+                                                               Node moduleNode = agentNode
+                                                                               .hasNode(moduleNodeName) ? agentNode
+                                                                               .getNode(moduleNodeName) : agentNode
+                                                                               .addNode(moduleNodeName);
+                                                               moduleNode
+                                                                               .addMixin(SlcTypes.SLC_EXECUTION_MODULE);
+                                                               moduleNode.setProperty(SLC_NAME, md.getName());
+                                                               moduleNode.setProperty(SLC_VERSION,
+                                                                               md.getVersion());
+                                                               moduleNode.setProperty(Property.JCR_TITLE,
+                                                                               md.getTitle());
+                                                               moduleNode.setProperty(
+                                                                               Property.JCR_DESCRIPTION,
+                                                                               md.getDescription());
+                                                               moduleNode.setProperty(SLC_STARTED,
+                                                                               md.getStarted());
+                                                               break allModules;
+                                                       }
+                                               }
+                                       }
+
+                                       // save if needed
+                                       if (session.hasPendingChanges())
+                                               session.save();
+                               }
+                       }
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
+                       JcrUtils.logoutQuietly(session);
+                       throw new SlcException("Cannot initialize modules", e);
+               }
        }
 
-       public void dispose() {
+       public void destroy() {
                clearAgent();
-               session.logout();
+               JcrUtils.logoutQuietly(session);
        }
 
        protected synchronized void clearAgent() {
@@ -70,8 +163,13 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
        /*
         * EXECUTION MODULES LISTENER
         */
+
        public synchronized void executionModuleAdded(
                        ModuleDescriptor moduleDescriptor) {
+               syncExecutionModule(moduleDescriptor);
+       }
+
+       protected void syncExecutionModule(ModuleDescriptor moduleDescriptor) {
                try {
                        Node agentNode = session.getNode(agent.getNodePath());
                        String moduleNodeName = SlcJcrUtils
@@ -86,12 +184,12 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                                        moduleDescriptor.getTitle());
                        moduleNode.setProperty(Property.JCR_DESCRIPTION,
                                        moduleDescriptor.getDescription());
+                       moduleNode.setProperty(SLC_STARTED, moduleDescriptor.getStarted());
                        session.save();
                } catch (RepositoryException e) {
                        JcrUtils.discardQuietly(session);
-                       throw new SlcException("Cannot add module " + moduleDescriptor, e);
+                       throw new SlcException("Cannot sync module " + moduleDescriptor, e);
                }
-
        }
 
        public synchronized void executionModuleRemoved(
@@ -99,10 +197,16 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                try {
                        String moduleName = SlcJcrUtils.getModuleNodeName(moduleDescriptor);
                        Node agentNode = session.getNode(agent.getNodePath());
-                       if (agentNode.hasNode(moduleName))
-                               agentNode.getNode(moduleName).remove();
-                       agentNode.getSession().save();
+                       if (agentNode.hasNode(moduleName)) {
+                               Node moduleNode = agentNode.getNode(moduleName);
+                               for (NodeIterator nit = moduleNode.getNodes(); nit.hasNext();) {
+                                       nit.nextNode().remove();
+                               }
+                               moduleNode.setProperty(SLC_STARTED, false);
+                       }
+                       session.save();
                } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(session);
                        throw new SlcException("Cannot remove module " + moduleDescriptor,
                                        e);
                }
@@ -139,8 +243,9 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                        String relativePath, ExecutionFlowDescriptor efd)
                        throws RepositoryException {
                Node flowNode = null;
-               Iterator<String> names = Arrays.asList(relativePath.split("/"))
-                               .iterator();
+               List<String> pathTokens = Arrays.asList(relativePath.split("/"));
+
+               Iterator<String> names = pathTokens.iterator();
                // create intermediary paths
                Node currNode = moduleNode;
                while (names.hasNext()) {
@@ -155,17 +260,27 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                                                        SlcTypes.SLC_EXECUTION_FLOW);
                        }
                }
+
+               // name, description
                flowNode.setProperty(SLC_NAME, efd.getName());
-               String[] tokens = relativePath.split("/");
-               flowNode.setProperty(Property.JCR_TITLE, tokens[tokens.length - 1]);
+               String endName = pathTokens.get(pathTokens.size() - 1);
+               flowNode.setProperty(Property.JCR_TITLE, endName);
                if (efd.getDescription() != null
-                               && efd.getDescription().trim().equals(""))
+                               && !efd.getDescription().trim().equals("")) {
                        flowNode.setProperty(Property.JCR_DESCRIPTION, efd.getDescription());
+               } else {
+                       flowNode.setProperty(Property.JCR_DESCRIPTION, endName);
+               }
 
                // execution spec
                ExecutionSpec executionSpec = efd.getExecutionSpec();
                String esName = executionSpec.getName();
-               if (!(esName == null || esName.equals(ExecutionSpec.INTERNAL_NAME))) {
+               if (esName == null || esName.equals(ExecutionSpec.INTERNAL_NAME)
+                               || esName.contains("#")/* automatically generated bean name */) {
+                       // internal spec node
+                       mapExecutionSpec(flowNode, executionSpec);
+               } else {
+                       // reference spec node
                        Node executionSpecsNode = moduleNode.hasNode(SLC_EXECUTION_SPECS) ? moduleNode
                                        .getNode(SLC_EXECUTION_SPECS) : moduleNode
                                        .addNode(SLC_EXECUTION_SPECS);
@@ -179,9 +294,24 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                                                executionSpec.getDescription());
                        mapExecutionSpec(executionSpecNode, executionSpec);
                        flowNode.setProperty(SLC_SPEC, executionSpecNode);
-               } else {
-                       mapExecutionSpec(flowNode, executionSpec);
                }
+
+               // values
+               for (String attr : efd.getValues().keySet()) {
+                       ExecutionSpecAttribute esa = executionSpec.getAttributes()
+                                       .get(attr);
+                       if (!flowNode.hasNode(attr))
+                               throw new SlcException("No spec node for attribute '" + attr
+                                               + "' in flow " + flowNode.getPath());
+                       if (esa instanceof PrimitiveSpecAttribute) {
+                               PrimitiveSpecAttribute psa = (PrimitiveSpecAttribute) esa;
+                               Node valueNode = flowNode.getNode(attr);
+                               valueNode.setProperty(SLC_TYPE, psa.getType());
+                               SlcJcrUtils.setPrimitiveAsProperty(valueNode, SLC_VALUE,
+                                               (PrimitiveValue) efd.getValues().get(attr));
+                       }
+               }
+
                return flowNode;
        }
 
@@ -210,8 +340,14 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                                attrNode.addMixin(SlcTypes.SLC_REF_SPEC_ATTRIBUTE);
                                RefSpecAttribute rsa = (RefSpecAttribute) esa;
                                attrNode.setProperty(SLC_TYPE, rsa.getTargetClassName());
+                               Object value = rsa.getValue();
                                if (rsa.getChoices() != null) {
+                                       Integer index = null;
+                                       int count = 0;
                                        for (RefValueChoice choice : rsa.getChoices()) {
+                                               String name = choice.getName();
+                                               if (value != null && name.equals(value.toString()))
+                                                       index = count;
                                                Node choiceNode = attrNode.addNode(choice.getName());
                                                choiceNode.addMixin(NodeType.MIX_TITLE);
                                                choiceNode.setProperty(Property.JCR_TITLE,
@@ -220,7 +356,11 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                                                                && !choice.getDescription().trim().equals(""))
                                                        choiceNode.setProperty(Property.JCR_DESCRIPTION,
                                                                        choice.getDescription());
+                                               count++;
                                        }
+
+                                       if (index != null)
+                                               attrNode.setProperty(SLC_VALUE, index);
                                }
                        }
                }
@@ -233,7 +373,7 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                        Node moduleNode = agentNode.getNode(SlcJcrUtils
                                        .getModuleNodeName(module));
                        String relativePath = getExecutionFlowRelativePath(executionFlow);
-                       if (!moduleNode.hasNode(relativePath))
+                       if (moduleNode.hasNode(relativePath))
                                moduleNode.getNode(relativePath).remove();
                        agentNode.getSession().save();
                } catch (RepositoryException e) {
@@ -267,9 +407,12 @@ public class JcrExecutionModulesListener implements ExecutionModulesListener,
                this.agent = agent;
        }
 
-       /** Expects a non-shared session with admin authorization */
-       public void setSession(Session session) {
-               this.session = session;
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setModulesManager(ExecutionModulesManager modulesManager) {
+               this.modulesManager = modulesManager;
        }
 
 }