001/* Manages undo/redo actions on a MoML model. 002 003 Copyright (c) 2000-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 */ 027package ptolemy.moml; 028 029import ptolemy.kernel.undo.UndoAction; 030import ptolemy.kernel.util.ChangeListener; 031import ptolemy.kernel.util.ChangeRequest; 032import ptolemy.kernel.util.NamedObj; 033 034/////////////////////////////////////////////////////////////////// 035//// MoMLUndoEntry 036 037/** 038 This is an undo action on the undo/redo stack. The undo/redo stack 039 is stored in an instance of UndoInfoAttribute associated with the top-level 040 of a model. If undo/redo is enabled, a MoMLParser will create entries 041 automatically and put them on the stack whenever it parses MoML. So the 042 easiest mechanism to perform undoable actions is to specify those actions 043 in MoML and issue a MoMLChangeRequest to execute them. An alternative, 044 however, is to create an instance of this class with no MoML, using 045 the single argument constructor, and to override execute() to directly 046 perform the undo. 047 048 @see MoMLParser 049 @see ptolemy.kernel.undo.UndoStackAttribute 050 @see MoMLChangeRequest 051 @author Neil Smyth and Edward A. Lee 052 @version $Id$ 053 @since Ptolemy II 2.1 054 @Pt.ProposedRating Yellow (eal) 055 @Pt.AcceptedRating Red (cxh) 056 */ 057public class MoMLUndoEntry implements UndoAction, ChangeListener { 058 /** Create an undo entry comprised of the specified MoML code. 059 * @param context The context in which to execute the undo. 060 * @param undoMoML The MoML specification of the undo action. 061 */ 062 public MoMLUndoEntry(NamedObj context, String undoMoML) { 063 _context = context; 064 _undoMoML = undoMoML; 065 } 066 067 /////////////////////////////////////////////////////////////////// 068 //// public methods //// 069 070 /** Do nothing. This method is called when a change is successfully 071 * executed. 072 * @param change The change that was successfully executed. 073 */ 074 @Override 075 public void changeExecuted(ChangeRequest change) { 076 // In case this has been set before... 077 _exception = null; 078 } 079 080 /** Record the exception so that execute() can throw it. 081 * @param change The change that failed. 082 * @param exception The exception that occurred. 083 * @see #execute() 084 */ 085 @Override 086 public void changeFailed(ChangeRequest change, Exception exception) { 087 _exception = exception; 088 } 089 090 /** Parse the MoML specified in the constructor call in the context 091 * specified in the constructor call using the parser associated 092 * with the context (as determined by ParserAttribute.getParser()). 093 * @see ParserAttribute#getParser(NamedObj) 094 */ 095 @Override 096 public void execute() throws Exception { 097 // If the MoML is empty, the parser will throw an exception. 098 if (_undoMoML == null || _undoMoML.trim().equals("")) { 099 // Nothing to do. 100 return; 101 } 102 // Use a MoMLChangeRequest so that changes get propagated 103 // as appropriate to models that defer to this. 104 MoMLChangeRequest request = new MoMLChangeRequest(this, _context, 105 _undoMoML); 106 107 // An undo entry is always undoable so that redo works. 108 request.addChangeListener(this); 109 request.setUndoable(true); 110 request.execute(); 111 112 // The above call will result in a call to changeFailed() 113 // if the execution fails. 114 if (_exception != null) { 115 throw _exception; 116 } 117 } 118 119 /** Return the MoML of the undo action. 120 * @return MoML for the undo action. 121 */ 122 @Override 123 public String toString() { 124 return _undoMoML + "\n...in context: " + _context.getFullName(); 125 } 126 127 /////////////////////////////////////////////////////////////////// 128 //// private variables //// 129 // The context in which to execute the undo. 130 private NamedObj _context; 131 132 // Exception that occurs during a change. 133 private Exception _exception = null; 134 135 // The MoML specification of the undo. 136 private String _undoMoML; 137}