📄 msystem.java
字号:
* preconditions are satisfied, the current state is saved and the * operation is pushed on an internal call stack. */ public void enterOperation(MOperationCall opcall, PrintWriter out) { opcall.enter(fCurrentState); // check preconditions boolean preOk = true; MOperation op = opcall.operation(); List preconds = op.preConditions(); Iterator it = preconds.iterator(); while (it.hasNext() ) { MPrePostCondition ppc = (MPrePostCondition) it.next(); Expression expr = ppc.expression(); Evaluator evaluator = new Evaluator(); // evaluate in scope local to operation Value v = evaluator.eval(expr, fCurrentState, opcall.varBindings()); boolean ok = v.isDefined() && ((BooleanValue) v).isTrue(); out.println("precondition `" + ppc.name() + "' is " + ok); if (! ok ) preOk = false; } if (preOk ) { pushOperation(opcall); fCurrentState = new MSystemState(fUniqueNameGenerator.generate("state#"), fCurrentState); } out.flush(); } /** * Exits the least recently entered operation. If the operation * signature specifies a result type, a result value must be * given. This value is bound to the special OCL variable * result. Finally, all postconditions are checked with the system * state saved at operation entry time and the current system * state. */ public void exitOperation(Value optionalResult, PrintWriter out) throws MSystemException { MOperationCall opcall = activeOperation(); if (opcall == null ) throw new MSystemException("Call stack is empty."); MOperation op = opcall.operation(); // bind result value to result variable VarBindings vb = opcall.varBindings(); if (op.hasResultType() ) { if (optionalResult == null ) throw new MSystemException("Result value required on exit of " + "operation `" + op + "'."); if (! optionalResult.type().isSubtypeOf(op.resultType()) ) throw new MSystemException("Result value type `" + optionalResult.type() + "' does not match operation result type `" + op.resultType() + "'."); vb.push("result", optionalResult); } // check postconditions boolean postOk = true; List postconds = op.postConditions(); Iterator it = postconds.iterator(); while (it.hasNext() ) { MPrePostCondition ppc = (MPrePostCondition) it.next(); // System.out.println("*** checking postcondition `" + ppc.name() + "'"); // System.out.println("*** prestate: " + opcall.preState()); Expression expr = ppc.expression(); Evaluator evaluator = new Evaluator(); // evaluate in scope local to operation Value v = evaluator.eval(expr, opcall.preState(), fCurrentState, vb, null); boolean ok = v.isDefined() && ((BooleanValue) v).isTrue(); out.println("postcondition `" + ppc.name() + "' is " + ok); if (! ok ) { postOk = false; out.println("evaluation results:"); evaluator.eval(expr, opcall.preState(), fCurrentState, vb, out); } } opcall.exit(optionalResult, postOk); out.flush(); try { opcall = popOperation(); } catch (EmptyStackException ex) { throw new MSystemException("Call stack is empty."); } } /** * Notify all listeners that have registered interest for * notification on this event type. */ private void fireStateChanged(MCmd cmd, boolean cmdWasUndone) { // Guaranteed to return a non-null array Object[] listeners = fListenerList.getListenerList(); StateChangeEvent e = null; // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length-2; i >= 0; i -= 2) { if (listeners[i] == StateChangeListener.class ) { // Lazily create the event: if (e == null) { e = new StateChangeEvent(this); cmd.getChanges(e, cmdWasUndone); } ((StateChangeListener) listeners[i+1]).stateChanged(e); //System.out.println("Notifying: " + ((StateChangeListener) listeners[i+1]).getClass()); } } } /** * Returns the currently active operation or null if no operation * is active. */ public MOperationCall activeOperation() { MOperationCall res = null; int activeOperations = fOperationCallStack.size(); if (activeOperations > 0 ) res = (MOperationCall) fOperationCallStack.get(activeOperations - 1); return res; } /** * Returns the operation call stack. * * @return List(MOperationCall) */ public List callStack() { return fOperationCallStack; } /** * Returns the current top-level bindings. Changes to the * returned value do NOT affect the bindings of the system. */ public VarBindings topLevelBindings() { VarBindings vb = new VarBindings(fVarBindings); // add bindings from the currently active operation int activeOperations = fOperationCallStack.size(); if (activeOperations > 0 ) { MOperationCall opcall = (MOperationCall) fOperationCallStack.get(activeOperations - 1); vb.add(opcall.varBindings()); } return vb; } /** * Returns the top-level bindings of object names. Changes to the * returned value affect the bindings of the system. */ public VarBindings varBindings() { return fVarBindings; } /** * Adds a variable binding to the current scope. If we are inside * of an operation call, the variable is bound in the operation's * scope and will be unbound on operation exit. Top-level * variables are persistent. */ void addVarBindingToCurrentScope(String var, Value v) { int activeOperations = fOperationCallStack.size(); if (activeOperations == 0 ) { // add to top-level fVarBindings.push(var, v); } else { // add to current scope MOperationCall opcall = (MOperationCall) fOperationCallStack.get(activeOperations - 1); opcall.varBindings().push(var, v); } } /** * This is the inverse to addVarBindingToCurrentScope. It is only * here for purposes of undo functionality. */ void removeLastVarBindingFromCurrentScope() { int activeOperations = fOperationCallStack.size(); if (activeOperations == 0 ) { // remove from fVarBindings.pop(); } else { // remove from current scope MOperationCall opcall = (MOperationCall) fOperationCallStack.get(activeOperations - 1); opcall.varBindings().pop(); } } void setCurrentState(MSystemState state) { fCurrentState = state; } /** * Pushes an operation onto the call stack. */ void pushOperation(MOperationCall opcall) { fOperationCallStack.add(opcall); } /** * Pops the currently active operation from the call stack and * returns the operation call object. * * @throws EmptyStackException */ MOperationCall popOperation() { int stackSize = fOperationCallStack.size(); if (stackSize == 0 ) throw new EmptyStackException(); MOperationCall opcall = (MOperationCall) fOperationCallStack.get(stackSize - 1); fOperationCallStack.remove(stackSize - 1); return opcall; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -