]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java
Help working
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / execution / DefaultExecutionFlowDescriptorConverter.java
index 7dc8d00cb74b97009f3240ae9691e81a5bb513b0..cec087f9d8f017c70d52cb3d4c109b80177f6b83 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ * 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.
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.argeo.slc.core.execution;
 
 import java.util.Comparator;
@@ -25,8 +24,6 @@ import java.util.TreeSet;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.UnsupportedException;
 import org.argeo.slc.execution.ExecutionFlow;
 import org.argeo.slc.execution.ExecutionFlowDescriptor;
 import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
@@ -35,14 +32,18 @@ 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.BeanFactory;
 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;
 import org.springframework.util.StringUtils;
 
+/**
+ * Performs conversion in both direction between data exchanged with the agent
+ * and the data in the application context.
+ */
 public class DefaultExecutionFlowDescriptorConverter implements
                ExecutionFlowDescriptorConverter, ApplicationContextAware {
        public final static String REF_VALUE_TYPE_BEAN_NAME = "beanName";
@@ -55,6 +56,7 @@ public class DefaultExecutionFlowDescriptorConverter implements
 
        private ApplicationContext applicationContext;
 
+       @SuppressWarnings("unused")
        public Map<String, Object> convertValues(
                        ExecutionFlowDescriptor executionFlowDescriptor) {
                Map<String, Object> values = executionFlowDescriptor.getValues();
@@ -70,7 +72,11 @@ public class DefaultExecutionFlowDescriptorConverter implements
                                ExecutionSpecAttribute attribute = executionSpec
                                                .getAttributes().get(key);
 
-                               if (attribute.getIsFrozen())
+                               if (attribute == null)
+                                       throw new FlowConfigurationException(
+                                                       "No spec attribute defined for '" + key + "'");
+
+                               if (attribute.getIsConstant())
                                        continue values;
 
                                Object value = values.get(key);
@@ -123,9 +129,13 @@ public class DefaultExecutionFlowDescriptorConverter implements
                                                Object obj = PrimitiveUtils.convert(type, ref);
                                                convertedValues.put(key, obj);
                                        } else {
-                                               throw new UnsupportedException("Ref value type",
-                                                               refValue.getType());
+                                               throw new FlowConfigurationException(
+                                                               "Ref value type not supported: "
+                                                                               + refValue.getType());
                                        }
+                               } else {
+                                       // default is to take the value as is
+                                       convertedValues.put(key, value);
                                }
                        }
                }
@@ -139,65 +149,81 @@ public class DefaultExecutionFlowDescriptorConverter implements
                for (String name : executionFlows.keySet()) {
                        ExecutionFlow executionFlow = executionFlows.get(name);
 
-                       Assert.notNull(executionFlow.getName());
-                       Assert.state(name.equals(executionFlow.getName()));
+                       ExecutionFlowDescriptor efd = getExecutionFlowDescriptor(executionFlow);
+                       ExecutionSpec executionSpec = efd.getExecutionSpec();
 
-                       ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
-                       Assert.notNull(executionSpec);
-                       Assert.notNull(executionSpec.getName());
+                       // Add execution spec if necessary
+                       if (!md.getExecutionSpecs().contains(executionSpec))
+                               md.getExecutionSpecs().add(executionSpec);
 
-                       Map<String, Object> values = new TreeMap<String, Object>();
-                       for (String key : executionSpec.getAttributes().keySet()) {
-                               ExecutionSpecAttribute attribute = executionSpec
-                                               .getAttributes().get(key);
+                       // Add execution flow
+                       set.add(efd);
+                       // md.getExecutionFlows().add(efd);
+               }
+               md.getExecutionFlows().addAll(set);
+       }
 
