/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.joiner.execution; import java.io.IOException; import java.util.UUID; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.ObjectWriter; import org.codehaus.jackson.node.ArrayNode; import org.codehaus.jackson.node.JsonNodeFactory; import org.codehaus.jackson.node.ObjectNode; import org.codehaus.jackson.node.TextNode; import de.rcenvironment.components.joiner.common.JoinerComponentConstants; import de.rcenvironment.core.component.update.api.PersistentComponentDescription; import de.rcenvironment.core.component.update.api.PersistentComponentDescriptionUpdaterUtils; import de.rcenvironment.core.component.update.api.PersistentDescriptionFormatVersion; import de.rcenvironment.core.component.update.spi.PersistentComponentDescriptionUpdater; import de.rcenvironment.core.utils.common.JsonUtils; /** * Implementation of {@link PersistentComponentDescriptionUpdater}. * * @author Sascha Zur * @author Doreen Seider */ public class JoinerPersistentComponentDescriptionUpdater implements PersistentComponentDescriptionUpdater { private static final String DATATYPE = "datatype"; private static final String CONFIGURATION = "configuration"; private static final String MERGED = "Merged"; private static final String IDENTIFIER = "identifier"; private static final String DYNAMIC_INPUTS = "dynamicInputs"; private static final String NAME = "name"; private static final String DYNAMIC_ADD_INPUTS = "addInput"; private static final String V1_0 = "1.0"; private static final String V3_0 = "3.0"; private static final String V3_1 = "3.1"; private static final String V3_2 = "3.2"; private static final String V3_3 = "3.3"; private final JsonFactory jsonFactory = new JsonFactory(); @Override public String[] getComponentIdentifiersAffectedByUpdate() { return JoinerComponentConstants.COMPONENT_IDS; } @Override public int getFormatVersionsAffectedByUpdate(String persistentComponentDescriptionVersion, boolean silent) { int versionsToUpdate = PersistentDescriptionFormatVersion.NONE; if (silent && (persistentComponentDescriptionVersion == null || persistentComponentDescriptionVersion.compareTo(V1_0) < 0)) { versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.BEFORE_VERSON_THREE; } else if (silent && persistentComponentDescriptionVersion.compareTo(V3_3) < 0) { versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.AFTER_VERSION_THREE; } else if (!silent && persistentComponentDescriptionVersion != null) { if (persistentComponentDescriptionVersion.compareTo(V3_0) < 0) { versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.FOR_VERSION_THREE; } if (persistentComponentDescriptionVersion.compareTo(V3_2) < 0) { versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.AFTER_VERSION_THREE; } } return versionsToUpdate; } @Override public PersistentComponentDescription performComponentDescriptionUpdate(int formatVersion, PersistentComponentDescription description, boolean silent) throws IOException { if (silent && formatVersion == PersistentDescriptionFormatVersion.BEFORE_VERSON_THREE) { return updateToV1(description); } else if (!silent && formatVersion == PersistentDescriptionFormatVersion.FOR_VERSION_THREE) { return updateToV3(description); } else if (!silent && formatVersion == PersistentDescriptionFormatVersion.AFTER_VERSION_THREE) { switch (description.getComponentVersion()) { case V3_0: description = updateFromV3ToV31(description); case V3_1: description = updateFromV31ToV32(description); case V3_2: description = updateFromV32ToV33(description); break; default: break; } } else if (silent && formatVersion == PersistentDescriptionFormatVersion.AFTER_VERSION_THREE) { switch (description.getComponentVersion()) { case V3_2: description = updateFromV32ToV33(description); break; default: break; } } return description; } private PersistentComponentDescription updateFromV32ToV33(PersistentComponentDescription description) throws JsonParseException, IOException { ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); ObjectNode node = (ObjectNode) mapper.readTree(description.getComponentDescriptionAsString()); String dataType; String inputCount; if (node.has(DYNAMIC_INPUTS)) { ArrayNode dynInputs = (ArrayNode) node.get(DYNAMIC_INPUTS); ObjectNode firstInput = (ObjectNode) dynInputs.get(0); dataType = firstInput.get(DATATYPE).getTextValue(); inputCount = String.valueOf(dynInputs.size()); } else { dataType = "Float"; inputCount = "0"; } ObjectNode configuration; if (node.has(CONFIGURATION)) { configuration = (ObjectNode) node.get(CONFIGURATION); configuration.removeAll(); } else { configuration = node.putObject(CONFIGURATION); } configuration.put(JoinerComponentConstants.INPUT_COUNT, inputCount); configuration.put(JoinerComponentConstants.DATATYPE, dataType); ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(node)); description.setComponentVersion(V3_3); return description; } private PersistentComponentDescription updateFromV31ToV32(PersistentComponentDescription description) throws JsonParseException, IOException { JsonParser jsonParser = jsonFactory.createJsonParser(description.getComponentDescriptionAsString()); ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode rootNode = mapper.readTree(jsonParser); TextNode nameNode = (TextNode) rootNode.get(NAME); String nodeName = nameNode.getTextValue(); if (nodeName.contains("Merger")) { nodeName = nodeName.replaceAll("Merger", "Joiner"); ((ObjectNode) rootNode).put(NAME, TextNode.valueOf(nodeName)); } final String joinedString = "Joined"; ArrayNode staticOutputs = (ArrayNode) rootNode.get("staticOutputs"); ObjectNode staticOutput = (ObjectNode) staticOutputs.get(0); staticOutput.put(NAME, TextNode.valueOf(joinedString)); JsonNode dynInputs = rootNode.get("dynamicInputs"); if (dynInputs != null) { for (JsonNode dynInput : dynInputs) { ((ObjectNode) dynInput).put("epIdentifier", TextNode.valueOf(JoinerComponentConstants.DYNAMIC_INPUT_ID)); } } ObjectNode configuration = (ObjectNode) rootNode.get(CONFIGURATION); if (configuration != null) { String number = configuration.get(MERGED).getTextValue(); configuration.remove(MERGED); configuration.put(joinedString, TextNode.valueOf(number)); } else { configuration = mapper.createObjectNode(); configuration.put(joinedString, TextNode.valueOf("2")); ((ObjectNode) rootNode).put(CONFIGURATION, configuration); } ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(rootNode)); description.setComponentVersion(V3_2); jsonParser.close(); return description; } private PersistentComponentDescription updateFromV3ToV31(PersistentComponentDescription description) throws JsonParseException, IOException { JsonParser jsonParser = jsonFactory.createJsonParser(description.getComponentDescriptionAsString()); ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode rootNode = mapper.readTree(jsonParser); JsonNode staticInputs = rootNode.get("staticInputs"); if (staticInputs != null) { for (JsonNode staticInput : staticInputs) { String name = staticInput.get(NAME).getTextValue(); String number = name.substring(name.length() - 3); for (JsonNode dynInput : rootNode.get(DYNAMIC_INPUTS)) { if (dynInput.get(NAME).getTextValue().endsWith(number)) { ((ObjectNode) dynInput).put(IDENTIFIER, staticInput.get(IDENTIFIER)); } } } } ((ObjectNode) rootNode).remove("staticInputs"); ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(rootNode)); description.setComponentVersion(V3_1); jsonParser.close(); return description; } /** * Updates the component from version 0 to 3.0. * */ private PersistentComponentDescription updateToV3(PersistentComponentDescription description) throws JsonParseException, IOException { description = PersistentComponentDescriptionUpdaterUtils.updateAllDynamicEndpointsToIdentifier(DYNAMIC_INPUTS, JoinerComponentConstants.DYNAMIC_INPUT_ID, description); JsonParser jsonParser = jsonFactory.createJsonParser(description.getComponentDescriptionAsString()); ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode rootNode = mapper.readTree(jsonParser); ArrayNode staticOutputs = JsonNodeFactory.instance.arrayNode(); ObjectNode output = JsonNodeFactory.instance.objectNode(); output.put(NAME, TextNode.valueOf(MERGED)); output.put(IDENTIFIER, TextNode.valueOf(UUID.randomUUID().toString())); output.put(DATATYPE, TextNode.valueOf(rootNode.get(DYNAMIC_INPUTS).get(0).get(DATATYPE).getTextValue())); staticOutputs.add(output); ((ObjectNode) rootNode).put("staticOutputs", staticOutputs); ((ObjectNode) rootNode).remove("dynamicOutputs"); ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(rootNode)); description.setComponentVersion(V3_0); jsonParser.close(); return description; } private PersistentComponentDescription updateToV1(PersistentComponentDescription description) throws IOException, JsonParseException, JsonProcessingException, JsonGenerationException, JsonMappingException { JsonParser jsonParser = jsonFactory.createJsonParser(description.getComponentDescriptionAsString()); ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode rootNode = mapper.readTree(jsonParser); ArrayNode dynamicInputsNode = (ArrayNode) rootNode.findPath(DYNAMIC_ADD_INPUTS); ArrayNode newDynamicInputsNode = JsonNodeFactory.instance.arrayNode(); for (JsonNode endpoint : dynamicInputsNode) { String newString = "Input " + endpoint.getTextValue() .substring(endpoint.getTextValue().indexOf("_") + 1); newDynamicInputsNode.add(TextNode.valueOf(newString)); } ((ObjectNode) rootNode).remove(DYNAMIC_ADD_INPUTS); ((ObjectNode) rootNode).put(DYNAMIC_ADD_INPUTS, newDynamicInputsNode); ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(rootNode)); description.setComponentVersion(V1_0); jsonParser.close(); return description; } }