/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.script.execution; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.ObjectWriter; import org.codehaus.jackson.node.ArrayNode; import org.codehaus.jackson.node.ObjectNode; import org.codehaus.jackson.node.TextNode; import de.rcenvironment.components.script.common.ScriptComponentConstants; 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 ScriptPersistentComponentDescriptionUpdater implements PersistentComponentDescriptionUpdater { private static final String SCRIPT = "script"; private static final String USAGEOFSCRIPT = "usageOfScript"; private static final String V2_9 = "2.9"; 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 static final String V3_4 = "3.4"; private static final String USAGE_OF_SCRIPT = "usage of script"; private static final String CONFIGURATION = "configuration"; @Override public String[] getComponentIdentifiersAffectedByUpdate() { return ScriptComponentConstants.COMPONENT_IDS; } @Override public int getFormatVersionsAffectedByUpdate(String persistentComponentDescriptionVersion, boolean silent) { int versionsToUpdate = PersistentDescriptionFormatVersion.NONE; if (!silent) { if (persistentComponentDescriptionVersion.compareTo(V2_9) >= 0 && persistentComponentDescriptionVersion.compareTo(V3_1) < 0) { versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.FOR_VERSION_THREE; } if (persistentComponentDescriptionVersion.compareTo(V3_1) >= 0 && persistentComponentDescriptionVersion.compareTo(V3_4) < 0) { versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.AFTER_VERSION_THREE; } } return versionsToUpdate; } @Override public PersistentComponentDescription performComponentDescriptionUpdate(int formatVersion, PersistentComponentDescription description, boolean silent) throws IOException { if (!silent) { if (formatVersion == PersistentDescriptionFormatVersion.FOR_VERSION_THREE) { return secondUpdate(description); } if (formatVersion == PersistentDescriptionFormatVersion.AFTER_VERSION_THREE) { if (description.getComponentVersion().compareTo(V3_2) < 0) { description = thirdUpdate(description); } if (description.getComponentVersion().compareTo(V3_3) < 0) { description = fourthUpdate(description); } if (description.getComponentVersion().compareTo(V3_4) < 0) { description = updateFromV33ToV34(description); } } } return description; } private PersistentComponentDescription updateFromV33ToV34(PersistentComponentDescription description) throws JsonProcessingException, IOException { description = PersistentComponentDescriptionUpdaterUtils.updateSchedulingInformation(description); description.setComponentVersion(V3_4); return description; } /** * Updates the component from version 3.2 to 3.3. * */ private PersistentComponentDescription fourthUpdate(PersistentComponentDescription description) throws JsonParseException, IOException { ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode node = mapper.readTree(description.getComponentDescriptionAsString()); ObjectNode configNode = (ObjectNode) node.get(CONFIGURATION); if (configNode.get(USAGEOFSCRIPT) != null) { if (configNode.get(USAGEOFSCRIPT).getTextValue().equals("LOCAL")) { configNode.put(USAGEOFSCRIPT, TextNode.valueOf("NEW")); configNode.put("script", TextNode.valueOf(configNode.get("localScript").getTextValue())); } } ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(node)); description.setComponentVersion(V3_3); return description; } /** * Updates the component from version 3.1 to 3.2. **/ private PersistentComponentDescription thirdUpdate(PersistentComponentDescription description) throws JsonProcessingException, IOException { ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode node = mapper.readTree(description.getComponentDescriptionAsString()); ObjectNode configNode = (ObjectNode) node.get(CONFIGURATION); ArrayNode dynOutputs = (ArrayNode) node.get("dynamicOutputs"); List<String> outputNameList = new LinkedList<String>(); if (dynOutputs != null) { for (JsonNode output : dynOutputs) { outputNameList.add(output.get("name").getTextValue()); } } String script = configNode.get(SCRIPT).getTextValue(); Pattern p = Pattern.compile("(\\S*\\s*= [\"|\']FINISHED[\"|\'])"); Matcher m = p.matcher(script); while (m.find()) { String group = m.group(1); String name = group.substring(0, group.indexOf("=")).trim(); if (outputNameList.contains(name)) { script = script.substring(0, script.indexOf(group)) + "RCE.close_output(\"" + name + "\")" + script.substring(script.indexOf(group) + group.length()); } } configNode.put(SCRIPT, TextNode.valueOf(script)); ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(node)); description.setComponentVersion(V3_2); return description; } /** * Updates the component from version 0 to 3.0. * */ private PersistentComponentDescription secondUpdate(PersistentComponentDescription description) throws JsonParseException, IOException { description = PersistentComponentDescriptionUpdaterUtils.updateAllDynamicEndpointsToIdentifier("dynamicOutputs", "default", description); description = PersistentComponentDescriptionUpdaterUtils.updateAllDynamicEndpointsToIdentifier("dynamicInputs", "default", description); ObjectMapper mapper = JsonUtils.getDefaultObjectMapper(); JsonNode node = mapper.readTree(description.getComponentDescriptionAsString()); ObjectNode configNode = (ObjectNode) node.get(CONFIGURATION); if (node.get(CONFIGURATION).get(USAGE_OF_SCRIPT) != null) { configNode.put(USAGEOFSCRIPT, node.get(CONFIGURATION).get(USAGE_OF_SCRIPT)); configNode.remove(USAGE_OF_SCRIPT); } if (node.get(CONFIGURATION).get(USAGEOFSCRIPT) == null) { configNode.put(USAGEOFSCRIPT, TextNode.valueOf("NEW")); } configNode.put(SCRIPT, TextNode.valueOf(configNode.get(SCRIPT).getTextValue().replaceAll("_dm_.clear\\(\\)", ""))); configNode.remove("remote path of existing script"); configNode.remove("debug"); configNode.remove("remote upload path of new script"); configNode.remove(USAGE_OF_SCRIPT); ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); description = new PersistentComponentDescription(writer.writeValueAsString(node)); description.setComponentVersion(V3_1); return description; } }