/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.components.parametricstudy.execution;
import java.io.IOException;
import java.util.Iterator;
import java.util.UUID;
import org.codehaus.jackson.JsonFactory;
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.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.parametricstudy.common.ParametricStudyComponentConstants;
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 Doreen Seider
*/
public class ParametricStudyPersistentComponentDescriptionUpdater implements PersistentComponentDescriptionUpdater {
private static final String DESIGN_VARIABLE = "Design Variable";
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 static final String V4 = "4";
private static final String OUTPUT_NAME = "name";
private static final String STATIC_OUTPUTS = "staticOutputs";
private static final String DYNAMIC_INPUTS = "dynamicInputs";
private static final String EP_IDENTIFIER = "epIdentifier";
@Override
public String[] getComponentIdentifiersAffectedByUpdate() {
return ParametricStudyComponentConstants.COMPONENT_IDS;
}
@Override
public int getFormatVersionsAffectedByUpdate(String persistentComponentDescriptionVersion, boolean silent) {
int versionsToUpdate = PersistentDescriptionFormatVersion.NONE;
if (!silent) {
if (persistentComponentDescriptionVersion == null
|| persistentComponentDescriptionVersion.compareTo(V1_0) < 0) {
versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.BEFORE_VERSON_THREE;
}
if (persistentComponentDescriptionVersion != null) {
if (persistentComponentDescriptionVersion.compareTo(V3_0) < 0) {
versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.FOR_VERSION_THREE;
}
if (persistentComponentDescriptionVersion.compareTo(V4) < 0) {
versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.AFTER_VERSION_THREE;
}
}
} else if (persistentComponentDescriptionVersion != null
&& persistentComponentDescriptionVersion.compareTo(V3_3) < 0) {
versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.AFTER_VERSION_THREE;
}
return versionsToUpdate;
}
@Override
public PersistentComponentDescription performComponentDescriptionUpdate(int formatVersion,
PersistentComponentDescription description, boolean silent) throws IOException {
if (!silent) { // called after "silent" was called
if (formatVersion == PersistentDescriptionFormatVersion.BEFORE_VERSON_THREE) {
return updateToV10(description);
}
if (formatVersion == PersistentDescriptionFormatVersion.FOR_VERSION_THREE) {
return updateFrom10To30(description);
}
if (formatVersion == PersistentDescriptionFormatVersion.AFTER_VERSION_THREE) {
switch (description.getComponentVersion()) {
case V3_0:
description = updateFrom30To31(description);
case V3_1:
description = updateFrom31To32(description);
case V3_2:
description = updateFrom32To33(description);
case V3_3:
description = updateFrom33To4(description);
default:
// nothing to do here
}
}
} else { // called first (before non-silent)
if (formatVersion == PersistentDescriptionFormatVersion.AFTER_VERSION_THREE) {
switch (description.getComponentVersion()) {
case V3_1:
description = updateFrom31To32(description);
case V3_2:
description = updateFrom32To33(description);
default:
// nothing to do here
}
}
}
return description;
}
private PersistentComponentDescription updateFrom33To4(PersistentComponentDescription description)
throws JsonProcessingException, IOException {
description =
PersistentComponentDescriptionUpdaterUtils.removeOuterLoopDoneEndpoints(description);
description = PersistentComponentDescriptionUpdaterUtils.removeEndpointCharacterInfoFromMetaData(description);
description = PersistentComponentDescriptionUpdaterUtils.reassignEndpointIdentifiers(description, DYNAMIC_INPUTS, "toForward",
"startToForward", "_start");
description.setComponentVersion(V4);
return description;
}
private PersistentComponentDescription updateFrom32To33(PersistentComponentDescription description)
throws JsonProcessingException, IOException {
PersistentComponentDescription updatedDesc =
PersistentComponentDescriptionUpdaterUtils.updateFaultToleranceOfLoopDriver(description);
updatedDesc.setComponentVersion(V3_3);
return updatedDesc;
}
private PersistentComponentDescription updateFrom31To32(PersistentComponentDescription description) throws JsonProcessingException,
IOException {
ObjectMapper mapper = JsonUtils.getDefaultObjectMapper();
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
JsonNode staticOutputs = node.get(STATIC_OUTPUTS);
for (JsonNode outputEndpoint : staticOutputs) {
((ObjectNode) outputEndpoint).remove(EP_IDENTIFIER);
if (outputEndpoint.get(OUTPUT_NAME).getTextValue().equals(DESIGN_VARIABLE)) {
((ObjectNode) outputEndpoint).put(OUTPUT_NAME, ParametricStudyComponentConstants.OUTPUT_NAME_DV);
}
}
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
PersistentComponentDescription newdesc = new PersistentComponentDescription(writer.writeValueAsString(node));
newdesc.setComponentVersion(V3_2);
return newdesc;
}
private PersistentComponentDescription updateFrom30To31(PersistentComponentDescription description) throws JsonProcessingException,
IOException {
ObjectMapper mapper = JsonUtils.getDefaultObjectMapper();
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
// remove epIdentifier for static outputs
JsonNode staticOutputs = node.get(STATIC_OUTPUTS);
if (staticOutputs != null) {
for (JsonNode outputEndpoint : staticOutputs) {
((ObjectNode) outputEndpoint).remove(EP_IDENTIFIER);
if (outputEndpoint.get(OUTPUT_NAME).getTextValue().equals("DesignVariable")) {
((ObjectNode) outputEndpoint).put(OUTPUT_NAME, DESIGN_VARIABLE);
ObjectNode metadata = createStaticOutputMetaData(node);
((ObjectNode) outputEndpoint).put("metadata", metadata);
((ObjectNode) outputEndpoint).put("datatype", "Float");
}
}
} else {
ArrayNode statOutputs = JsonNodeFactory.instance.arrayNode();
ObjectNode output =
JsonNodeFactory.instance.objectNode();
output.put("identifier",
TextNode.valueOf(UUID.randomUUID().toString()));
output.put(OUTPUT_NAME,
TextNode.valueOf(DESIGN_VARIABLE));
output.put("datatype", TextNode.valueOf("Float"));
ObjectNode metadata = createStaticOutputMetaData(node);
output.put("metadata", metadata);
statOutputs.add(output);
((ObjectNode) node).put(STATIC_OUTPUTS, statOutputs);
}
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
PersistentComponentDescription newdesc = new PersistentComponentDescription(writer.writeValueAsString(node));
newdesc.setComponentVersion(V3_1);
return newdesc;
}
private ObjectNode createStaticOutputMetaData(JsonNode node) {
ObjectNode metadata = JsonNodeFactory.instance.objectNode();
ObjectNode config = (ObjectNode) node.get("configuration");
metadata.put("FromValue", TextNode.valueOf(config.get("FromValue").getTextValue()));
metadata.put("StepSize", TextNode.valueOf(config.get("StepSize").getTextValue()));
metadata.put("ToValue", TextNode.valueOf(config.get("ToValue").getTextValue()));
return metadata;
}
private PersistentComponentDescription updateFrom10To30(PersistentComponentDescription description) throws JsonProcessingException,
IOException {
description =
PersistentComponentDescriptionUpdaterUtils.updateAllDynamicEndpointsToIdentifier("dynamicInputs", "parameters", description);
ObjectMapper mapper = JsonUtils.getDefaultObjectMapper();
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
// remove epIdentifier for static outputs
JsonNode staticOutputs = node.get(STATIC_OUTPUTS);
if (staticOutputs != null) {
for (JsonNode outputEndpoint : staticOutputs) {
((ObjectNode) outputEndpoint).remove(EP_IDENTIFIER);
}
}
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
PersistentComponentDescription newdesc = new PersistentComponentDescription(writer.writeValueAsString(node));
newdesc.setComponentVersion(V3_0);
return newdesc;
}
private PersistentComponentDescription updateToV10(PersistentComponentDescription description) throws JsonParseException, IOException {
JsonFactory jsonFactory = new JsonFactory();
JsonParser jsonParser = jsonFactory.createJsonParser(description.getComponentDescriptionAsString());
ObjectMapper mapper = JsonUtils.getDefaultObjectMapper();
JsonNode rootNode = mapper.readTree(jsonParser);
jsonParser.close();
JsonNode dynamicInputsNode = rootNode.findPath(STATIC_OUTPUTS);
Iterator<JsonNode> it = dynamicInputsNode.getElements();
while (it.hasNext()) {
JsonNode inputNode = it.next();
((ObjectNode) inputNode).remove(OUTPUT_NAME);
((ObjectNode) inputNode).put(OUTPUT_NAME, TextNode.valueOf(ParametricStudyComponentConstants.OUTPUT_NAME_DV));
}
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
description = new PersistentComponentDescription(writer.writeValueAsString(rootNode));
description.setComponentVersion(V1_0);
return description;
}
}