/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.inputprovider.execution; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.ObjectWriter; import org.codehaus.jackson.node.ObjectNode; import org.codehaus.jackson.node.TextNode; import de.rcenvironment.components.inputprovider.common.InputProviderComponentConstants; import de.rcenvironment.core.component.api.ComponentUtils; import de.rcenvironment.core.component.model.configuration.api.ConfigurationDefinitionConstants; import de.rcenvironment.core.component.model.configuration.api.PlaceholdersMetaDataConstants; 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.component.workflow.model.api.WorkflowDescriptionPersistenceHandler; import de.rcenvironment.core.datamodel.api.DataType; import de.rcenvironment.core.utils.common.JsonUtils; import de.rcenvironment.core.utils.common.StringUtils; /** * Implementation of {@link PersistentComponentDescriptionUpdater}. * * @author Sascha Zur * @author Doreen Seider */ public class InputProviderPersistentComponentDescriptionUpdater implements PersistentComponentDescriptionUpdater { private static final String VERSION_3_0 = "3.0"; private static final String VERSION_3_1 = "3.1"; private static final String VERSION_3_2 = "3.2"; private static final String CURRENT_VERSION = VERSION_3_2; @Override public String[] getComponentIdentifiersAffectedByUpdate() { return InputProviderComponentConstants.COMPONENT_IDS; } @Override public int getFormatVersionsAffectedByUpdate(String persistentComponentDescriptionVersion, boolean silent) { int update = PersistentDescriptionFormatVersion.NONE; if (!silent) { if ((persistentComponentDescriptionVersion == null || persistentComponentDescriptionVersion.compareTo(VERSION_3_0) < 0)) { update = update | PersistentDescriptionFormatVersion.FOR_VERSION_THREE; } if ((persistentComponentDescriptionVersion != null && persistentComponentDescriptionVersion.compareTo(CURRENT_VERSION) < 0)) { update = update | PersistentDescriptionFormatVersion.AFTER_VERSION_THREE; } } return update; } @Override public PersistentComponentDescription performComponentDescriptionUpdate(int formatVersion, PersistentComponentDescription description, boolean silent) throws IOException { if (!silent) { switch (formatVersion) { case PersistentDescriptionFormatVersion.FOR_VERSION_THREE: description = updateTo30(description); break; case PersistentDescriptionFormatVersion.AFTER_VERSION_THREE: if (description.getComponentVersion().compareTo(VERSION_3_1) < 0) { description = updateFrom30To31(description); } if (description.getComponentVersion().compareTo(VERSION_3_2) < 0) { description = updateFrom31To32(description); } break; default: break; } } return description; } /** * Updates the component from version 0 to 3.0. * */ private PersistentComponentDescription updateTo30(PersistentComponentDescription description) throws JsonParseException, IOException { description = PersistentComponentDescriptionUpdaterUtils.updateAllDynamicEndpointsToIdentifier( WorkflowDescriptionPersistenceHandler.DYNAMIC_OUTPUTS, "default", description); description.setComponentVersion(VERSION_3_0); return description; } /** * Updates the component from version 3.0 to 3.1. * */ private PersistentComponentDescription updateFrom30To31(PersistentComponentDescription description) throws JsonParseException, IOException { ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode node = mapper.readTree(description.getComponentDescriptionAsString()); JsonNode configNode = node.get(WorkflowDescriptionPersistenceHandler.DYNAMIC_OUTPUTS); Iterator<JsonNode> iterator = configNode.getElements(); while (iterator.hasNext()) { ObjectNode outputNode = (ObjectNode) iterator.next(); if (outputNode.get(WorkflowDescriptionPersistenceHandler.DATATYPE).getTextValue().equals(DataType.FileReference.name())) { ObjectNode metaDataNode = (ObjectNode) outputNode.get(WorkflowDescriptionPersistenceHandler.METADATA); metaDataNode.put(InputProviderComponentConstants.META_VALUE, TextNode.valueOf(StringUtils.format(ConfigurationDefinitionConstants.PLACEHOLDER_FORMAT_STRING, outputNode.get(WorkflowDescriptionPersistenceHandler.NAME).getTextValue()))); metaDataNode.put(InputProviderComponentConstants.META_FILESOURCETYPE, TextNode.valueOf(InputProviderComponentConstants.META_FILESOURCETYPE_ATWORKFLOWSTART)); } } ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(node)); description.setComponentVersion(VERSION_3_1); return description; } /** * Updates the component from version 3.1 to 3.2. * */ private PersistentComponentDescription updateFrom31To32(PersistentComponentDescription description) throws JsonParseException, IOException { final String filePlaceholderRegex = "\\$\\{((\\w*)(\\.))?((\\*)(\\.))?(.*) \\(File\\)\\}"; final String directoryPlaceholderRegex = "\\$\\{((\\w*)(\\.))?((\\*)(\\.))?(.*) \\(Directory\\)\\}"; ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode node = mapper.readTree(description.getComponentDescriptionAsString()); ObjectNode configurationsNode = (ObjectNode) node.get(WorkflowDescriptionPersistenceHandler.CONFIGURATION); if (configurationsNode != null) { Iterator<Entry<String, JsonNode>> fields = configurationsNode.getFields(); Map<String, String> fileOutputs = new HashMap<>(); Map<String, String> dirOutputs = new HashMap<>(); while (fields.hasNext()) { Entry<String, JsonNode> configurationNode = fields.next(); String ouputName = configurationNode.getKey(); String value = ((TextNode) configurationNode.getValue()).getTextValue(); if (value.matches(ComponentUtils.PLACEHOLDER_REGEX) || value.matches(filePlaceholderRegex)) { fields.remove(); fileOutputs.put(ouputName, value); } else if (value.matches(directoryPlaceholderRegex)) { fields.remove(); dirOutputs.put(ouputName, value); } } for (String outputName : fileOutputs.keySet()) { configurationsNode.put(outputName, fileOutputs.get(outputName).replace(" (File)", "")); configurationsNode.put(outputName + PlaceholdersMetaDataConstants.DATA_TYPE, PlaceholdersMetaDataConstants.TYPE_FILE); } for (String outputName : dirOutputs.keySet()) { configurationsNode.put(outputName, dirOutputs.get(outputName).replace(" (Directory)", "")); configurationsNode.put(outputName + PlaceholdersMetaDataConstants.DATA_TYPE, PlaceholdersMetaDataConstants.TYPE_DIR); } } ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(node)); description.setComponentVersion(VERSION_3_2); return description; } }