/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.component.execution.internal; import java.io.IOException; import java.util.Iterator; import java.util.LinkedList; import java.util.Queue; import java.util.UUID; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.node.ArrayNode; import org.codehaus.jackson.node.ObjectNode; import de.rcenvironment.core.component.execution.api.WorkflowGraphHop; import de.rcenvironment.core.datamodel.api.DataType; import de.rcenvironment.core.datamodel.types.api.InternalTD; import de.rcenvironment.core.utils.common.JsonUtils; /** * Internal value sent to ouputs to control the workflow. * * @author Doreen Seider */ public class InternalTDImpl implements InternalTD { private static final String SERIALIZE_KEY_TYPE = "t"; private static final String SERIALIZE_KEY_IDENTIFIER = "i"; private static final String SERIALIZE_KEY_HOPS = "h"; private static final String SERIALIZE_KEY_PAYLOAD = "p"; /** * Type of possible purposes an {@link InternalTDImpl} can have. * * @author Doreen Seider */ public enum InternalTDType { /** Used to detect if a workflow is finished. */ WorkflowFinish, /** Used to reset nested loops. */ NestedLoopReset, /** Used to announce failure to loop driver. */ FailureInLoop; } private final String identifier; private final InternalTDType type; private Queue<WorkflowGraphHop> hopsToTraverse = null; private String payload = null; public InternalTDImpl(InternalTDType type) { this(type, UUID.randomUUID().toString()); } public InternalTDImpl(InternalTDType type, String identifier) { this.identifier = identifier; this.type = type; } public InternalTDImpl(InternalTDType type, Queue<WorkflowGraphHop> hopsToTraverse) { this(type, UUID.randomUUID().toString(), hopsToTraverse); } public InternalTDImpl(InternalTDType type, String identifier, Queue<WorkflowGraphHop> hopsToTraverse) { this(type, identifier); this.hopsToTraverse = hopsToTraverse; } public InternalTDImpl(InternalTDType type, Queue<WorkflowGraphHop> hopsToTraverse, String payload) { this(type, UUID.randomUUID().toString(), hopsToTraverse, payload); } public InternalTDImpl(InternalTDType type, String identifier, Queue<WorkflowGraphHop> hopsToTraverse, String payload) { this(type, identifier); this.hopsToTraverse = hopsToTraverse; this.payload = payload; } @Override public DataType getDataType() { return DataType.Internal; } public String getIdentifier() { return identifier; } public InternalTDType getType() { return type; } public Queue<WorkflowGraphHop> getHopsToTraverse() { return hopsToTraverse; } public String getPayload() { return payload; } @Override public String toString() { return "Internal: " + getType().name(); } /** * @return serialized {@link InternalTDImpl} */ public String serialize() { ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); ObjectNode rootNode = mapper.createObjectNode(); rootNode.put(SERIALIZE_KEY_TYPE, getType().name()); rootNode.put(SERIALIZE_KEY_IDENTIFIER, getIdentifier()); ArrayNode hopsArrayNode = mapper.createArrayNode(); Queue<WorkflowGraphHop> hops = getHopsToTraverse(); if (hops != null) { for (WorkflowGraphHop hop : getHopsToTraverse()) { ArrayNode hopArrayNode = mapper.createArrayNode(); hopArrayNode.add(hop.getHopExecutionIdentifier()); hopArrayNode.add(hop.getHopOuputName()); hopArrayNode.add(hop.getTargetExecutionIdentifier()); hopArrayNode.add(hop.getTargetInputName()); hopsArrayNode.add(hopArrayNode); } rootNode.put(SERIALIZE_KEY_HOPS, hopsArrayNode); } String pyld = getPayload(); if (pyld != null) { rootNode.put(SERIALIZE_KEY_PAYLOAD, pyld); } return rootNode.toString(); } /** * Creates {@link InternalTDImpl} instance out of a serialized string. * * @param value serialized string * @return {@link InternalTDImpl} instance */ public static InternalTDImpl fromString(String value) { ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); ObjectNode rootNode; try { rootNode = (ObjectNode) mapper.readTree(value); } catch (IOException e) { throw new IllegalArgumentException(e); } InternalTDType type = InternalTDImpl.InternalTDType.valueOf(rootNode.get(SERIALIZE_KEY_TYPE).getTextValue()); String identifier = rootNode.get(SERIALIZE_KEY_IDENTIFIER).getTextValue(); Queue<WorkflowGraphHop> hops = null; if (rootNode.has(SERIALIZE_KEY_HOPS)) { ArrayNode hopsArrayNode = (ArrayNode) rootNode.get(SERIALIZE_KEY_HOPS); hops = new LinkedList<>(); Iterator<JsonNode> hopsElements = hopsArrayNode.getElements(); while (hopsElements.hasNext()) { ArrayNode hopArrayNode = (ArrayNode) hopsElements.next(); hops.add(new WorkflowGraphHop(hopArrayNode.get(0).asText(), hopArrayNode.get(1).asText(), hopArrayNode.get(2).asText(), hopArrayNode.get(3).asText())); } } String pyld = null; if (rootNode.has(SERIALIZE_KEY_PAYLOAD)) { pyld = rootNode.get(SERIALIZE_KEY_PAYLOAD).getTextValue(); } return new InternalTDImpl(type, identifier, hops, pyld); } }