de.bund.bfr.knime.fsklab.deprecatednodes/src-1_9_0/de/bund/bfr/knime/fsklab/v1_9/joiner/JoinerNodeModel.java
/*
***************************************************************************************************
* Copyright (c) 2017 Federal Institute for Risk Assessment (BfR), Germany
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If
* not, see <http://www.gnu.org/licenses/>.
*
* Contributors: Department Biological Safety - BfR
*************************************************************************************************
*/
package de.bund.bfr.knime.fsklab.v1_9.joiner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonReader;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.json.simple.parser.ParseException;
import org.knime.base.data.xml.SvgCell;
import org.knime.core.node.CanceledExecutionException;
import org.knime.core.node.ExecutionContext;
import org.knime.core.node.InvalidSettingsException;
import org.knime.core.node.NodeSettingsRO;
import org.knime.core.node.NodeSettingsWO;
import org.knime.core.node.port.PortObject;
import org.knime.core.node.port.PortObjectHolder;
import org.knime.core.node.port.PortObjectSpec;
import org.knime.core.node.port.PortType;
import org.knime.core.node.port.image.ImagePortObject;
import org.knime.core.node.port.image.ImagePortObjectSpec;
import org.knime.core.node.web.ValidationError;
import org.knime.core.node.workflow.FlowVariable;
import org.knime.core.node.workflow.NodeContainer;
import org.knime.core.node.workflow.NodeContext;
import org.knime.js.core.node.AbstractSVGWizardNodeModel;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.bund.bfr.knime.fsklab.FskPluginObjectMapper;
import de.bund.bfr.knime.fsklab.nodes.v1_9.NodeRemovedListener;
import de.bund.bfr.knime.fsklab.v1_9.CombinedFskPortObject;
import de.bund.bfr.knime.fsklab.v1_9.CombinedFskPortObjectSpec;
import de.bund.bfr.knime.fsklab.v1_9.FskPortObject;
import de.bund.bfr.knime.fsklab.v1_9.JoinRelation;
import de.bund.bfr.knime.fsklab.v1_9.OldJoinerRelation;
import de.bund.bfr.metadata.swagger.Parameter;
import metadata.SwaggerUtil;
/**
* Fsk Joiner node model.
*/
public final class JoinerNodeModel
extends AbstractSVGWizardNodeModel<JoinerViewRepresentation, JoinerViewValue>
implements PortObjectHolder {
private final JoinerNodeSettings nodeSettings = new JoinerNodeSettings();
private FskPortObject firstInputPort;
private FskPortObject secondInputPort;
// public final static String SUFFIX = "_dup";
public final static String SUFFIX_FIRST = "1";
public final static String SUFFIX_SECOND = "2";
// public final static String SUFFIX = "_";
Map<String, String> originals = new LinkedHashMap<String, String>();
private final static ObjectMapper MAPPER = FskPluginObjectMapper.MAPPER104;
// Input and output port types
private static final PortType[] IN_TYPES = {FskPortObject.TYPE, FskPortObject.TYPE};
private static final PortType[] OUT_TYPES = {CombinedFskPortObject.TYPE, ImagePortObject.TYPE};
private static final String VIEW_NAME = new JoinerNodeFactory().getInteractiveViewName();
public JoinerNodeModel() {
super(IN_TYPES, OUT_TYPES, VIEW_NAME);
}
@Override
public JoinerViewRepresentation createEmptyViewRepresentation() {
return new JoinerViewRepresentation();
}
@Override
public JoinerViewValue createEmptyViewValue() {
return new JoinerViewValue();
}
@Override
public String getJavascriptObjectID() {
return "de.bund.bfr.knime.fsklab.v1.9.joiner.component";
}
@Override
public boolean isHideInWizard() {
return false;
}
@Override
public ValidationError validateViewValue(JoinerViewValue viewContent) {
return null;
}
@Override
public void saveCurrentValue(NodeSettingsWO content) {}
@Override
public JoinerViewValue getViewValue() {
JoinerViewValue val;
synchronized (getLock()) {
val = super.getViewValue();
if (val == null) {
val = createEmptyViewValue();
}
}
return val;
}
@Override
public JoinerViewRepresentation getViewRepresentation() {
JoinerViewRepresentation representation;
synchronized (getLock()) {
representation = super.getViewRepresentation();
if (representation == null) {
representation = createEmptyViewRepresentation();
}
// Set first model parameters
if (representation.getFirstModelParameters() == null && firstInputPort != null) {
List<Parameter> firstModelParams = SwaggerUtil.getParameter(firstInputPort.modelMetadata);
if (firstModelParams != null && !firstModelParams.isEmpty()) {
representation.setFirstModelParameters(
firstModelParams.toArray(new Parameter[firstModelParams.size()]));
}
}
// Set second model parameters
if (representation.getSecondModelParameters() == null && secondInputPort != null) {
List<Parameter> secondModelParams = SwaggerUtil.getParameter(secondInputPort.modelMetadata);
if (secondModelParams != null && !secondModelParams.isEmpty()) {
representation.setSecondModelParameters(
secondModelParams.toArray(new Parameter[secondModelParams.size()]));
}
}
if (firstInputPort != null) {
if (representation.getFirstModelName() == null) {
representation.setFirstModelName(SwaggerUtil.getModelName(firstInputPort.modelMetadata));
}
if (representation.getFirstModelScript() == null) {
representation.setFirstModelScript(firstInputPort.getModel());
}
if (representation.getFirstModelViz() == null) {
representation.setFirstModelViz(firstInputPort.getViz());
}
}
if (secondInputPort != null) {
if (representation.getSecondModelName() == null) {
representation
.setSecondModelName(SwaggerUtil.getModelName(secondInputPort.modelMetadata));
}
if (representation.getSecondModelScript() == null) {
representation.setSecondModelScript(secondInputPort.getModel());
}
if (representation.getSecondModelViz() == null) {
if (secondInputPort instanceof CombinedFskPortObject) {
representation.setSecondModelViz(extractSecondObjectVis(secondInputPort));
} else {
representation.setSecondModelViz(secondInputPort.getViz());
}
}
representation.setModelType(secondInputPort.modelMetadata.getModelType());
}
}
return representation;
}
@Override
protected PortObjectSpec[] configure(PortObjectSpec[] inSpecs) throws InvalidSettingsException {
ImagePortObjectSpec imageSpec = new ImagePortObjectSpec(SvgCell.TYPE);
return new PortObjectSpec[] {CombinedFskPortObjectSpec.INSTANCE, imageSpec};
}
private void loadFromPorts(JoinerViewValue joinerProxyValue) throws JsonProcessingException {
SwaggerUtil.setParameter(secondInputPort.modelMetadata,
JoinerNodeUtil.combineParameters(SwaggerUtil.getParameter(firstInputPort.modelMetadata),
SwaggerUtil.getParameter(secondInputPort.modelMetadata)));
joinerProxyValue.modelMetaData = MAPPER.writeValueAsString(secondInputPort.modelMetadata);
}
// second visualization script is the script which draw and control the plotting!
private String extractSecondObjectVis(FskPortObject object) {
if (!(object instanceof CombinedFskPortObject)) {
return object.getViz();
} else {
return extractSecondObjectVis(((CombinedFskPortObject) object).getSecondFskPortObject());
}
}
private void setScriptBack(FskPortObject fskObject1, FskPortObject fskObject2,
JsonArray scriptTree) {
JsonObject obj1 = scriptTree.getJsonObject(0);
if (obj1.containsKey("script")) {
fskObject1.setModel(obj1.getString("script"));
} else {
CombinedFskPortObject firstCombinedModel = (CombinedFskPortObject) fskObject1;
setScriptBack(firstCombinedModel.getFirstFskPortObject(),
firstCombinedModel.getSecondFskPortObject(), obj1.getJsonArray("nodes"));
}
JsonObject obj2 = scriptTree.getJsonObject(2);
if (obj2.containsKey("script")) {
fskObject2.setModel(obj2.getString("script"));
} else {
CombinedFskPortObject secondCombinedModel = (CombinedFskPortObject) fskObject2;
setScriptBack(secondCombinedModel.getFirstFskPortObject(),
secondCombinedModel.getSecondFskPortObject(), obj2.getJsonArray("nodes"));
}
}
private String buildModelscriptAsTree() {
JsonArrayBuilder array = Json.createArrayBuilder();
array.add(getModelScriptNode(firstInputPort).build());
JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
jsonObjectBuilder.add("id", "" + generateRandomUnifier());
jsonObjectBuilder.add("text", "Joining Script");
StringBuilder joinModel = new StringBuilder();
jsonObjectBuilder.add("script", joinModel.toString());
array.add(jsonObjectBuilder.build());
array.add(getModelScriptNode(secondInputPort).build());
return array.build().toString();
}
private static JsonArray getScriptArray(String input) {
try (JsonReader jsonReader = Json.createReader(new StringReader(input))) {
return jsonReader.readArray();
}
}
private JsonObjectBuilder getModelScriptNode(FskPortObject object) {
JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
jsonObjectBuilder.add("id", "" + generateRandomUnifier());
if (object instanceof CombinedFskPortObject) {
jsonObjectBuilder.add("text", "Joining Script");
StringBuilder joinModel = new StringBuilder();
if (((CombinedFskPortObject) object).getJoinerRelation() != null) {
Arrays.stream(((CombinedFskPortObject) object).getJoinerRelation()).forEach(connection -> {
joinModel.append(connection.getTargetParam() + " <- " + connection.getCommand() + ";\n");
});
}
jsonObjectBuilder.add("script", joinModel.toString());
FskPortObject first = ((CombinedFskPortObject) object).getFirstFskPortObject();
FskPortObject second = ((CombinedFskPortObject) object).getSecondFskPortObject();
JsonArrayBuilder array = Json.createArrayBuilder();
array.add(getModelScriptNode(first));
array.add(jsonObjectBuilder.build());
array.add(getModelScriptNode(second));
jsonObjectBuilder.add("nodes", array);
} else {
jsonObjectBuilder.add("text", SwaggerUtil.getModelName(object.modelMetadata));
jsonObjectBuilder.add("script", object.getModel());
}
return jsonObjectBuilder;
}
private static String generateRandomUnifier() {
return new AtomicLong((int) (100000 * Math.random())).toString();
}
@Override
protected void performReset() {
createEmptyViewValue();
setViewRepresentation(null);
nodeSettings.modelMetaData = null;
nodeSettings.connections = null;
firstInputPort = null;
secondInputPort = null;
}
@Override
protected void useCurrentValueAsDefault() {}
protected void loadJsonSetting() throws IOException, CanceledExecutionException, ParseException {
File directory =
NodeContext.getContext().getWorkflowManager().getContext().getCurrentLocation();
File settingFolder = new File(buildContainerName());
// Get flow variables
Map<String, FlowVariable> flowVariables;
if (NodeContext.getContext().getNodeContainer().getFlowObjectStack() != null) {
flowVariables = NodeContext.getContext().getNodeContainer().getFlowObjectStack()
.getAvailableFlowVariables();
} else {
flowVariables = Collections.emptyMap();
}
if (flowVariables.containsKey("JoinRelations.json")) {
String connectionString = flowVariables.get("JoinRelations.json").getStringValue();
try {
nodeSettings.connections = MAPPER.readValue(connectionString, JoinRelation[].class);
}catch(Exception ex) {
OldJoinerRelation[] oldRelations= MAPPER.readValue(connectionString, OldJoinerRelation[].class);
Function<OldJoinerRelation, JoinRelation> funcMigrateJoinerRelation= (OldJoinerRelation e)-> {return e.getNewJoinRelation();};
nodeSettings.connections = Arrays.stream(oldRelations).map(funcMigrateJoinerRelation
).collect(Collectors.toList()).toArray(new JoinRelation[oldRelations.length]);
}
} else {
File configFile = new File(settingFolder, "JoinRelations.json");
if (configFile.exists()) {
try {
nodeSettings.connections = MAPPER.readValue(configFile, JoinRelation[].class);
} catch (Exception ex) {
OldJoinerRelation[] oldRelations =
MAPPER.readValue(configFile, OldJoinerRelation[].class);
nodeSettings.connections =
Arrays.stream(oldRelations).map((OldJoinerRelation e) -> {
return e.getNewJoinRelation();
}).collect(Collectors.toList()).toArray(new JoinRelation[oldRelations.length]);
}
}
}
if (flowVariables.containsKey("modelMetaData.json")) {
nodeSettings.modelMetaData = flowVariables.get("modelMetaData.json").getStringValue();
} else {
File configFile = new File(settingFolder, "modelMetaData.json");
if (configFile.exists()) {
nodeSettings.modelMetaData = FileUtils.readFileToString(configFile, StandardCharsets.UTF_8);
}
}
List <Parameter> firstParams = new ArrayList<>();
if (flowVariables.containsKey("firstModelParameters.json")) {
String parametersString = flowVariables.get("firstModelParameters.json").getStringValue();
nodeSettings.firstModelParameters = MAPPER.readValue(parametersString, Parameter[].class);
} else {
File configFile = new File(settingFolder, "firstModelParameters.json");
if (configFile.exists()) {
nodeSettings.firstModelParameters = MAPPER.readValue(configFile, Parameter[].class);
}
configFile = new File(settingFolder, "modelMath1.json");
if (configFile.exists()) {
firstParams = getModelParametersfromOldFile(configFile);
nodeSettings.firstModelParameters = firstParams.toArray(new Parameter[firstParams.size()]);
}
}
if (flowVariables.containsKey("secondModelParameters.json")) {
String parametersString = flowVariables.get("secondModelParameters.json").getStringValue();
nodeSettings.secondModelParameters = MAPPER.readValue(parametersString, Parameter[].class);
} else {
File configFile = new File(settingFolder, "secondModelParameters.json");
if (configFile.exists()) {
nodeSettings.secondModelParameters = MAPPER.readValue(configFile, Parameter[].class);
}
configFile = new File(settingFolder, "modelMath2.json");
if (configFile.exists()) {
List <Parameter> secondParams = getModelParametersfromOldFile(configFile);
secondParams.removeAll(firstParams);
nodeSettings.secondModelParameters = secondParams.toArray(new Parameter[secondParams.size()]);
}
}
String sourceTree;
if (flowVariables.containsKey("sourceTree.json")) {
sourceTree = flowVariables.get("sourceTree.json").getStringValue();
} else {
File configFile = new File(settingFolder, "sourceTree.json");
if (configFile.exists()) {
sourceTree = FileUtils.readFileToString(configFile, StandardCharsets.UTF_8);
} else {
sourceTree = null;
}
}
String visualizationScript;
if (flowVariables.containsKey("visualization.txt")) {
visualizationScript = flowVariables.get("visualization.txt").getStringValue();
} else {
File configFile = new File(settingFolder, "visualization.txt");
if (configFile.exists()) {
visualizationScript = FileUtils.readFileToString(configFile, StandardCharsets.UTF_8);
} else {
visualizationScript = null;
}
}
JoinerViewValue viewValue = getViewValue();
viewValue.joinRelations = nodeSettings.connections;
viewValue.modelScriptTree = sourceTree;
viewValue.modelMetaData = nodeSettings.modelMetaData;
JoinerViewRepresentation representation = getViewRepresentation();
if (nodeSettings.firstModelParameters != null) {
representation.setFirstModelParameters(nodeSettings.firstModelParameters);
}
if (nodeSettings.secondModelParameters != null) {
representation.setSecondModelParameters(nodeSettings.secondModelParameters);
}
if (firstInputPort != null) {
List<Parameter> newFirstModelParameters =
SwaggerUtil.getParameter(firstInputPort.modelMetadata);
List<Parameter> newSecondModelParameters =
SwaggerUtil.getParameter(secondInputPort.modelMetadata);
if (!JoinerNodeUtil.parametersNeedUpdate(newFirstModelParameters,
JoinerNodeModel.SUFFIX_FIRST, JoinerNodeModel.SUFFIX_SECOND)) {
representation.updateParameters(newFirstModelParameters, newSecondModelParameters);
viewValue.updateParameters(newFirstModelParameters, newSecondModelParameters);
} else {
viewValue.modelMetaData = nodeSettings.modelMetaData;
}
}
representation.setSecondModelViz(visualizationScript);
}
/*
* A migration method, takes an old setting file and extract the data inside as list of
* de.bund.bfr.metadata.swagger.parameter
*/
private static List<Parameter> getModelParametersfromOldFile(File configFile)
throws FileNotFoundException, IOException, ParseException {
JsonNode nodes = MAPPER.readTree(configFile);
return new ArrayList<>(Arrays.asList(MAPPER.treeToValue(nodes.get("parameter") , Parameter[].class)));
}
@Override
protected void saveSettingsTo(NodeSettingsWO settings) {
File directory =
NodeContext.getContext().getWorkflowManager().getContext().getCurrentLocation();
File settingsFolder = new File(directory, buildContainerName());
if (!settingsFolder.exists()) {
settingsFolder.mkdir();
}
JoinerViewValue viewValue = getViewValue();
JoinerViewRepresentation representation = getViewRepresentation();
if (ArrayUtils.isNotEmpty(viewValue.joinRelations)) {
File configFile = new File(settingsFolder, "JoinRelations.json");
try {
MAPPER.writeValue(configFile, viewValue.joinRelations);
} catch (IOException e) {
// do nothing
}
}
if (StringUtils.isNotEmpty(viewValue.modelMetaData)) {
File configFile = new File(settingsFolder, "modelMetaData.json");
try {
FileUtils.writeStringToFile(configFile, viewValue.modelMetaData, StandardCharsets.UTF_8);
} catch (IOException e) {
// do nothing
}
}
if (ArrayUtils.isNotEmpty(representation.getFirstModelParameters())) {
File configFile = new File(settingsFolder, "firstModelParameters.json");
try {
MAPPER.writeValue(configFile, representation.getFirstModelParameters());
} catch (IOException e) {
// do nothing
}
}
if (ArrayUtils.isNotEmpty(representation.getSecondModelParameters())) {
File configFile = new File(settingsFolder, "secondModelParameters.json");
try {
MAPPER.writeValue(configFile, representation.getSecondModelParameters());
} catch (IOException e) {
// do nothing
}
}
if (StringUtils.isNotEmpty(viewValue.modelScriptTree)) {
File configFile = new File(settingsFolder, "sourceTree.json");
try {
FileUtils.writeStringToFile(configFile, viewValue.modelScriptTree, StandardCharsets.UTF_8);
} catch (IOException e) {
// do nothing
}
}
if (StringUtils.isNotEmpty(viewValue.getVisualizationScript())) {
File configFile = new File(settingsFolder, "visualization.txt");
try {
if (viewValue.getVisualizationScript() != "")
representation.setSecondModelViz(viewValue.getVisualizationScript());
FileUtils.writeStringToFile(configFile, representation.getSecondModelViz(),
StandardCharsets.UTF_8);
} catch (IOException e) {
// do nothing
}
}
}
@Override
protected void loadValidatedSettingsFrom(NodeSettingsRO settings)
throws InvalidSettingsException {
try {
loadJsonSetting();
} catch (IOException | CanceledExecutionException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
@Override
protected void validateSettings(NodeSettingsRO settings) throws InvalidSettingsException {}
@Override
public PortObject[] getInternalPortObjects() {
return new PortObject[] {firstInputPort, secondInputPort};
}
@Override
public void setInternalPortObjects(PortObject[] portObjects) {
if (portObjects != null && portObjects.length == 2) {
firstInputPort = (FskPortObject) portObjects[0];
secondInputPort = (FskPortObject) portObjects[1];
}
}
public void setHideInWizard(boolean hide) {}
/** @return string with node name and id with format "{name} (#{id}) setting". */
private static String buildContainerName() {
final NodeContainer nodeContainer = NodeContext.getContext().getNodeContainer();
return nodeContainer.getNodeContainerDirectory() + " setting";
}
@Override
protected void performExecuteCreateView(PortObject[] inObjects, ExecutionContext exec)
throws Exception {
final String nodeWithId = NodeContext.getContext().getNodeContainer().getNameWithID();
NodeContext.getContext().getWorkflowManager()
.addListener(new NodeRemovedListener(nodeWithId, buildContainerName()));
setInternalPortObjects(inObjects);
JoinerNodeUtil.addIdentifierToParameters(SwaggerUtil.getParameter(firstInputPort.modelMetadata),
SwaggerUtil.getParameter(secondInputPort.modelMetadata));
synchronized (getLock()) {
JoinerViewValue value = getViewValue();
if (value.modelMetaData == null) {
value.modelScriptTree = buildModelscriptAsTree();
loadJsonSetting();
if (value.modelMetaData == null) {
loadFromPorts(value);
}
exec.setProgress(1);
}
}
}
@Override
protected PortObject[] performExecuteCreatePortObjects(PortObject svgImageFromView,
PortObject[] inObjects, ExecutionContext exec) throws Exception {
CombinedFskPortObject outObj = new CombinedFskPortObject(Optional.empty(), new ArrayList<>(),
firstInputPort, secondInputPort);
JoinRelation[] connections = new JoinRelation[0];
synchronized (getLock()) {
JoinerViewValue value = getViewValue();
if (value.joinRelations != null) {
connections = value.joinRelations;
} else if (nodeSettings.connections != null) {
connections = nodeSettings.connections;
}
outObj.setJoinerRelation(connections);
// Give CombinedModel some metadata (for now: from second portObject)
// Consider Here that the model type is the same as the second model
if (StringUtils.isNotEmpty(value.modelMetaData)) {
outObj.modelMetadata = MAPPER.readValue(value.modelMetaData,
SwaggerUtil.modelClasses.get(secondInputPort.modelMetadata.getModelType()));
} else {
outObj.modelMetadata = secondInputPort.modelMetadata;
}
// change default values for CombinedModel to those of the currently selected simulations
// (model1 & model2)
JoinerNodeUtil.createDefaultParameterValues(
firstInputPort.simulations.get(firstInputPort.selectedSimulationIndex),
secondInputPort.simulations.get(secondInputPort.selectedSimulationIndex),
SwaggerUtil.getParameter(outObj.modelMetadata));
// give the new combined model a name:
// suggestion: model1.name + model2.name
if (StringUtils.isNotEmpty(value.modelScriptTree)) {
JsonArray scriptTree = getScriptArray(value.modelScriptTree);
setScriptBack(firstInputPort, secondInputPort, scriptTree);
} else {
value.modelScriptTree = buildModelscriptAsTree();
}
Set<String> packageSet = new HashSet<>();
packageSet.addAll(firstInputPort.packages);
packageSet.addAll(secondInputPort.packages);
outObj.packages.addAll(packageSet);
JoinerNodeUtil.removeJoinedParameters(connections, outObj);
// Create default simulation out of parameters metadata
JoinerNodeUtil.createDefaultSimulation(outObj);
// add all possible simulations to combined object
JoinerNodeUtil.createAllPossibleSimulations(firstInputPort, secondInputPort, outObj);
// update second visualization script from the view
if (value.getVisualizationScript() == "")
setLastVisualizationScript(outObj, this.getViewRepresentation().getSecondModelViz());
// outObj.getSecondFskPortObject().viz = this.getViewRepresentation().getSecondModelViz();
else
setLastVisualizationScript(outObj, value.getVisualizationScript());
// outObj.getSecondFskPortObject().viz = value.getVisualizationScript();
// remove suffix from original parameters since they are needed with their original id for the
// scripts
if (value.joinRelations != null) {
resetParameterIdToOriginal(
SwaggerUtil.getParameter(outObj.getFirstFskPortObject().modelMetadata));
resetParameterIdToOriginal(
SwaggerUtil.getParameter(outObj.getSecondFskPortObject().modelMetadata));
}
}
return new PortObject[] {outObj, svgImageFromView};
}
private void setLastVisualizationScript(FskPortObject fskObj, String viz) {
if (fskObj instanceof CombinedFskPortObject)
setLastVisualizationScript(((CombinedFskPortObject) fskObj).getSecondFskPortObject(), viz);
else
fskObj.setViz(viz);
}
private void resetParameterIdToOriginal(List<Parameter> parameter) {
for (Parameter p : parameter) {
p.setId(p.getId().substring(0, p.getId().length() - 1));
}
}
@Override
protected boolean generateImage() {
return true;
}
}