/* * 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; import static com.google.common.collect.Lists.newArrayList; import java.io.ObjectStreamException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; import java.util.List; import java.util.Optional; import org.eclipse.jface.resource.ImageDescriptor; import org.rf.ide.core.testdata.model.AModelElement; import org.rf.ide.core.testdata.model.ModelType; import org.rf.ide.core.testdata.model.presenter.update.IExecutablesTableModelUpdater; import org.rf.ide.core.testdata.model.presenter.update.TestCaseTableModelUpdater; import org.rf.ide.core.testdata.model.table.RobotExecutableRow; import org.rf.ide.core.testdata.model.table.testcases.TestCase; import org.rf.ide.core.testdata.text.read.recognizer.RobotTokenType; import org.robotframework.ide.eclipse.main.plugin.RedImages; public class RobotCase extends RobotCodeHoldingElement<TestCase> { private static final long serialVersionUID = 1L; RobotCase(final RobotCasesSection parent, final TestCase testCase) { super(parent, testCase); } @Override public IExecutablesTableModelUpdater<TestCase> getModelUpdater() { return new TestCaseTableModelUpdater(); } @Override protected ModelType getExecutableRowModelType() { return ModelType.TEST_CASE_EXECUTABLE_ROW; } @Override public RobotTokenType getSettingDeclarationTokenTypeFor(final String name) { return RobotTokenType.findTypeOfDeclarationForTestCaseSettingTable(name); } public void link() { final TestCase testCase = getLinkedElement(); final List<PrioriterizedCaseSettings> settings = newArrayList(EnumSet.allOf(PrioriterizedCaseSettings.class)); Collections.sort(settings); // settings for (final PrioriterizedCaseSettings setting : settings) { for (final AModelElement<TestCase> element : setting.getModelElements(testCase)) { getChildren().add(new RobotDefinitionSetting(this, element)); } } // executables for (final RobotExecutableRow<TestCase> execRow : testCase.getTestExecutionRows()) { getChildren().add(new RobotKeywordCall(this, execRow)); } } @Override public void fixChildrenOrder() { Collections.sort(getChildren(), new Comparator<RobotKeywordCall>() { @Override public int compare(final RobotKeywordCall call1, final RobotKeywordCall call2) { if (call1 instanceof RobotDefinitionSetting && call2 instanceof RobotDefinitionSetting) { final ModelType modelType1 = call1.getLinkedElement().getModelType(); final ModelType modelType2 = call2.getLinkedElement().getModelType(); return PrioriterizedCaseSettings.from(modelType1).compareTo(PrioriterizedCaseSettings.from(modelType2)); } else if (call1 instanceof RobotDefinitionSetting && !(call2 instanceof RobotDefinitionSetting)) { return -1; } else if (!(call1 instanceof RobotDefinitionSetting) && call2 instanceof RobotDefinitionSetting) { return 1; } else { // sort is stable so we don't care about those cases return 0; } } }); } @Override public RobotCasesSection getParent() { return (RobotCasesSection) super.getParent(); } @Override public ImageDescriptor getImage() { final TestCase testCase = getLinkedElement(); return testCase != null && testCase.isDataDrivenTestCase() ? RedImages.getTemplatedTestCaseImage() : RedImages.getTestCaseImage(); } public List<RobotDefinitionSetting> getTagsSetting() { return findSettings(ModelType.TEST_CASE_TAGS); } public Optional<String> getTemplateInUse() { return Optional.ofNullable(getLinkedElement().getTemplateKeywordName()); } @Override public void moveChildDown(final RobotKeywordCall keywordCall) { final int index = keywordCall.getIndex(); Collections.swap(getChildren(), index, index + 1); @SuppressWarnings("unchecked") final RobotExecutableRow<TestCase> linkedCall = (RobotExecutableRow<TestCase>) keywordCall.getLinkedElement(); getLinkedElement().moveDownExecutableRow(linkedCall); } @Override public void moveChildUp(final RobotKeywordCall keywordCall) { final int index = keywordCall.getIndex(); Collections.swap(getChildren(), index, index - 1); @SuppressWarnings("unchecked") final RobotExecutableRow<TestCase> linkedCall = (RobotExecutableRow<TestCase>) keywordCall.getLinkedElement(); getLinkedElement().moveUpExecutableRow(linkedCall); } @SuppressWarnings("unchecked") private Object readResolve() throws ObjectStreamException { // after deserialization we fix parent relationship in direct children for (final RobotKeywordCall call : getChildren()) { ((AModelElement<TestCase>) call.getLinkedElement()).setParent(getLinkedElement()); call.setParent(this); } return this; } @Override public String toString() { // for debugging purposes only return getName(); } static enum PrioriterizedCaseSettings { // the order is defined by enums definitions order (see Enum.compareTo() method javadoc) DOCUMENTATION, TAGS, SETUP, TEARDOWN, TEMPLATE, TIMEOUT, UNKNOWN; public List<? extends AModelElement<TestCase>> getModelElements(final TestCase testCase) { switch (this) { case DOCUMENTATION: return testCase.getDocumentation(); case TAGS: return testCase.getTags(); case SETUP: return testCase.getSetups(); case TEARDOWN: return testCase.getTeardowns(); case TEMPLATE: return testCase.getTemplates(); case TIMEOUT: return testCase.getTimeouts(); case UNKNOWN: return testCase.getUnknownSettings(); default: return new ArrayList<>(); } } public static PrioriterizedCaseSettings from(final ModelType modelType) { switch (modelType) { case TEST_CASE_DOCUMENTATION: return DOCUMENTATION; case TEST_CASE_TAGS: return TAGS; case TEST_CASE_SETUP: return SETUP; case TEST_CASE_TEARDOWN: return TEARDOWN; case TEST_CASE_TEMPLATE: return TEMPLATE; case TEST_CASE_TIMEOUT: return TIMEOUT; case TEST_CASE_SETTING_UNKNOWN: return UNKNOWN; default: throw new IllegalArgumentException("No setting defined for " + modelType.name()); } } } }