/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.components.optimizer.execution;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.NullNode;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.node.TextNode;
import de.rcenvironment.components.optimizer.common.MethodDescription;
import de.rcenvironment.components.optimizer.common.OptimizerComponentConstants;
import de.rcenvironment.components.optimizer.common.OptimizerFileLoader;
import de.rcenvironment.core.component.api.LoopComponentConstants;
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;
import de.rcenvironment.core.utils.common.StringUtils;
/**
* Implementation of {@link PersistentComponentDescriptionUpdater}.
*
* @author Sascha Zur
* @author Doreen Seider
*/
public class OptimizerPersistentComponentDescriptionUpdater implements PersistentComponentDescriptionUpdater {
private static final String REQUIRED = "Required";
private static final String INPUT_EXECUTION_CONSTRAINT = "inputExecutionConstraint_4aae3eea";
private static final String PRE_CALC_FILE_PATH = "preCalcFilePath";
private static final String SELF_LOOP_ENDPOINT = "SelfLoopEndpoint";
private static final String OUTER_LOOP_ENDPOINT = "OuterLoopEndpoint";
private static final String DYNAMIC_OUTPUTS = "dynamicOutputs";
private static final String GOAL = "goal";
private static final String DYNAMIC_INPUTS = "dynamicInputs";
private static final String SPECIFIC_SETTINGS = "specificSettings";
private static final String DAKOTA_COLINY_EVOLUTIONARY_ALGORITHM = "Dakota Coliny Evolutionary Algorithm";
private static final String DAKOTA_COLINY_COBYLA_CONSTRAINT_OPTIMIZATION_BY_LINEAR_APPROXIMATIONS =
"Dakota Coliny COBYLA (Constraint Optimization By Linear Approximations)";
private static final String DAKOTA_QUASI_NEWTON_METHOD = "Dakota Quasi-Newton method";
private static final String EP_IDENTIFIER = "epIdentifier";
private static final String CONSTRAINT = "Constraint";
private static final String OBJECTIVE = "Objective";
private static final String NAME = "name";
private static final String STATIC_OUTPUTS = "staticOutputs";
private static final String NAN = "NaN";
private static final String WEIGHT = "weight";
private static final String METADATA = "metadata";
private static final String METHOD_CONFIGURATIONS = "methodConfigurations";
private static final String ALGORITHM = "algorithm";
private static final String CONFIGURATION = "configuration";
private static final String LOOP_ENDPOINT_TYPE = "loopEndpointType_5e0ed1cd";
private static final Log LOGGER = LogFactory.getLog(OptimizerPersistentComponentDescriptionUpdater.class);
private static final String COLON = ":";
private static final String V1_0 = "1.0";
private static final String V3_0 = "3.0";
private static final String V5_0 = "5.0";
private static final String V5_1 = "5.1";
private static final String V6_0 = "6.0";
private static final String V6_1 = "6.1";
private static final String V6_2 = "6.2";
private static final String V7_0 = "7.0";
private static final String V7_1 = "7.1";
private static final String V8 = "8";
private static ObjectMapper mapper = JsonUtils.getDefaultObjectMapper();
@Override
public String[] getComponentIdentifiersAffectedByUpdate() {
return OptimizerComponentConstants.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;
}
if (!silent && persistentComponentDescriptionVersion != null
&& persistentComponentDescriptionVersion.compareTo(V3_0) < 0) {
versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.FOR_VERSION_THREE;
}
if (!silent && persistentComponentDescriptionVersion != null
&& persistentComponentDescriptionVersion.compareTo(V8) < 0) {
versionsToUpdate = versionsToUpdate | PersistentDescriptionFormatVersion.AFTER_VERSION_THREE;
}
if (silent && persistentComponentDescriptionVersion != null
&& persistentComponentDescriptionVersion.compareTo(V7_1) < 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) {
description = updateBeforeVersion3(description);
} else if (formatVersion == PersistentDescriptionFormatVersion.FOR_VERSION_THREE) {
description = updateToVersion3(description);
} else if (formatVersion == PersistentDescriptionFormatVersion.AFTER_VERSION_THREE) {
switch (description.getComponentVersion()) {
case V3_0:
description = updateToVersion50(description);
case V5_0:
description = updateToVersion51(description);
case V5_1:
description = updateToVersion60(description);
case V6_0:
description = updateToVersion61(description);
case V6_1:
description = updateFrom61To62(description);
case V6_2:
description = updateToVersion70(description);
case V7_0:
description = updateFrom70To71(description);
case V7_1:
description = updateFrom71To8(description);
default:
// nothing to do here
}
}
} else { // called first (before non-silent)
if (formatVersion == PersistentDescriptionFormatVersion.AFTER_VERSION_THREE) {
switch (description.getComponentVersion()) {
case V7_0:
description = updateFrom70To71(description);
default:
// nothing to do here
}
}
}
return description;
}
private PersistentComponentDescription updateFrom71To8(PersistentComponentDescription description)
throws JsonProcessingException, IOException {
description =
PersistentComponentDescriptionUpdaterUtils.removeOuterLoopDoneEndpoints(description);
description = PersistentComponentDescriptionUpdaterUtils.removeEndpointCharacterInfoFromMetaData(description);
description.setComponentVersion(V8);
return description;
}
private PersistentComponentDescription updateFrom70To71(PersistentComponentDescription description)
throws JsonProcessingException, IOException {
PersistentComponentDescription updatedDesc =
PersistentComponentDescriptionUpdaterUtils.updateFaultToleranceOfLoopDriver(description);
JsonNode node = mapper.readTree(updatedDesc.getComponentDescriptionAsString());
JsonNode configuration = node.get(CONFIGURATION);
if (configuration != null) {
ObjectNode configNode = (ObjectNode) configuration;
configNode.put(OptimizerComponentConstants.USE_RESTART_FILE, "false");
configNode.put(PRE_CALC_FILE_PATH, "");
}
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
PersistentComponentDescription newdesc = new PersistentComponentDescription(writer.writeValueAsString(node));
newdesc.setComponentVersion(V7_1);
return newdesc;
}
private PersistentComponentDescription updateToVersion70(PersistentComponentDescription description)
throws JsonParseException, JsonGenerationException, JsonMappingException, IOException {
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
JsonNode staticOutputs = node.get(STATIC_OUTPUTS);
if (staticOutputs != null) {
for (JsonNode outputEndpoint : staticOutputs) {
ObjectNode metaData = (ObjectNode) outputEndpoint.get(METADATA);
if (metaData == null) {
metaData = JsonNodeFactory.instance.objectNode();
((ObjectNode) outputEndpoint).put(METADATA, metaData);
}
if (outputEndpoint.get(NAME).getTextValue().equals("Outer loop done")) {
metaData.put(LOOP_ENDPOINT_TYPE, "InnerLoopEndpoint");
}
if (outputEndpoint.get(NAME).getTextValue().equals("Iteration")) {
metaData.put(LOOP_ENDPOINT_TYPE, SELF_LOOP_ENDPOINT);
}
if (outputEndpoint.get(NAME).getTextValue().equals("Gradient request")) {
metaData.put(LOOP_ENDPOINT_TYPE, SELF_LOOP_ENDPOINT);
}
if (outputEndpoint.get(NAME).getTextValue().equals("Done")) {
metaData.put(LOOP_ENDPOINT_TYPE, OUTER_LOOP_ENDPOINT);
}
}
}
JsonNode dynamicOutputs = node.get(DYNAMIC_OUTPUTS);
if (dynamicOutputs != null) {
for (JsonNode outputEndpoint : dynamicOutputs) {
ObjectNode metaData = (ObjectNode) outputEndpoint.get(METADATA);
if (outputEndpoint.get(EP_IDENTIFIER).getTextValue().equals("Design")) {
metaData.put(LOOP_ENDPOINT_TYPE, SELF_LOOP_ENDPOINT);
}
if (outputEndpoint.get(EP_IDENTIFIER).getTextValue().equals("optima")) {
metaData.put(LOOP_ENDPOINT_TYPE, OUTER_LOOP_ENDPOINT);
}
}
}
JsonNode dynamicInputs = node.get(DYNAMIC_INPUTS);
if (dynamicInputs != null) {
for (JsonNode inputEndpoint : dynamicInputs) {
ObjectNode metaData = (ObjectNode) inputEndpoint.get(METADATA);
if (inputEndpoint.get(EP_IDENTIFIER).getTextValue().equals("Objective")
|| inputEndpoint.get(EP_IDENTIFIER).getTextValue().equals("Constraint")
|| inputEndpoint.get(EP_IDENTIFIER).getTextValue().equals("gradients")) {
metaData.put(LOOP_ENDPOINT_TYPE, SELF_LOOP_ENDPOINT);
}
if (inputEndpoint.get(EP_IDENTIFIER).getTextValue().equals("startvalues")
|| inputEndpoint.get(EP_IDENTIFIER).getTextValue().equals("outerLoopDone")) {
metaData.put(LOOP_ENDPOINT_TYPE, OUTER_LOOP_ENDPOINT);
metaData.put(INPUT_EXECUTION_CONSTRAINT, REQUIRED);
}
}
}
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
PersistentComponentDescription newdesc = new PersistentComponentDescription(writer.writeValueAsString(node));
newdesc.setComponentVersion(V7_0);
return newdesc;
}
private PersistentComponentDescription updateFrom61To62(PersistentComponentDescription description)
throws JsonParseException, IOException {
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
JsonNode staticOutputs = node.get(STATIC_OUTPUTS);
if (staticOutputs != null) {
for (JsonNode outputEndpoint : staticOutputs) {
((ObjectNode) outputEndpoint).remove(EP_IDENTIFIER);
if (outputEndpoint.get(NAME).getTextValue().equals("Optimizer is finished")) {
((ObjectNode) outputEndpoint).put(NAME, LoopComponentConstants.ENDPOINT_NAME_LOOP_DONE);
}
}
}
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
PersistentComponentDescription newdesc = new PersistentComponentDescription(writer.writeValueAsString(node));
newdesc.setComponentVersion(V6_2);
return newdesc;
}
@SuppressWarnings("unchecked")
private PersistentComponentDescription updateToVersion61(PersistentComponentDescription description)
throws JsonParseException, IOException {
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
((ObjectNode) node.get(CONFIGURATION)).put(PRE_CALC_FILE_PATH, "${preCalcFilePath}");
TextNode methodConfigurations = (TextNode) node.get(CONFIGURATION).get(METHOD_CONFIGURATIONS);
Map<String, Object> configs = mapper.readValue(methodConfigurations.getTextValue(), new HashMap<String, Object>().getClass());
ObjectNode accuracyNode = mapper.createObjectNode();
accuracyNode.put("GuiName", "Solution accuracy");
accuracyNode.put("dataType", "Real");
accuracyNode.put("SWTWidget", "Text");
accuracyNode.put("DefaultValue", "1.E-4");
accuracyNode.put("Value", "");
accuracyNode.put("Validation", "required");
if (configs != null && configs.get(DAKOTA_COLINY_COBYLA_CONSTRAINT_OPTIMIZATION_BY_LINEAR_APPROXIMATIONS) != null) {
Map<String, Object> specifics =
(Map<String, Object>) ((HashMap<String, Object>) configs
.get(DAKOTA_COLINY_COBYLA_CONSTRAINT_OPTIMIZATION_BY_LINEAR_APPROXIMATIONS)).get(
SPECIFIC_SETTINGS);
specifics.put("solution_accuracy", accuracyNode);
}
if (configs != null && configs.get(DAKOTA_COLINY_EVOLUTIONARY_ALGORITHM) != null) {
Map<String, Object> specifics =
(Map<String, Object>) ((HashMap<String, Object>) configs.get(DAKOTA_COLINY_EVOLUTIONARY_ALGORITHM)).get(
SPECIFIC_SETTINGS);
specifics.put("solution_accuracy", accuracyNode);
}
((ObjectNode) node.get(CONFIGURATION)).remove(METHOD_CONFIGURATIONS);
((ObjectNode) node.get(CONFIGURATION)).put(METHOD_CONFIGURATIONS, mapper.writeValueAsString(configs));
ArrayNode inputs = ((ArrayNode) node.get(DYNAMIC_INPUTS));
if (inputs != null) {
Iterator<JsonNode> it = inputs.iterator();
while (it.hasNext()) {
ObjectNode input = (ObjectNode) it.next();
if (((ObjectNode) input.get(METADATA)).get(GOAL) != null
&& ((ObjectNode) input.get(METADATA)).get(GOAL).getTextValue().equals("Solve for")) {
((ObjectNode) input.get(METADATA)).put(GOAL, "Minimize");
((ObjectNode) input.get(METADATA)).remove("solve");
}
}
}
description = new PersistentComponentDescription(writer.writeValueAsString(node));
description.setComponentVersion(V6_1);
return description;
}
@SuppressWarnings("unchecked")
private PersistentComponentDescription updateToVersion60(PersistentComponentDescription description)
throws JsonParseException, IOException {
description = PersistentComponentDescriptionUpdaterUtils.updateSchedulingInformation(description);
description = PersistentComponentDescriptionUpdaterUtils.updateIsNestedLoop(description);
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
ArrayNode statEndpoints = (ArrayNode) node.get("staticOutputs");
if (statEndpoints != null) {
ObjectNode gradientRequest = mapper.createObjectNode();
gradientRequest.put("identifier", UUID.randomUUID().toString());
gradientRequest.put(NAME, OptimizerComponentConstants.DERIVATIVES_NEEDED);
gradientRequest.put(EP_IDENTIFIER, NullNode.instance);
gradientRequest.put("datatype", "Boolean");
statEndpoints.add(gradientRequest);
for (JsonNode o : statEndpoints) {
ObjectNode outNode = (ObjectNode) o;
if (outNode.get(NAME).getTextValue().equals("Iteration count")) {
outNode.remove(NAME);
outNode.put(NAME, "Iteration");
}
}
}
((ObjectNode) node.get(CONFIGURATION)).put(PRE_CALC_FILE_PATH, "${preCalcFilePath}");
TextNode methodConfigurations = (TextNode) node.get(CONFIGURATION).get(METHOD_CONFIGURATIONS);
Map<String, Object> configs = mapper.readValue(methodConfigurations.getTextValue(), new HashMap<String, Object>().getClass());
if (configs != null && configs.get("Dakota Surrogate-Based Local") != null) {
((HashMap<String, Object>) configs.get("Dakota Surrogate-Based Local")).put("methodCode", "surrogate_based_local");
}
if (configs != null && configs.get(DAKOTA_QUASI_NEWTON_METHOD) != null) {
Map<String, Object> specifics =
(Map<String, Object>) ((HashMap<String, Object>) configs.get(DAKOTA_QUASI_NEWTON_METHOD)).get(SPECIFIC_SETTINGS);
specifics.remove("central_path");
((Map<String, Object>) specifics.get("merit_function")).put("dataType", "None");
((Map<String, Object>) specifics.get("merit_function")).put("defaultValue", "argaez_tapia");
}
Map<String, Object> moga =
mapper.readValue(OptimizerFileLoader.class.getResourceAsStream("/resources/optimizer/dakota/dakotaMOGA.json"),
new HashMap<String, Object>().getClass());
Map<String, Object> soga =
mapper.readValue(OptimizerFileLoader.class.getResourceAsStream("/resources/optimizer/dakota/dakotaSOGA.json"),
new HashMap<String, Object>().getClass());
Map<String, Object> defaults =
mapper.readValue(OptimizerFileLoader.class.getResourceAsStream("/resources/optimizer/dakota/defaults.json"),
new HashMap<String, Object>().getClass());
moga.put("commonSettings", defaults);
soga.put("commonSettings", defaults);
if (configs != null) {
configs.put("Dakota Multi Objective Genetic Algorithm", moga);
configs.put("Dakota Single Objective Genetic Algorithm", soga);
}
((ObjectNode) node.get(CONFIGURATION)).remove(METHOD_CONFIGURATIONS);
((ObjectNode) node.get(CONFIGURATION)).put(METHOD_CONFIGURATIONS, mapper.writeValueAsString(configs));
description = new PersistentComponentDescription(writer.writeValueAsString(node));
description.setComponentVersion(V6_0);
return description;
}
private PersistentComponentDescription updateToVersion51(PersistentComponentDescription description) throws JsonParseException,
IOException {
if (!description.getComponentVersion().equals(V5_0)) {
description = updateToVersion50(description);
}
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
ArrayNode dynEndpoints = (ArrayNode) node.get(DYNAMIC_INPUTS);
if (dynEndpoints != null) {
for (JsonNode endpoint : dynEndpoints) {
if (endpoint.get(NAME) != null
&& endpoint.get(NAME).getTextValue().contains(OptimizerComponentConstants.GRADIENT_DELTA)) {
((ObjectNode) endpoint).put(EP_IDENTIFIER, "gradients");
}
}
}
description = new PersistentComponentDescription(writer.writeValueAsString(node));
description.setComponentVersion(V5_1);
return description;
}
private PersistentComponentDescription updateToVersion50(PersistentComponentDescription description) throws JsonParseException,
IOException {
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
ArrayNode dynEndpoints = (ArrayNode) node.get(DYNAMIC_OUTPUTS);
if (dynEndpoints != null) {
List<JsonNode> newNodes = new LinkedList<JsonNode>();
for (JsonNode endpoint : dynEndpoints) {
if (endpoint.get(NAME) != null
&& dynEndpoints.get(endpoint.get(NAME).getTextValue()
+ OptimizerComponentConstants.OPTIMUM_VARIABLE_SUFFIX) == null) {
ObjectNode optimalNode = (ObjectNode) copy(endpoint);
optimalNode.put("identifier", UUID.randomUUID().toString());
optimalNode.put(NAME, optimalNode.get(NAME).getTextValue() + OptimizerComponentConstants.OPTIMUM_VARIABLE_SUFFIX);
optimalNode.put(EP_IDENTIFIER, OptimizerComponentConstants.ID_OPTIMA);
newNodes.add(optimalNode);
}
if (endpoint.get(METADATA) != null) {
((ObjectNode) endpoint.get(METADATA)).put(OptimizerComponentConstants.META_HAS_STARTVALUE, true);
}
}
for (JsonNode e : newNodes) {
dynEndpoints.add(e);
}
}
description = new PersistentComponentDescription(writer.writeValueAsString(node));
description.setComponentVersion(V5_0);
return description;
}
@SuppressWarnings("unchecked")
private <T extends JsonNode> T copy(T node) {
try {
return (T) JsonUtils.getDefaultObjectMapper().readTree(node.traverse());
} catch (IOException e) {
throw new AssertionError(e);
}
}
private PersistentComponentDescription updateToVersion3(PersistentComponentDescription description) throws JsonParseException,
IOException {
description =
PersistentComponentDescriptionUpdaterUtils.updateAllDynamicEndpointsToIdentifier(DYNAMIC_OUTPUTS, "Design", description);
JsonNode node = mapper.readTree(description.getComponentDescriptionAsString());
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
JsonNode dynEndpoints = node.get(DYNAMIC_INPUTS);
if (dynEndpoints != null) {
for (JsonNode endpoint : dynEndpoints) {
if (endpoint.get(PersistentComponentDescriptionUpdaterUtils.EP_IDENTIFIER) == null
|| endpoint.get(PersistentComponentDescriptionUpdaterUtils.EP_IDENTIFIER).isNull()
|| endpoint.get(PersistentComponentDescriptionUpdaterUtils.EP_IDENTIFIER).getTextValue().equals("null")) {
ObjectNode objectEndpoint = (ObjectNode) endpoint;
objectEndpoint.remove(PersistentComponentDescriptionUpdaterUtils.EP_IDENTIFIER);
String identifier = "";
if ((objectEndpoint.get(METADATA)) != null
&& !((ObjectNode) objectEndpoint.get(METADATA)).get(WEIGHT).getTextValue().equals(NAN)) {
identifier = OBJECTIVE;
updateMetaData(objectEndpoint, dynEndpoints);
} else if (((ObjectNode) objectEndpoint.get(METADATA)) != null) {
identifier = CONSTRAINT;
updateMetaData(objectEndpoint, dynEndpoints);
} else {
if (objectEndpoint.get(NAME).getTextValue().contains(OptimizerComponentConstants.GRADIENT_DELTA)) {
ObjectNode newMetadataObjectNode = JsonNodeFactory.instance.objectNode();
objectEndpoint.put(METADATA, newMetadataObjectNode);
String functionName =
objectEndpoint.get(NAME).getTextValue()
.substring(1, objectEndpoint.get(NAME).getTextValue().indexOf('.'));
for (JsonNode otherEndpoint : dynEndpoints) {
if (otherEndpoint.get(NAME).getTextValue().equals(functionName)
&& (otherEndpoint.get(METADATA)) != null
&& !((ObjectNode) otherEndpoint.get(METADATA)).get(WEIGHT).getTextValue().equals(NAN)) {
identifier = OBJECTIVE;
break;
} else {
identifier = CONSTRAINT;
}
}
}
}
objectEndpoint.put(PersistentComponentDescriptionUpdaterUtils.EP_IDENTIFIER, TextNode.valueOf(identifier));
}
}
}
// Add Static endpoints
description = new PersistentComponentDescription(writer.writeValueAsString(node));
description.setComponentVersion(V3_0);
return description;
}
private void updateMetaData(ObjectNode objectEndpoint, JsonNode dynEndpoints) {
ObjectNode metadata = (ObjectNode) objectEndpoint.get(METADATA);
if (metadata.get(GOAL).getTextValue().equals("0")) {
metadata.put(GOAL, TextNode.valueOf("Minimize"));
} else if (metadata.get(GOAL).getTextValue().equals("1")) {
metadata.put(GOAL, TextNode.valueOf("Maximize"));
} else {
metadata.put(GOAL, TextNode.valueOf("Solve for"));
}
boolean hasMetaData = false;
for (JsonNode otherEndpoint : dynEndpoints) {
if (otherEndpoint.get(NAME).getTextValue().contains(OptimizerComponentConstants.GRADIENT_DELTA)
&& otherEndpoint.get(NAME).getTextValue()
.contains(OptimizerComponentConstants.GRADIENT_DELTA + objectEndpoint.get(NAME).getTextValue() + ".")) {
hasMetaData = true;
}
}
metadata.put("hasGradient", JsonNodeFactory.instance.booleanNode(hasMetaData));
objectEndpoint.remove(METADATA);
objectEndpoint.put(METADATA, metadata);
}
private PersistentComponentDescription updateBeforeVersion3(PersistentComponentDescription description) throws IOException,
JsonParseException,
JsonProcessingException, JsonGenerationException, JsonMappingException {
JsonFactory jsonFactory = new JsonFactory();
JsonNode completeComponent;
try (JsonParser jsonParser = jsonFactory.createJsonParser(description.getComponentDescriptionAsString())) {
completeComponent = mapper.readTree(jsonParser);
}
JsonNode completeConfiguration = completeComponent.get(CONFIGURATION);
JsonNode algorithmNode = null;
JsonNode methodsConfigurationNode = null;
JsonNode optimizerPackageNode = null;
boolean foundMethodConfigurations = false;
boolean foundPackageDeclaration = false;
for (int i = 0; i < completeConfiguration.size(); i++) {
if (completeConfiguration.get(i).getTextValue() != null) {
String[] configItem = completeConfiguration.get(i).getTextValue().split(COLON);
if (configItem[0].equals(ALGORITHM)) {
algorithmNode = updateAlgorithm(completeConfiguration.get(i));
}
if (configItem[0].contains(METHOD_CONFIGURATIONS) && configItem.length > 2 && configItem[2] != null) {
String configs = completeConfiguration.get(i).getTextValue();
configs = configs.substring(configs.indexOf("{"));
methodsConfigurationNode = updateMethods(configs);
foundMethodConfigurations = true;
}
if (configItem[0].equals(OptimizerComponentConstants.OPTIMIZER_PACKAGE)) {
foundPackageDeclaration = true;
if (configItem.length > 2 && configItem[2] != null && !configItem[2].isEmpty()
&& (algorithmNode != null && algorithmNode.getTextValue().contains("Pyranha"))) {
optimizerPackageNode = TextNode.valueOf(OptimizerComponentConstants.OPTIMIZER_PACKAGE
+ ":java.lang.String:pyranha");
} else if (configItem.length > 2 && configItem[2] != null && !configItem[2].isEmpty()
&& (algorithmNode != null && algorithmNode.getTextValue().contains("Dakota"))) {
optimizerPackageNode = TextNode.valueOf(OptimizerComponentConstants.OPTIMIZER_PACKAGE
+ ":java.lang.String:dakota");
} else {
optimizerPackageNode = TextNode.valueOf(OptimizerComponentConstants.OPTIMIZER_PACKAGE
+ ":java.lang.String:generic");
}
}
}
}
if (!foundMethodConfigurations) {
methodsConfigurationNode = writeNewMethodConfigurationsNode();
}
if (!foundPackageDeclaration) {
optimizerPackageNode = TextNode.valueOf(OptimizerComponentConstants.OPTIMIZER_PACKAGE
+ ":java.lang.String:dakota");
}
if (completeConfiguration.get("genericPythonPath") != null) {
((ObjectNode) completeConfiguration).put("genericPythonPath", TextNode.valueOf("${genericPythonPath}"));
}
if (completeConfiguration.get("pyranhaPythonPath") != null) {
((ObjectNode) completeConfiguration).put("pyranhaPythonPath", TextNode.valueOf("${pyranhaPythonPath}"));
}
ArrayNode newConfig = mapper.createArrayNode();
newConfig.add(algorithmNode);
if (methodsConfigurationNode != null) {
newConfig.add(methodsConfigurationNode);
}
newConfig.add(optimizerPackageNode);
((ObjectNode) completeComponent).remove(CONFIGURATION);
((ObjectNode) completeComponent).put(CONFIGURATION, newConfig);
PersistentComponentDescription newDesc =
new PersistentComponentDescription(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(completeComponent));
newDesc.setComponentVersion(V1_0);
return newDesc;
}
@SuppressWarnings("unchecked")
private JsonNode updateMethods(String methodConfigs) {
JsonNode returnNode = null;
try {
String newMethodConfiguations = METHOD_CONFIGURATIONS + ":java.lang.String:";
Map<String, MethodDescription> defaultMethodConfigurations = OptimizerFileLoader.getAllMethodDescriptions("/optimizer");
for (String key : defaultMethodConfigurations.keySet()) {
defaultMethodConfigurations.put(key, mapper.convertValue(defaultMethodConfigurations.get(key), MethodDescription.class));
}
Map<String, MethodDescription> methodConfigurations;
if (!methodConfigs.equals("")) {
methodConfigs = StringUtils.unescapeSeparator(methodConfigs);
methodConfigurations = mapper.readValue(methodConfigs, new HashMap<String, MethodDescription>().getClass());
for (String key : methodConfigurations.keySet()) {
methodConfigurations.put(key, mapper.convertValue(methodConfigurations.get(key), MethodDescription.class));
}
replaceConfigurations(methodConfigurations, defaultMethodConfigurations);
} else {
return writeNewMethodConfigurationsNode();
}
returnNode =
TextNode.valueOf(newMethodConfiguations
+ StringUtils.escapeSeparator(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(
methodConfigurations)));
} catch (JsonParseException e) {
LOGGER.error("Could not parse method file ", e);
} catch (JsonMappingException e) {
LOGGER.error("Could not map method file ", e);
} catch (IOException e) {
LOGGER.error("Could not load method file ", e);
}
return returnNode;
}
private static JsonNode writeNewMethodConfigurationsNode() {
JsonNode returnNode = null;
String newMethodConfiguations = METHOD_CONFIGURATIONS + ":java.lang.String:";
Map<String, MethodDescription> defaultMethodConfigurations;
try {
defaultMethodConfigurations = OptimizerFileLoader.getAllMethodDescriptions("/optimizer");
for (String key : defaultMethodConfigurations.keySet()) {
defaultMethodConfigurations.put(key, mapper.convertValue(defaultMethodConfigurations.get(key), MethodDescription.class));
}
String configs = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(defaultMethodConfigurations);
configs = StringUtils.escapeSeparator(configs);
returnNode = mapper.valueToTree(newMethodConfiguations + configs);
return returnNode;
} catch (JsonParseException e) {
LOGGER.warn("", e);
} catch (JsonMappingException e) {
LOGGER.warn("", e);
} catch (IOException e) {
LOGGER.warn("", e);
}
return null;
}
private static JsonNode updateAlgorithm(JsonNode algorithm) {
JsonNode returnNode = null;
String prefix = "algorithm:java.lang.String:";
String[] algorithmItem = algorithm.getTextValue().split(COLON);
if (algorithmItem.length > 2) {
if (algorithmItem[2] != null && algorithmItem[2].equals("HOPSPACK Asynch Pattern Search")) {
returnNode = TextNode.valueOf(prefix + "Dakota HOPSPACK Asynch Pattern Search");
}
if (algorithmItem[2] != null && !algorithmItem[2].contains("Dakota")) {
if (algorithmItem[2].contains("COBYLA")) {
returnNode = TextNode.valueOf(prefix + DAKOTA_COLINY_COBYLA_CONSTRAINT_OPTIMIZATION_BY_LINEAR_APPROXIMATIONS);
}
if (algorithmItem[2].contains("Newton")) {
returnNode = TextNode.valueOf(prefix + DAKOTA_QUASI_NEWTON_METHOD);
}
if (algorithmItem[2].contains("Evolutionary")) {
returnNode = TextNode.valueOf(prefix + DAKOTA_COLINY_EVOLUTIONARY_ALGORITHM);
}
}
}
if (returnNode != null) {
return returnNode;
}
return algorithm;
}
private void replaceConfigurations(Map<String, MethodDescription> methodConfigurations,
Map<String, MethodDescription> defaultMethodConfigurations) {
// delete old methods from the configuration
List<String> keysToDelete = new LinkedList<String>();
for (String key : methodConfigurations.keySet()) {
if (!defaultMethodConfigurations.containsKey(key)) {
keysToDelete.add(key);
}
}
for (String key : keysToDelete) {
methodConfigurations.remove(key);
}
// replace existing keys
for (String key : methodConfigurations.keySet()) {
MethodDescription oldDescription = methodConfigurations.get(key);
MethodDescription defaultdescription = defaultMethodConfigurations.get(key);
oldDescription.setFollowingMethods(defaultdescription.getFollowingMethods());
oldDescription.setMethodCode(defaultdescription.getMethodCode());
oldDescription.setMethodName(defaultdescription.getMethodName());
oldDescription.setOptimizerPackage(defaultdescription.getOptimizerPackage());
replaceKeyValueMaps(oldDescription.getSpecificSettings(), defaultdescription.getSpecificSettings());
replaceKeyValueMaps(oldDescription.getResponsesSettings(), defaultdescription.getResponsesSettings());
}
// add new methods to the configuration
for (String key : defaultMethodConfigurations.keySet()) {
if (!methodConfigurations.containsKey(key)) {
methodConfigurations.put(key, defaultMethodConfigurations.get(key));
}
}
}
private void replaceKeyValueMaps(Map<String, Map<String, String>> currentSettings,
Map<String, Map<String, String>> defaultSettings) {
// delete old keys from the configuration
if (currentSettings != null) {
// delete old methods from the configuration
List<String> keysToDelete = new LinkedList<String>();
for (String key : currentSettings.keySet()) {
if (!defaultSettings.containsKey(key)) {
keysToDelete.add(key);
}
}
for (String key : keysToDelete) {
currentSettings.remove(key);
}
}
if (currentSettings != null) {
for (String controlKey : currentSettings.keySet()) {
Map<String, String> currentProperties = currentSettings.get(controlKey);
Map<String, String> defaultProperties = defaultSettings.get(controlKey);
// delete old properties
for (String propertyKey : currentProperties.keySet()) {
if (!defaultProperties.containsKey(propertyKey)) {
currentProperties.remove(propertyKey);
}
}
// replace all other proerties but the value which could be user defined
for (String propertyKey : currentProperties.keySet()) {
if (!propertyKey.equalsIgnoreCase(OptimizerComponentConstants.VALUE_KEY)) {
currentProperties.put(propertyKey, defaultProperties.get(propertyKey));
} else {
if (currentProperties.get(propertyKey).equals(
defaultProperties.get(OptimizerComponentConstants.DEFAULT_VALUE_KEY))) {
currentProperties.put(propertyKey, defaultProperties.get(propertyKey));
}
}
}
// add new properties
for (String propertyKey : defaultProperties.keySet()) {
if (!currentProperties.containsKey(propertyKey)) {
currentProperties.put(propertyKey, defaultProperties.get(propertyKey));
}
}
}
}
// add new methods to the configuration
if (defaultSettings != null && currentSettings != null) {
for (String controlKey : defaultSettings.keySet()) {
if (!currentSettings.containsKey(controlKey)) {
currentSettings.put(controlKey, defaultSettings.get(controlKey));
}
}
}
}
}