diff --git a/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/graph/GraphLoader.java b/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/graph/GraphLoader.java index 2a8aaf76..e181ea1f 100644 --- a/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/graph/GraphLoader.java +++ b/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/graph/GraphLoader.java @@ -110,7 +110,7 @@ public class GraphLoader { if (n.isStart()) { foundStart = true; } - if (!this.nodeHelper.isValidType(n.getType())) { throw new WorkflowManagerException("Invalid node type: " + n.getType()); } + if (!this.nodeHelper.isValid(n)) { throw new WorkflowManagerException("Invalid node type: " + n.getType()); } } if (!foundStart) { throw new WorkflowManagerException("Start node not found"); } } diff --git a/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/util/NodeHelper.java b/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/util/NodeHelper.java index 20ec408c..cfb92be4 100644 --- a/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/util/NodeHelper.java +++ b/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/util/NodeHelper.java @@ -1,14 +1,22 @@ package eu.dnetlib.manager.wf.workflows.util; +import java.util.Map; +import java.util.Set; + import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.stereotype.Component; import eu.dnetlib.errors.WorkflowManagerException; +import eu.dnetlib.manager.wf.annotations.WfNode; import eu.dnetlib.manager.wf.nodes.DefaultJobNode; import eu.dnetlib.manager.wf.nodes.ProcessNode; import eu.dnetlib.manager.wf.nodes.SuccessNode; @@ -19,7 +27,6 @@ import eu.dnetlib.manager.wf.workflows.procs.WorkflowProcess; @Component public class NodeHelper implements ApplicationContextAware { - public static final String beanNamePrefix = "wfNode"; private static final Log log = LogFactory.getLog(NodeHelper.class); private ApplicationContext applicationContext; @@ -30,25 +37,63 @@ public class NodeHelper implements ApplicationContextAware { } else if (StringUtils.isBlank(node.getType())) { return new DefaultJobNode(node.getName()); } else { + try { + Class clazz; - // TODO: Considerare i nodi annotati con WfNode - final ProcessNode pnode = this.applicationContext.getBean(beanNamePrefix + node.getType(), ProcessNode.class); - if (pnode != null) { - pnode.setNodeName(node.getName()); - if (pnode instanceof ProcessAware) { - ((ProcessAware) pnode).setProcess(process); + clazz = findClassForNodeType(node.getType()); + + final ProcessNode pnode = this.applicationContext.getBean(clazz); + + if (pnode != null) { + pnode.setNodeName(node.getName()); + if (pnode instanceof ProcessAware) { + ((ProcessAware) pnode).setProcess(process); + } + return pnode; + } else { + log.error("cannot find bean of type " + node.getType()); + throw new WorkflowManagerException("cannot find bean of type " + node.getType()); } - return pnode; - } else { - log.error("cannot find bean " + beanNamePrefix + node.getType()); - throw new WorkflowManagerException("cannot find bean " + beanNamePrefix + node.getType()); + } catch (final ClassNotFoundException e) { + throw new WorkflowManagerException("Class not found for node " + node.getType()); } } } - public boolean isValidType(final String type) { - return StringUtils.isBlank(type) || this.applicationContext.isPrototype(beanNamePrefix + type) && this.applicationContext - .isTypeMatch(beanNamePrefix + type, ProcessNode.class); + private Class findClassForNodeType(final String type) throws ClassNotFoundException { + final ClassPathScanningCandidateComponentProvider provider = + new ClassPathScanningCandidateComponentProvider(false); + + provider.addIncludeFilter(new AnnotationTypeFilter(WfNode.class)); + + final Set beanDefs = provider.findCandidateComponents("eu.dnetlib.wf.nodes"); + + for (final BeanDefinition bd : beanDefs) { + if (bd instanceof AnnotatedBeanDefinition) { + final Map annotAttributeMap = ((AnnotatedBeanDefinition) bd) + .getMetadata() + .getAnnotationAttributes(WfNode.class.getCanonicalName()); + + if (type.equals(annotAttributeMap.get("value"))) { + final Class clazz = Class.forName(bd.getBeanClassName()); + if (ProcessNode.class.isAssignableFrom(clazz)) { return (Class) Class.forName(bd.getBeanClassName()); } + } + } + } + + throw new ClassNotFoundException("Class not found for type " + type); + } + + public boolean isValid(final GraphNode n) { + if (n.getType() == null) { + return true; + } else { + try { + return findClassForNodeType(n.getType()) != null; + } catch (final ClassNotFoundException e) { + return false; + } + } } @Override