-                               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) {
-                                       if (attribute.getIsFrozen()) {
-                                               values.put(key, new RefValue(REF_VALUE_INTERNAL));
-                                       } else
-                                               values.put(key, buildRefValue(
-                                                               (RefSpecAttribute) attribute, executionFlow,
-                                                               key));
+       public ExecutionFlowDescriptor getExecutionFlowDescriptor(
+                       ExecutionFlow executionFlow) {
+               if (executionFlow.getName() == null)
+                       throw new FlowConfigurationException("Flow name is null: "
+                                       + executionFlow);
+               String name = executionFlow.getName();
+
+               ExecutionSpec executionSpec = executionFlow.getExecutionSpec();
+               if (executionSpec == null)
+                       throw new FlowConfigurationException("Execution spec is null: "
+                                       + executionFlow);
+               if (executionSpec.getName() == null)
+                       throw new FlowConfigurationException(
+                                       "Execution spec name is null: " + executionSpec);
+
+               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 {
-                                       throw new SlcException("Unkown spec attribute type "
-                                                       + attribute.getClass());
+                                       // no need to add a primitive value if it is not set,
+                                       // all necessary information is in the spec
                                }
-
+                       } else if (attribute instanceof RefSpecAttribute) {
+                               if (attribute.getIsConstant()) {
+                                       values.put(key, new RefValue(REF_VALUE_INTERNAL));
+                               } else
+                                       values.put(
+                                                       key,
+                                                       buildRefValue((RefSpecAttribute) attribute,
+                                                                       executionFlow, key));
+                       } else {
+                               throw new FlowConfigurationException(
+                                               "Unkown spec attribute type " + attribute.getClass());
                        }
 
-                       ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name,
-                                       values, executionSpec);
-                       if (executionFlow.getPath() != null)
-                               efd.setPath(executionFlow.getPath());
-                       else
-                               efd.setPath("");
+               }
+
+               ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, null,
+                               values, executionSpec);
+               // if (executionFlow.getPath() != null)
+               // efd.setPath(executionFlow.getPath());
+               // else
+               // efd.setPath("");
 
-                       // Takes description from spring
+               // Takes description from spring
+               BeanFactory bf = getBeanFactory();
+               if (bf != null) {
                        BeanDefinition bd = getBeanFactory().getBeanDefinition(name);
                        efd.setDescription(bd.getDescription());
-
-                       // Add execution spec if necessary
-                       if (!md.getExecutionSpecs().contains(executionSpec))
-                               md.getExecutionSpecs().add(executionSpec);
-
-                       // Add execution flow
-                       set.add(efd);
-                       // md.getExecutionFlows().add(efd);
                }
-               md.getExecutionFlows().addAll(set);
+               return efd;
        }
 
        @SuppressWarnings(value = { "unchecked" })
@@ -206,7 +232,7 @@ public class DefaultExecutionFlowDescriptorConverter implements
                RefValue refValue = new RefValue();
                // FIXME: UI should be able to deal with other types
                refValue.setType(REF_VALUE_TYPE_BEAN_NAME);
-               Class targetClass = rsa.getTargetClass();
+               Class<?> targetClass = rsa.getTargetClass();
                String primitiveType = PrimitiveUtils.classAsType(targetClass);
                if (primitiveType != null) {
                        if (executionFlow.isSetAsParameter(key)) {
@@ -221,8 +247,7 @@ public class DefaultExecutionFlowDescriptorConverter implements
                                String ref = null;
                                Object value = executionFlow.getParameter(key);
                                if (applicationContext == null) {
-                                       log
-                                                       .warn("No application context declared, cannot scan ref value.");
+                                       log.warn("No application context declared, cannot scan ref value.");
                                        ref = value.toString();
                                } else {
 
@@ -248,15 +273,15 @@ public class DefaultExecutionFlowDescriptorConverter implements
                                        }
                                }
                                if (ref == null) {
-                                       log
-                                                       .warn("Cannot define reference for ref spec attribute "
-                                                                       + key
-                                                                       + " in "
-                                                                       + executionFlow
-                                                                       + " ("
-                                                                       + rsa
-                                                                       + ")."
-                                                                       + " If it is an inner bean consider put it frozen.");
+                                       if (log.isTraceEnabled())
+                                               log.trace("Cannot define reference for ref spec attribute "
+                                                               + key
+                                                               + " in "
+                                                               + executionFlow
+                                                               + " ("
+                                                               + rsa
+                                                               + ")."
+                                                               + " If it is an inner bean consider put it frozen.");
                                        ref = REF_VALUE_INTERNAL;
                                } else {
                                        if (log.isTraceEnabled())
@@ -271,7 +296,10 @@ public class DefaultExecutionFlowDescriptorConverter implements
                }
        }
 
