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=7dc8d00cb74b97009f3240ae9691e81a5bb513b0;hb=bfb5bb54702d2e706ab7a8b0bc4af94eada6e01c;hp=d8429d192d1d9675516d47a6365e0e199426f887;hpb=9f0c9b3c49a556b671e6b1b6d88cf83357d1f028;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 d8429d192..7dc8d00cb 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,8 +1,27 @@ +/* + * Copyright (C) 2010 Mathieu Baudier + * + * 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.core.execution; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; +import java.util.SortedSet; import java.util.TreeMap; +import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -22,13 +41,14 @@ 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; public class DefaultExecutionFlowDescriptorConverter implements ExecutionFlowDescriptorConverter, ApplicationContextAware { public final static String REF_VALUE_TYPE_BEAN_NAME = "beanName"; /** Workaround for https://www.spartadn.com/bugzilla/show_bug.cgi?id=206 */ - private final static String REF_VALUE_IS_FROZEN = "__frozen"; + private final static String REF_VALUE_INTERNAL = "[internal]"; private final static Log log = LogFactory .getLog(DefaultExecutionFlowDescriptorConverter.class); @@ -39,11 +59,16 @@ public class DefaultExecutionFlowDescriptorConverter implements ExecutionFlowDescriptor executionFlowDescriptor) { Map values = executionFlowDescriptor.getValues(); Map convertedValues = new HashMap(); + ExecutionSpec executionSpec = executionFlowDescriptor + .getExecutionSpec(); + + if (executionSpec == null && log.isTraceEnabled()) + log.warn("Execution spec is null for " + executionFlowDescriptor); - if (values != null) { + if (values != null && executionSpec != null) { values: for (String key : values.keySet()) { - ExecutionSpecAttribute attribute = executionFlowDescriptor - .getExecutionSpec().getAttributes().get(key); + ExecutionSpecAttribute attribute = executionSpec + .getAttributes().get(key); if (attribute.getIsFrozen()) continue values; @@ -55,18 +80,52 @@ public class DefaultExecutionFlowDescriptorConverter implements convertedValues.put(key, primitiveValue.getValue()); } else if (value instanceof RefValue) { RefValue refValue = (RefValue) value; - - if (REF_VALUE_TYPE_BEAN_NAME.equals(refValue.getType())) - if (refValue.getRef() != null) { - Object obj = applicationContext.getBean(refValue - .getRef()); + String type = refValue.getType(); + if (REF_VALUE_TYPE_BEAN_NAME.equals(type)) { + // FIXME: UI should send all information about spec + // - targetClass + // - name + // String executionSpecName = executionSpec.getName(); + // ExecutionSpec localSpec = (ExecutionSpec) + // applicationContext + // .getBean(executionSpecName); + // RefSpecAttribute localAttr = (RefSpecAttribute) + // localSpec + // .getAttributes().get(key); + // Class targetClass = localAttr.getTargetClass(); + // + // String primitiveType = PrimitiveUtils + // .classAsType(targetClass); + String primitiveType = null; + if (primitiveType != null) { + // not active + String ref = refValue.getRef(); + Object obj = PrimitiveUtils.convert(primitiveType, + ref); convertedValues.put(key, obj); } else { - log.warn("Cannot interpret " + refValue); + String ref = refValue.getRef(); + if (ref != null && !ref.equals(REF_VALUE_INTERNAL)) { + Object obj = null; + if (applicationContext.containsBean(ref)) { + obj = applicationContext.getBean(ref); + } else { + // FIXME: hack in order to pass primitive + obj = ref; + } + convertedValues.put(key, obj); + } else { + log.warn("Cannot interpret " + refValue); + } } - else + } else if (PrimitiveUtils.typeAsClass(type) != null) { + String ref = refValue.getRef(); + Object obj = PrimitiveUtils.convert(type, ref); + convertedValues.put(key, obj); + } else { throw new UnsupportedException("Ref value type", refValue.getType()); + } } } } @@ -75,6 +134,8 @@ public class DefaultExecutionFlowDescriptorConverter implements public void addFlowsToDescriptor(ExecutionModuleDescriptor md, Map executionFlows) { + SortedSet set = new TreeSet( + new ExecutionFlowDescriptorComparator()); for (String name : executionFlows.keySet()) { ExecutionFlow executionFlow = executionFlows.get(name); @@ -86,7 +147,7 @@ public class DefaultExecutionFlowDescriptorConverter implements Assert.notNull(executionSpec.getName()); Map values = new TreeMap(); - attrs: for (String key : executionSpec.getAttributes().keySet()) { + for (String key : executionSpec.getAttributes().keySet()) { ExecutionSpecAttribute attribute = executionSpec .getAttributes().get(key); @@ -105,7 +166,7 @@ public class DefaultExecutionFlowDescriptorConverter implements } } else if (attribute instanceof RefSpecAttribute) { if (attribute.getIsFrozen()) { - values.put(key, new RefValue(REF_VALUE_IS_FROZEN)); + values.put(key, new RefValue(REF_VALUE_INTERNAL)); } else values.put(key, buildRefValue( (RefSpecAttribute) attribute, executionFlow, @@ -121,6 +182,8 @@ public class DefaultExecutionFlowDescriptorConverter implements values, executionSpec); if (executionFlow.getPath() != null) efd.setPath(executionFlow.getPath()); + else + efd.setPath(""); // Takes description from spring BeanDefinition bd = getBeanFactory().getBeanDefinition(name); @@ -131,56 +194,81 @@ public class DefaultExecutionFlowDescriptorConverter implements md.getExecutionSpecs().add(executionSpec); // Add execution flow - md.getExecutionFlows().add(efd); + set.add(efd); + // md.getExecutionFlows().add(efd); } + md.getExecutionFlows().addAll(set); } @SuppressWarnings(value = { "unchecked" }) protected RefValue buildRefValue(RefSpecAttribute rsa, ExecutionFlow executionFlow, String key) { 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(); + String primitiveType = PrimitiveUtils.classAsType(targetClass); + if (primitiveType != null) { + if (executionFlow.isSetAsParameter(key)) { + Object value = executionFlow.getParameter(key); + refValue.setRef(value.toString()); + } + refValue.setType(primitiveType); + return refValue; + } else { - if (executionFlow.isSetAsParameter(key)) { - String ref = null; - Object value = executionFlow.getParameter(key); - if (applicationContext == null) { - log - .warn("No application context declared, cannot scan ref value."); - ref = value.toString(); - } else { + if (executionFlow.isSetAsParameter(key)) { + String ref = null; + Object value = executionFlow.getParameter(key); + if (applicationContext == null) { + log + .warn("No application context declared, cannot scan ref value."); + ref = value.toString(); + } else { - // look for a ref to the value - Map beans = getBeanFactory().getBeansOfType( - rsa.getTargetClass(), false, false); - // TODO: also check scoped beans - beans: for (String beanName : beans.keySet()) { - Object obj = beans.get(beanName); - if (value instanceof ScopedObject) { - // don't call methods of the target of the scope - if (obj instanceof ScopedObject) - if (value == obj) { + // look for a ref to the value + Map beans = getBeanFactory() + .getBeansOfType(targetClass, false, false); + // TODO: also check scoped beans + beans: for (String beanName : beans.keySet()) { + Object obj = beans.get(beanName); + if (value instanceof ScopedObject) { + // don't call methods of the target of the scope + if (obj instanceof ScopedObject) + if (value == obj) { + ref = beanName; + break beans; + } + } else { + if (obj.equals(value)) { ref = beanName; break beans; } - } else { - if (obj.equals(value)) { - ref = beanName; - break beans; } } } + 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."); + ref = REF_VALUE_INTERNAL; + } else { + if (log.isTraceEnabled()) + log.trace(ref + + " is the reference for ref spec attribute " + + key + " in " + executionFlow + " (" + rsa + + ")"); + } + refValue.setRef(ref); } - if (ref == null) { - if (log.isTraceEnabled()) - log.warn("Cannot define reference for ref spec attribute " - + key + " in " + executionFlow + " (" + rsa + ")"); - } else if (log.isDebugEnabled()) - log.debug(ref + " is the reference for ref spec attribute " - + key + " in " + executionFlow + " (" + rsa + ")"); - refValue.setRef(ref); + return refValue; } - return refValue; } private ConfigurableListableBeanFactory getBeanFactory() { @@ -194,4 +282,34 @@ public class DefaultExecutionFlowDescriptorConverter implements this.applicationContext = applicationContext; } + private static class ExecutionFlowDescriptorComparator implements + Comparator { + 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())) + return -1; + else if (o2.getPath().startsWith(o1.getPath())) + return 1; + else + return o1.getPath().compareTo(o2.getPath()); + } else if (!StringUtils.hasText(o1.getPath()) + && StringUtils.hasText(o2.getPath())) { + return 1; + } else if (StringUtils.hasText(o1.getPath()) + && !StringUtils.hasText(o2.getPath())) { + return -1; + } else if (!StringUtils.hasText(o1.getPath()) + && !StringUtils.hasText(o2.getPath())) { + return o1.getName().compareTo(o2.getName()); + } else { + return 0; + } + } + + } }