package hu.sztaki.ilab.longneck.process.kernel; import hu.sztaki.ilab.longneck.Record; import hu.sztaki.ilab.longneck.process.CheckError; import hu.sztaki.ilab.longneck.process.FrameAddress; import hu.sztaki.ilab.longneck.process.block.SwitchStrict; import hu.sztaki.ilab.longneck.process.constraint.CheckResult; import java.util.ArrayList; import java.util.List; /** * * @author Lukacs Gabor <lukacsg@sztaki.mta.hu> */ class SwitchStrictControl implements StartHandler, SuccessHandler, ErrorHandler { /** The switch object under execution. */ private final SwitchStrict switchObj; /** List of errors that occured during execution. */ private List<CheckResult> errors = new ArrayList<CheckResult>(); /** Last executed case. */ private int lastCase = 0; public SwitchStrictControl(SwitchStrict switchObj) { this.switchObj = switchObj; } @Override public void beforeChildren(KernelState kernelState, Record record) { record.saveState(); } @Override public void onSuccess(KernelState kernelState, Record record) throws RedirectException { // Clean exit record.removeState(); // Jump to next frame throw new RedirectException(FrameAddress.RETURN); } @Override public void onError(KernelState kernelState, Record record) throws CheckError { // Roll back changes record.restoreState(); record.saveState(); // Add errors to error state errors.add(kernelState.getLastError().getCheckResult()); kernelState.clearError(); // Increase case counter ++lastCase; if (lastCase >= switchObj.getCases().size()) { throw new CheckError( new CheckResult(switchObj, false, null, null, "All cases failed.", errors)); } } @Override public SwitchStrictControl clone() { try { SwitchStrictControl copy = (SwitchStrictControl) super.clone(); // Copy errors copy.errors = new ArrayList<CheckResult>(); for (CheckResult cr : errors) { copy.errors.add(cr); } return copy; } catch (CloneNotSupportedException ex) { throw new AssertionError(ex); } } }