/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.gui.workflow.editor.properties;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
import de.rcenvironment.core.component.api.LoopComponentConstants;
import de.rcenvironment.core.component.api.LoopComponentConstants.LoopBehaviorInCaseOfFailure;
import de.rcenvironment.core.component.workflow.model.api.WorkflowNode;
import de.rcenvironment.core.gui.utils.incubator.NumericalTextConstraintListener;
import de.rcenvironment.core.gui.utils.incubator.WidgetGroupFactory;
/**
* Config gui for behavior in case of loop failure.
*
* @author Doreen Seider
*/
public class FaultTolerantLoopSection extends ValidatingWorkflowNodePropertySection {
private static final String TEXT_DISCARD = "Discard the evaluation loop run and continue with next one";
private static final String TEXT_FINALLY_FAIL =
"If an evaluation loop run was discarded, finally fail on loop termination (only applicable outside nested loops)";
private static final String TEXT_ONLY_FAIL_LOOP =
"Only fail the loop and forward failure to outer loop (only applicable if used in nested loop)";
private Button failRadioButtonNAV;
private Button discardAndContinueRadioButtonNAV;
private Button rerunAndDiscardRadioButtonNAV;
private Text rerunTimesAndFailTextNAV;
private Button rerunAndFailRadioButtonNAV;
private Text rerunTimesAndDiscardTextNAV;
private Label rerunTimesAndDiscardLabelNAV;
private Button failLoopIfAnyRunFailedCheckboxNAV;
private Button onlyFailLoopCheckboxNAV;
private Button failRadioButtonCmpFlr;
private Button discardAndContinueRadioButtonCmpFlr;
private boolean canHandleNaVValues;
@Override
protected void createCompositeContent(final Composite parent, final TabbedPropertySheetPage aTabbedPropertySheetPage) {
parent.setLayout(new GridLayout(1, true));
TabbedPropertySheetWidgetFactory factory = aTabbedPropertySheetPage.getWidgetFactory();
final Section sectionPropertiesNAV = factory.createSection(parent, Section.TITLE_BAR | Section.EXPANDED);
sectionPropertiesNAV.setText("Fault-tolerance in case of 'not-a-value' received");
final Composite compositeNAV = factory.createFlatFormComposite(sectionPropertiesNAV);
compositeNAV.setLayout(new GridLayout(3, false));
factory.createLabel(compositeNAV, "If a component in the loop sent 'not-a-value':");
BehaviorInCaseOfFailureSelectionListenerNAV listenerNAV = new BehaviorInCaseOfFailureSelectionListenerNAV();
failRadioButtonNAV = factory.createButton(compositeNAV, "Fail", SWT.RADIO);
spanHorizontal(failRadioButtonNAV);
failRadioButtonNAV.setData(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_NAV, LoopBehaviorInCaseOfFailure.Fail);
failRadioButtonNAV.addSelectionListener(listenerNAV);
discardAndContinueRadioButtonNAV = factory.createButton(compositeNAV, TEXT_DISCARD, SWT.RADIO);
spanHorizontal(discardAndContinueRadioButtonNAV);
discardAndContinueRadioButtonNAV.setData(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_NAV,
LoopBehaviorInCaseOfFailure.Discard);
discardAndContinueRadioButtonNAV.addSelectionListener(listenerNAV);
rerunAndFailRadioButtonNAV = factory.createButton(compositeNAV,
"Rerun the evaluation loop at the maximum of", SWT.RADIO);
rerunAndFailRadioButtonNAV.setData(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_NAV,
LoopBehaviorInCaseOfFailure.RerunAndFail);
rerunAndFailRadioButtonNAV.addSelectionListener(listenerNAV);
final int width = 40;
rerunTimesAndFailTextNAV = new Text(compositeNAV, SWT.BORDER | (SWT.CENTER & WidgetGroupFactory.ALIGN_CENTER));
GridData gridData = new GridData(SWT.CENTER & WidgetGroupFactory.ALIGN_CENTER);
gridData.widthHint = width;
rerunTimesAndFailTextNAV.setLayoutData(gridData);
rerunTimesAndFailTextNAV.setData(WorkflowNodePropertiesSection.CONTROL_PROPERTY_KEY,
LoopComponentConstants.CONFIG_KEY_MAX_RERUN_BEFORE_FAIL_NAV);
rerunTimesAndFailTextNAV.addVerifyListener(new NumericalTextConstraintListener(rerunTimesAndFailTextNAV,
NumericalTextConstraintListener.GREATER_ZERO | NumericalTextConstraintListener.ONLY_INTEGER));
factory.createLabel(compositeNAV, "time(s) and fail if maximum exceeded");
rerunAndDiscardRadioButtonNAV = factory.createButton(compositeNAV,
"Rerun the evaluation loop at the maximum of", SWT.RADIO);
rerunAndDiscardRadioButtonNAV.setData(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_NAV,
LoopBehaviorInCaseOfFailure.RerunAndDiscard);
rerunAndDiscardRadioButtonNAV.addSelectionListener(listenerNAV);
rerunTimesAndDiscardTextNAV = new Text(compositeNAV, SWT.BORDER | (SWT.CENTER & WidgetGroupFactory.ALIGN_CENTER));
gridData = new GridData();
gridData.widthHint = width;
rerunTimesAndDiscardTextNAV.setLayoutData(gridData);
rerunTimesAndDiscardTextNAV.setData(WorkflowNodePropertiesSection.CONTROL_PROPERTY_KEY,
LoopComponentConstants.CONFIG_KEY_MAX_RERUN_BEFORE_DISCARD_NAV);
rerunTimesAndDiscardTextNAV.addVerifyListener(new NumericalTextConstraintListener(rerunTimesAndDiscardTextNAV,
NumericalTextConstraintListener.GREATER_ZERO | NumericalTextConstraintListener.ONLY_INTEGER));
rerunTimesAndDiscardLabelNAV = factory.createLabel(compositeNAV, "time(s) and discard if maximum exceeded");
failLoopIfAnyRunFailedCheckboxNAV = factory.createButton(compositeNAV, TEXT_FINALLY_FAIL, SWT.CHECK);
spanHorizontal(failLoopIfAnyRunFailedCheckboxNAV);
failLoopIfAnyRunFailedCheckboxNAV.setData(WorkflowNodePropertiesSection.CONTROL_PROPERTY_KEY,
LoopComponentConstants.CONFIG_KEY_FINALLY_FAIL_IF_DISCARDED_NAV);
onlyFailLoopCheckboxNAV = factory.createButton(compositeNAV, TEXT_ONLY_FAIL_LOOP, SWT.CHECK);
spanHorizontal(onlyFailLoopCheckboxNAV);
onlyFailLoopCheckboxNAV.setData(WorkflowNodePropertiesSection.CONTROL_PROPERTY_KEY,
LoopComponentConstants.CONFIG_KEY_FAIL_LOOP_ONLY_NAV);
sectionPropertiesNAV.setClient(compositeNAV);
final Section sectionPropertiesCmpFlr = factory.createSection(parent, Section.TITLE_BAR | Section.EXPANDED);
sectionPropertiesCmpFlr.setText("Fault-tolerance in case of component failure");
final Composite compositeCmpFlr = factory.createFlatFormComposite(sectionPropertiesCmpFlr);
compositeCmpFlr.setLayout(new GridLayout(1, false));
compositeCmpFlr.setLayoutData(gridData);
factory.createLabel(compositeCmpFlr, "If a component in the loop fails:");
BehaviorInCaseOfFailureSelectionListenerCompFailure listenerCmpFlr = new BehaviorInCaseOfFailureSelectionListenerCompFailure();
failRadioButtonCmpFlr = factory.createButton(compositeCmpFlr, "Fail component", SWT.RADIO);
spanHorizontal(failRadioButtonCmpFlr);
failRadioButtonCmpFlr.setData(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_COMP_FAILURE,
LoopBehaviorInCaseOfFailure.Fail);
failRadioButtonCmpFlr.addSelectionListener(listenerCmpFlr);
discardAndContinueRadioButtonCmpFlr = factory.createButton(compositeCmpFlr, TEXT_DISCARD, SWT.RADIO);
spanHorizontal(discardAndContinueRadioButtonCmpFlr);
discardAndContinueRadioButtonCmpFlr.setData(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_COMP_FAILURE,
LoopBehaviorInCaseOfFailure.Discard);
discardAndContinueRadioButtonCmpFlr.addSelectionListener(listenerCmpFlr);
sectionPropertiesCmpFlr.setClient(compositeCmpFlr);
}
private void spanHorizontal(Control control) {
GridData gridData = new GridData();
gridData.horizontalSpan = 3;
control.setLayoutData(gridData);
}
@Override
protected void setWorkflowNode(WorkflowNode workflowNode) {
super.setWorkflowNode(workflowNode);
LoopBehaviorInCaseOfFailure loopBehaviorInCaseOfFailureNAV = LoopBehaviorInCaseOfFailure.fromString(
getProperty(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_NAV));
LoopBehaviorInCaseOfFailure loopBehaviorInCaseOfFailureCmpFlr = LoopBehaviorInCaseOfFailure.fromString(
getProperty(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_COMP_FAILURE));
canHandleNaVValues = workflowNode.getComponentDescription().getComponentInterface().getCanHandleNotAValueDataTypes();
failRadioButtonNAV.setSelection(loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.Fail));
failRadioButtonCmpFlr.setSelection(loopBehaviorInCaseOfFailureCmpFlr.equals(LoopBehaviorInCaseOfFailure.Fail));
rerunAndFailRadioButtonNAV.setSelection(loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.RerunAndFail));
rerunTimesAndFailTextNAV.setEnabled(loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.RerunAndFail));
onlyFailLoopCheckboxNAV.setEnabled((loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.Fail)
|| loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.RerunAndFail))
&& Boolean.valueOf(getProperty(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP)));
discardAndContinueRadioButtonNAV.setEnabled(canHandleNaVValues);
discardAndContinueRadioButtonCmpFlr.setEnabled(canHandleNaVValues);
rerunAndDiscardRadioButtonNAV.setEnabled(canHandleNaVValues);
rerunTimesAndDiscardTextNAV.setEnabled(canHandleNaVValues);
rerunTimesAndDiscardLabelNAV.setEnabled(canHandleNaVValues);
failLoopIfAnyRunFailedCheckboxNAV.setEnabled(canHandleNaVValues
&& !Boolean.valueOf(getProperty(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP)));
if (canHandleNaVValues) {
discardAndContinueRadioButtonNAV.setSelection(loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.Discard));
discardAndContinueRadioButtonCmpFlr.setSelection(loopBehaviorInCaseOfFailureCmpFlr.equals(LoopBehaviorInCaseOfFailure.Discard));
rerunAndDiscardRadioButtonNAV.setSelection(loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.RerunAndDiscard));
rerunTimesAndDiscardTextNAV.setEnabled(loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.RerunAndDiscard));
failLoopIfAnyRunFailedCheckboxNAV.setEnabled(failLoopIfAnyRunFailedCheckboxNAV.getEnabled()
&& (loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.Discard)
|| loopBehaviorInCaseOfFailureNAV.equals(LoopBehaviorInCaseOfFailure.RerunAndDiscard)));
}
setSelectionOfCheckbox();
}
@Override
public void aboutToBeShown() {
super.aboutToBeShown();
failLoopIfAnyRunFailedCheckboxNAV.setEnabled(failLoopIfAnyRunFailedCheckboxNAV.getEnabled()
&& !Boolean.valueOf(getProperty(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP)));
onlyFailLoopCheckboxNAV.setEnabled(Boolean.valueOf(getProperty(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP)));
setSelectionOfCheckbox();
}
private void setSelectionOfCheckbox() {
if (!failLoopIfAnyRunFailedCheckboxNAV.isEnabled()) {
failLoopIfAnyRunFailedCheckboxNAV.setSelection(false);
}
if (!onlyFailLoopCheckboxNAV.isEnabled()) {
onlyFailLoopCheckboxNAV.setSelection(false);
}
}
/**
* {@link SelectionListener} for the radio buttons.
*
* @author Doreen Seider
*/
private class BehaviorInCaseOfFailureSelectionListenerNAV implements SelectionListener {
@Override
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
@Override
public void widgetSelected(SelectionEvent event) {
Button button = ((Button) event.getSource());
setProperty(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_NAV,
button.getData(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_NAV).toString());
rerunTimesAndFailTextNAV.setEnabled(button == rerunAndFailRadioButtonNAV);
rerunTimesAndDiscardTextNAV.setEnabled(button == rerunAndDiscardRadioButtonNAV);
failLoopIfAnyRunFailedCheckboxNAV.setEnabled(!Boolean.valueOf(getProperty(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP))
&& (button == discardAndContinueRadioButtonNAV || button == rerunAndDiscardRadioButtonNAV));
onlyFailLoopCheckboxNAV
.setEnabled((button == failRadioButtonNAV || button == rerunAndFailRadioButtonNAV)
&& Boolean.valueOf(getProperty(LoopComponentConstants.CONFIG_KEY_IS_NESTED_LOOP)));
setSelectionOfCheckbox();
}
}
/**
* {@link SelectionListener} for the radio buttons.
*
* @author Doreen Seider
*/
private class BehaviorInCaseOfFailureSelectionListenerCompFailure implements SelectionListener {
@Override
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
@Override
public void widgetSelected(SelectionEvent event) {
Button button = ((Button) event.getSource());
setProperty(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_COMP_FAILURE,
button.getData(LoopComponentConstants.CONFIG_KEY_LOOP_FAULT_TOLERANCE_COMP_FAILURE).toString());
}
}
}