/* * Copyright 2015 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.robotframework.ide.eclipse.main.plugin.model.cmd; import static com.google.common.collect.Lists.newArrayList; import java.util.ArrayList; import java.util.List; import org.rf.ide.core.testdata.model.AModelElement; import org.rf.ide.core.testdata.model.presenter.update.IExecutablesTableModelUpdater; import org.robotframework.ide.eclipse.main.plugin.model.RobotCodeHoldingElement; import org.robotframework.ide.eclipse.main.plugin.model.RobotDefinitionSetting; import org.robotframework.ide.eclipse.main.plugin.model.RobotKeywordCall; import org.robotframework.ide.eclipse.main.plugin.model.RobotModelEvents; import org.robotframework.ide.eclipse.main.plugin.tableeditor.EditorCommand; import org.robotframework.ide.eclipse.main.plugin.views.documentation.DocumentationView; public class SetKeywordCallArgumentCommand extends EditorCommand { protected final RobotKeywordCall keywordCall; protected final int index; protected final String value; protected boolean shouldReplaceValue; protected String previousValue; public SetKeywordCallArgumentCommand(final RobotKeywordCall keywordCall, final int index, final String value) { this(keywordCall, index, value, true); } protected SetKeywordCallArgumentCommand(final RobotKeywordCall keywordCall, final int index, final String value, final boolean shouldReplaceValue) { this.keywordCall = keywordCall; this.index = index; this.value = value; this.shouldReplaceValue = shouldReplaceValue; } @Override public void execute() throws CommandExecutionException { final boolean isSetting = keywordCall instanceof RobotDefinitionSetting; final List<String> arguments = prepareArgumentsList(keywordCall, value, index, isSetting); if (!arguments.equals(keywordCall.getArguments())) { updateModelElement(arguments); keywordCall.resetStored(); if (isSetting && ((RobotDefinitionSetting) keywordCall).isDocumentation()) { eventBroker.post(DocumentationView.REFRESH_DOC_EVENT_TOPIC, keywordCall); } eventBroker.send(RobotModelEvents.ROBOT_KEYWORD_CALL_ARGUMENT_CHANGE, keywordCall); } } private List<String> prepareArgumentsList(final RobotKeywordCall call, final String value, final int index, final boolean isSetting) { final List<String> arguments = createArgumentsList(call, index); previousValue = index >= 0 && index < arguments.size() ? arguments.get(index) : value; fillArgumentsList(value, index, arguments, shouldReplaceValue); checkIfPreviousCommandWasAddingNewValue(); checkIfUndoCommandShouldAddArgument(arguments.get(index), isSetting); return arguments; } public static List<String> createArgumentsList(final RobotKeywordCall call, final int index) { final List<String> arguments = call == null ? new ArrayList<String>() : newArrayList(call.getArguments()); for (int i = arguments.size(); i <= index; i++) { arguments.add("\\"); } return arguments; } public static void fillArgumentsList(final String value, final int index, final List<String> arguments, final boolean shouldReplaceValue) { final String newValue = value == null || value.trim().isEmpty() ? "\\" : value; if (shouldReplaceValue) { arguments.set(index, newValue); } else { arguments.add(index, newValue); } for (int i = arguments.size() - 1; i >= 0; i--) { if (!arguments.get(i).equals("\\")) { break; } arguments.set(i, null); } } private void checkIfPreviousCommandWasAddingNewValue() { if(!shouldReplaceValue) { previousValue = null; // when new value was not replaced but added by undo command, then redo command should remove this value } } private void checkIfUndoCommandShouldAddArgument(final String currentArgValue, final boolean isSetting) { if(currentArgValue != null && currentArgValue.equals("\\") && value == null && !isFirstArgumentInKeywordBasedSetting(isSetting)) { shouldReplaceValue = false; // when arg is deleted not on last position, undo command will add new arg on this position and shifts other args to the right } else { shouldReplaceValue = true; // reset the flag for future undo commands } } private boolean isFirstArgumentInKeywordBasedSetting(final boolean isSetting) { if (isSetting && ((RobotDefinitionSetting) keywordCall).isKeywordBased()) { return index == 0; } return false; } protected void updateModelElement(final List<String> arguments) { final RobotCodeHoldingElement<?> parent = (RobotCodeHoldingElement<?>) keywordCall.getParent(); final IExecutablesTableModelUpdater<?> updater = parent.getModelUpdater(); final AModelElement<?> linkedElement = keywordCall.getLinkedElement(); if (value != null) { for (int i = arguments.size() - 1; i >= 0; i--) { updater.updateArgument(linkedElement, i, arguments.get(i)); } } else { updater.updateArgument(linkedElement, index, value); } } @Override public List<EditorCommand> getUndoCommands() { return newUndoCommands(new SetKeywordCallArgumentCommand(keywordCall, index, previousValue, shouldReplaceValue)); } }