dnet-applications/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/workflows/util/NodeHelper.java

105 lines
3.6 KiB
Java

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;
import eu.dnetlib.manager.wf.workflows.graph.GraphNode;
import eu.dnetlib.manager.wf.workflows.procs.ProcessAware;
import eu.dnetlib.manager.wf.workflows.procs.WorkflowProcess;
@Component
public class NodeHelper implements ApplicationContextAware {
private static final Log log = LogFactory.getLog(NodeHelper.class);
private ApplicationContext applicationContext;
public ProcessNode newProcessNode(final GraphNode node, final WorkflowProcess process) throws WorkflowManagerException {
if (node.isSucessNode()) {
return new SuccessNode();
} else if (StringUtils.isBlank(node.getType())) {
return new DefaultJobNode(node.getName());
} else {
try {
Class<? extends ProcessNode> clazz;
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());
}
} catch (final ClassNotFoundException e) {
throw new WorkflowManagerException("Class not found for node " + node.getType());
}
}
}
private Class<? extends ProcessNode> findClassForNodeType(final String type) throws ClassNotFoundException {
final ClassPathScanningCandidateComponentProvider provider =
new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AnnotationTypeFilter(WfNode.class));
final Set<BeanDefinition> beanDefs = provider.findCandidateComponents("eu.dnetlib.wf.nodes");
for (final BeanDefinition bd : beanDefs) {
if (bd instanceof AnnotatedBeanDefinition) {
final Map<String, Object> 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<? extends ProcessNode>) 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
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}