+       /** @return can be null */
        private ConfigurableListableBeanFactory getBeanFactory() {
+               if (applicationContext == null)
+                       return null;
                return ((ConfigurableApplicationContext) applicationContext)
                                .getBeanFactory();
        }
@@ -284,28 +312,50 @@ public class DefaultExecutionFlowDescriptorConverter implements
 
        private static class ExecutionFlowDescriptorComparator implements
                        Comparator<ExecutionFlowDescriptor> {
+               @SuppressWarnings("deprecation")
                public int compare(ExecutionFlowDescriptor o1,
                                ExecutionFlowDescriptor o2) {
                        // TODO: write unit tests for this
-                       if (StringUtils.hasText(o1.getPath())
-                                       && StringUtils.hasText(o2.getPath())) {
-                               if (o1.getPath().equals(o2.getPath()))
-                                       return o1.getName().compareTo(o2.getName());
-                               else if (o1.getPath().startsWith(o2.getPath()))
+
+                       String name1 = o1.getName();
+                       String name2 = o2.getName();
+
+                       String path1 = o1.getPath();
+                       String path2 = o2.getPath();
+
+                       // Check whether name include path
+                       int lastIndex1 = name1.lastIndexOf('/');
+                       // log.debug(name1+", "+lastIndex1);
+                       if (!StringUtils.hasText(path1) && lastIndex1 >= 0) {
+                               path1 = name1.substring(0, lastIndex1);
+                               name1 = name1.substring(lastIndex1 + 1);
+                       }
+
+                       int lastIndex2 = name2.lastIndexOf('/');
+                       if (!StringUtils.hasText(path2) && lastIndex2 >= 0) {
+                               path2 = name2.substring(0, lastIndex2);
+                               name2 = name2.substring(lastIndex2 + 1);
+                       }
+
+                       // Perform the actual comparison
+                       if (StringUtils.hasText(path1) && StringUtils.hasText(path2)) {
+                               if (path1.equals(path2))
+                                       return name1.compareTo(name2);
+                               else if (path1.startsWith(path2))
                                        return -1;
-                               else if (o2.getPath().startsWith(o1.getPath()))
+                               else if (path2.startsWith(path1))
                                        return 1;
                                else
-                                       return o1.getPath().compareTo(o2.getPath());
-                       } else if (!StringUtils.hasText(o1.getPath())
-                                       && StringUtils.hasText(o2.getPath())) {
+                                       return path1.compareTo(path2);
+                       } else if (!StringUtils.hasText(path1)
+                                       && StringUtils.hasText(path2)) {
                                return 1;
-                       } else if (StringUtils.hasText(o1.getPath())
-                                       && !StringUtils.hasText(o2.getPath())) {
+                       } else if (StringUtils.hasText(path1)
+                                       && !StringUtils.hasText(path2)) {
                                return -1;
-                       } else if (!StringUtils.hasText(o1.getPath())
-                                       && !StringUtils.hasText(o2.getPath())) {
-                               return o1.getName().compareTo(o2.getName());
+                       } else if (!StringUtils.hasText(path1)
+                                       && !StringUtils.hasText(path2)) {
+                               return name1.compareTo(name2);
                        } else {
                                return 0;
                        }