package hu.sztaki.ilab.longneck.process.kernel; import hu.sztaki.ilab.longneck.process.VariableSpace; import hu.sztaki.ilab.longneck.process.block.Block; import hu.sztaki.ilab.longneck.process.block.BlockReference; import hu.sztaki.ilab.longneck.process.block.Caching; import hu.sztaki.ilab.longneck.process.block.CompoundBlock; import hu.sztaki.ilab.longneck.process.block.If; import hu.sztaki.ilab.longneck.process.block.Switch; import hu.sztaki.ilab.longneck.process.block.SwitchStrict; import hu.sztaki.ilab.longneck.process.block.TryAll; /** * * @author Lukacs Gabor <lukacsg@sztaki.mta.hu> */ /** * Execution frame. * * Maintains information about the currently executed compound block. * * @author Lukacs Gabor <lukacsg@sztaki.mta.hu> * */ class ExecutionFrame { /** * The parent execution frame. */ private final ExecutionFrame parentFrame; /** * The parent compound block. */ private final CompoundBlock hostBlock; /** * The associated control object, if any. */ private final ControlStructure control; /** * The current variable space. */ private final VariableSpace variables; /** * Cached has control flag. */ private final boolean hasControl; /** * Cached is start handler flag. */ private final boolean startHandler; /** * Cached is end handler flag. */ private final boolean endHandler; /** * Cached is error handler flag. */ private final boolean errorHandler; /** * Cached is success handler flag. */ private final boolean successHandler; /** * Cached is break handler flag. */ private final boolean breakHandler; /** * Cached is record change handler */ private final boolean recordchangehandler; private final String context; /** * The current position in the parent compound block. */ private int position; public ExecutionFrame() { position = 0; parentFrame = null; hostBlock = null; control = getControl(null); variables = null; context = null; hasControl = false; startHandler = false; endHandler = false; errorHandler = false; successHandler = false; breakHandler = false; recordchangehandler = false; } public ExecutionFrame(CompoundBlock block, ExecutionFrame parentFrame) { position = 0; this.parentFrame = parentFrame; variables = new VariableSpace(parentFrame.variables); context = parentFrame.getContext(); hostBlock = block; control = getControl(block); hasControl = (this.control instanceof ControlStructure); startHandler = (this.hasControl && this.control instanceof StartHandler); endHandler = (this.hasControl && this.control instanceof EndHandler); errorHandler = (this.hasControl && this.control instanceof ErrorHandler); successHandler = (this.hasControl && this.control instanceof SuccessHandler); breakHandler = (this.hasControl && this.control instanceof BreakHandler); recordchangehandler = (this.hasControl && this.control instanceof RecordChangeHandler); } public ExecutionFrame(BlockReference blockRef, ExecutionFrame parentFrame) { position = 0; this.parentFrame = parentFrame; variables = new VariableSpace(parentFrame.variables); context = blockRef.getContext() != null?blockRef.getContext():parentFrame.getContext(); hostBlock = blockRef.getReferredBlock(); control = getControl(blockRef); ((BlockReferenceControl) control).setContext(context); hasControl = (this.control instanceof ControlStructure); startHandler = (this.hasControl && this.control instanceof StartHandler); endHandler = (this.hasControl && this.control instanceof EndHandler); errorHandler = (this.hasControl && this.control instanceof ErrorHandler); successHandler = (this.hasControl && this.control instanceof SuccessHandler); breakHandler = (this.hasControl && this.control instanceof BreakHandler); recordchangehandler = (this.hasControl && this.control instanceof RecordChangeHandler); } /** * Copy constructor. * * @param other The frame to copy. * @param parent The parent frame that has already been copied, since it's final. */ public ExecutionFrame(ExecutionFrame other, ExecutionFrame parent) { position = other.position; parentFrame = parent; if (parent != null) { variables = new VariableSpace(other.variables, parent.variables); } else { variables = null; } context = other.context; //hostBlock = (CompoundBlock) other.hostBlock.clone(); hostBlock = (CompoundBlock) other.hostBlock; control = other.control == null ? null : other.control.clone(); hasControl = other.hasControl; startHandler = other.startHandler; endHandler = other.endHandler; errorHandler = other.errorHandler; successHandler = other.successHandler; breakHandler = other.breakHandler; recordchangehandler = other.recordchangehandler; } public static ControlStructure getControl(Block block) { if (block instanceof If) { return new IfControl((If) block); } else if (block instanceof Switch) { return new SwitchControl(); } else if (block instanceof SwitchStrict) { return new SwitchStrictControl((SwitchStrict) block); } else if (block instanceof TryAll) { return new TryAllControl(); } else if (block instanceof BlockReference) { return new BlockReferenceControl((BlockReference) block); } else if (block instanceof Caching) { return new CachingControl((Caching) block); } return null; } /** * Increase position. */ void increasePosition() { ++position; } VariableSpace getVariables() { return variables; } ExecutionFrame getParentFrame() { return parentFrame; } CompoundBlock getHostBlock() { return hostBlock; } boolean isStartHandler() { return startHandler; } boolean isEndHandler() { return endHandler; } boolean isErrorHandler() { return errorHandler; } boolean isSuccessHandler() { return successHandler; } boolean isBreakHandler() { return breakHandler; } public boolean isRecordchangehandler() { return recordchangehandler; } public int getPosition() { return position; } public void setPosition(int position) { this.position = position; } public ControlStructure getControl() { return control; } public String getContext() { return context; } }