dnet-applications/libs/dnet-wf-service/src/main/java/eu/dnetlib/manager/wf/nodes/ProcessNode.java

127 lines
4.1 KiB
Java

package eu.dnetlib.manager.wf.nodes;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanNameAware;
import eu.dnetlib.manager.wf.annotations.WfInputParam;
import eu.dnetlib.manager.wf.annotations.WfOutputParam;
import eu.dnetlib.manager.wf.workflows.procs.Env;
import eu.dnetlib.manager.wf.workflows.procs.Token;
import eu.dnetlib.manager.wf.workflows.util.NodeCallback;
public abstract class ProcessNode implements BeanNameAware {
private static final Log log = LogFactory.getLog(ProcessNode.class);
private String beanName;
private String nodeName;
public abstract void execute(final Token token, NodeCallback callback);
public final void initInputParams(final Map<String, Object> params) {
findFields(getClass(), WfInputParam.class).forEach(field -> {
final String annName = field.getAnnotation(WfInputParam.class).value();
if (StringUtils.isNotBlank(annName)) {
fieldValue(field, params.get(annName));
} else {
fieldValue(field, params.get(field.getName()));
}
});
}
public final void saveOutputParams(final Env env) {
findFields(getClass(), WfOutputParam.class).forEach(field -> {
final String annName = field.getAnnotation(WfOutputParam.class).value();
if (StringUtils.isNotBlank(annName)) {
env.setAttribute(annName, fieldValue(field));
} else {
env.setAttribute(field.getName(), fieldValue(field));
}
});
}
private final void fieldValue(final Field field, final Object value) {
try {
field.setAccessible(true);
final Class<?> fieldClass = field.getType();
if (value.getClass().isAssignableFrom(fieldClass)) {
field.set(this, value);
} else if (String.class.isAssignableFrom(fieldClass)) {
field.set(this, value.toString());
} else if (long.class.isAssignableFrom(fieldClass) || Long.class.isAssignableFrom(fieldClass)) {
field.set(this, NumberUtils.toLong(value.toString()));
} else if (int.class.isAssignableFrom(fieldClass) || Integer.class.isAssignableFrom(fieldClass)) {
field.set(this, NumberUtils.toInt(value.toString()));
} else if (double.class.isAssignableFrom(fieldClass) || Double.class.isAssignableFrom(fieldClass)) {
field.set(this, NumberUtils.toDouble(value.toString()));
} else if (float.class.isAssignableFrom(fieldClass) || Float.class.isAssignableFrom(fieldClass)) {
field.set(this, NumberUtils.toFloat(value.toString()));
} else {
log.error("Not Mapped Type, Field class: " + fieldClass + ", Value: " + value + " (" + value.getClass() + ")");
throw new RuntimeException("Not Mapped Type: " + fieldClass);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
log.error("Error setting field " + field.getName(), e);
throw new RuntimeException(e);
}
}
private Object fieldValue(final Field field) {
try {
field.setAccessible(true);
return field.get(this);
} catch (IllegalArgumentException | IllegalAccessException e) {
log.error("Error getting field " + field.getName(), e);
throw new RuntimeException(e);
}
}
public String getBeanName() {
return this.beanName;
}
@Override
public void setBeanName(final String beanName) {
this.beanName = beanName;
}
public String getNodeName() {
return this.nodeName;
}
public void setNodeName(final String nodeName) {
this.nodeName = nodeName;
}
@Override
public String toString() {
return String.format("[node beanName=%s, name=%s, object: %s]", this.beanName, this.nodeName, super.toString());
}
private final Set<Field> findFields(final Class<?> clazz, final Class<? extends Annotation> ann) {
final Set<Field> fields = new HashSet<>();
if (clazz != null) {
fields.addAll(findFields(clazz.getSuperclass(), ann));
for (final Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(ann)) {
fields.add(field);
}
}
}
return fields;
}
}