updater = new Updater();
}
WizardLogic create(final List<? extends ScriptTargetMapping> targetList,
final ErrorPositionHighlighter positionHighlighter) {
Scope scope = updater.rootScope();
final boolean skipSingleTargetSelection = true;
// Wizard logic is described from the first page toward the last pages.
final PageImpl<PushChangesWizard.ChooseVmPageElements> chooseVmPage =
pageSet.getChooseVmPage();
// A value corresponding to selected VMs on 'choose vm' page.
final ValueSource<List<ScriptTargetMapping>> selectedVmInput =
new ValueSource<List<ScriptTargetMapping>>() {
private final ChooseVmControl.Logic chooseVmControl =
chooseVmPage.getPageElements().getChooseVm();
{
chooseVmControl.setData(targetList);
chooseVmControl.selectAll();
final ValueSource<?> thisSource = this;
ChooseVmControl.Logic.Listener listener = new ChooseVmControl.Logic.Listener() {
public void checkStateChanged() {
updater.reportChanged(thisSource);
updater.update();
}
};
chooseVmControl.addListener(listener);
}
public List<ScriptTargetMapping> getValue() {
return chooseVmControl.getSelected();
}
};
updater.addSource(scope, selectedVmInput);
final ValueProcessor<? extends List<Optional<PushChangesPlan>>> selectedChangePlansValue =
createProcessor(new Gettable<List<Optional<PushChangesPlan>>>() {
@Override
public List<Optional<PushChangesPlan>> getValue() {
List<ScriptTargetMapping> input = selectedVmInput.getValue();
List<Optional<PushChangesPlan>> result =
new ArrayList<DialogUtils.Optional<PushChangesPlan>>(input.size());
for (ScriptTargetMapping mapping : input) {
Optional<PushChangesPlan> optionalPlan;
try {
PushChangesPlan plan = PushChangesPlan.create(mapping);
optionalPlan = createOptional(plan);
} catch (RuntimeException e) {
// TODO: have more specific exception types to catch.
optionalPlan = createErrorOptional(new Message(
Messages.WizardLogicBuilder_FAILED_TO_GET,
MessagePriority.BLOCKING_PROBLEM));
}
result.add(optionalPlan);
}
return result;
}
});
updater.addSource(scope, selectedChangePlansValue);
updater.addConsumer(scope, selectedChangePlansValue);
updater.addDependency(selectedChangePlansValue, selectedVmInput);
// A derived value of selected VMs list; the list is non-empty or the value is error.
final ValueProcessor<? extends Optional<List<PushChangesPlan>>> nonEmptySelectedPlansValue =
createProcessor(new Gettable<Optional<List<PushChangesPlan>>>() {
public Optional<List<PushChangesPlan>> getValue() {
List<Optional<PushChangesPlan>> planList = selectedChangePlansValue.getValue();
if (planList.isEmpty()) {
return createErrorOptional(
new Message(Messages.WizardLogicBuilder_CHOOSE_VM, MessagePriority.BLOCKING_INFO));
}
List<Message> errorMessages = new LinkedList<Message>();
List<PushChangesPlan> result = new ArrayList<PushChangesPlan>(planList.size());
for (Optional<PushChangesPlan> optionalPlan : planList) {
if (optionalPlan.isNormal()) {
result.add(optionalPlan.getNormal());
} else {
errorMessages.addAll(optionalPlan.errorMessages());
}
}
if (errorMessages.isEmpty()) {
return createOptional(result);
} else {
return createErrorOptional(new HashSet<Message>(errorMessages));
}
}
});
updater.addSource(scope, nonEmptySelectedPlansValue);
updater.addConsumer(scope, nonEmptySelectedPlansValue);
updater.addDependency(nonEmptySelectedPlansValue, selectedChangePlansValue);
// A condition value for up-coming fork between 'single vm' and 'multiple vm' paths.
Gettable<? extends Optional<? extends Boolean>> singleVmSelectedExpression = handleErrors(
new NormalExpression<Boolean>() {
@Calculate
public Boolean calculate(List<PushChangesPlan> selectedVm) {
return selectedVm.size() == 1;
}
@DependencyGetter
public ValueSource<? extends Optional<List<PushChangesPlan>>> getSelectVmSource() {
return nonEmptySelectedPlansValue;
}
});
// A switch between 2 paths: 'single vm' and 'multiple vm'.
OptionalSwitcher<Boolean> singleVmSelectedSwitch =
scope.addOptionalSwitch(singleVmSelectedExpression);
final PreviewAndOptionPath singleVmPath =
createSingleVmPath(chooseVmPage, singleVmSelectedSwitch, nonEmptySelectedPlansValue);
final PreviewAndOptionPath multipleVmPath =
createMultipleVmPath(chooseVmPage, singleVmSelectedSwitch, nonEmptySelectedPlansValue);