X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.core%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fcore%2Fexecution%2FDefaultExecutionFlowDescriptorConverter.java;h=cec087f9d8f017c70d52cb3d4c109b80177f6b83;hb=6de9c4036be9e318f59a0ffa187570f5999c53cb;hp=7dc8d00cb74b97009f3240ae9691e81a5bb513b0;hpb=bfb5bb54702d2e706ab7a8b0bc4af94eada6e01c;p=gpl%2Fargeo-slc.git 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 index 7dc8d00cb..cec087f9d 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Mathieu Baudier + * 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 convertValues( ExecutionFlowDescriptor executionFlowDescriptor) { Map 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 values = new TreeMap(); - 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 values = new TreeMap(); + 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 { + @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; }