001/* 002 * Copyright (c) 2003-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: brooks $' 006 * '$Date: 2012-06-18 00:36:48 +0000 (Mon, 18 Jun 2012) $' 007 * '$Revision: 29975 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.sdm.spa.gui; 031 032import java.util.Set; 033 034import ptolemy.actor.gui.Effigy; 035import ptolemy.actor.gui.Tableau; 036import ptolemy.actor.gui.TableauFactory; 037import ptolemy.data.Token; 038import ptolemy.data.expr.ASTPtAssignmentNode; 039import ptolemy.data.expr.ASTPtRootNode; 040import ptolemy.data.expr.ModelScope; 041import ptolemy.data.expr.Parameter; 042import ptolemy.data.expr.ParseTreeEvaluator; 043import ptolemy.data.expr.ParserScope; 044import ptolemy.data.expr.PtParser; 045import ptolemy.data.expr.Variable; 046import ptolemy.gui.ShellInterpreter; 047import ptolemy.kernel.util.Attribute; 048import ptolemy.kernel.util.IllegalActionException; 049import ptolemy.kernel.util.NameDuplicationException; 050import ptolemy.kernel.util.NamedObj; 051 052////////////////////////////////////////////////////////////////////////// 053//// DoubleShellTAPTableau 054/** 055 * Based on the Ptolemy II v.3.0.2 code ExpressionShellTableau.java A tableau 056 * that provides an interactive shell for evaluating expressions. 057 * 058 * @author Ilkay Altintas 059 * @version $Id: DoubleShellTAPTableau.java 29975 2012-06-18 00:36:48Z brooks $ 060 */ 061public class DoubleShellTAPTableau extends Tableau implements ShellInterpreter { 062 063 /** 064 * Create a new tableau. The tableau is itself an entity contained by the 065 * effigy and having the specified name. The frame is not made visible 066 * automatically. You must call show() to make it visible. 067 * 068 * @param container 069 * The containing effigy. 070 * @param name 071 * The name of this tableau within the specified effigy. 072 * @exception IllegalActionException 073 * If the tableau is not acceptable to the specified 074 * container. 075 * @exception NameDuplicationException 076 * If the container already contains an entity with the 077 * specified name. 078 */ 079 public DoubleShellTAPTableau(DoubleShellTAPEffigy container, String name) 080 throws IllegalActionException, NameDuplicationException { 081 super(container, name); 082 frame = new DoubleShellTAPTableauFrame(this); 083 setFrame(frame); 084 frame.setTableau(this); 085 _evaluator = new ParseTreeEvaluator(); 086 } 087 088 // ///////////////////////////////////////////////////////////////// 089 // // public methods //// 090 091 /** 092 * Evaluate the specified command. 093 * 094 * @param command 095 * The command. 096 * @return The return value of the command, or null if there is none. 097 * @exception Exception 098 * If something goes wrong processing the command. 099 */ 100 public String evaluateCommand(String command) throws Exception { 101 if (command.trim().equals("")) { 102 return ""; 103 } 104 PtParser parser = new PtParser(); 105 ASTPtRootNode node = parser.generateSimpleAssignmentParseTree(command); 106 String targetName = null; 107 108 // Figure out if we got an assignment... if so, then get the 109 // identifier name and only evaluated the expression part. 110 if (node instanceof ASTPtAssignmentNode) { 111 ASTPtAssignmentNode assignmentNode = (ASTPtAssignmentNode) node; 112 targetName = assignmentNode.getIdentifier(); 113 node = assignmentNode.getExpressionTree(); 114 } 115 116 final NamedObj model = ((DoubleShellTAPEffigy) getContainer()) 117 .getModel(); 118 ParserScope scope = new ModelScope() { 119 public ptolemy.data.Token get(String name) 120 throws IllegalActionException { 121 Variable result = getScopedVariable(null, model, name); 122 if (result != null) { 123 return result.getToken(); 124 } else { 125 return null; 126 } 127 } 128 129 public ptolemy.data.type.Type getType(String name) 130 throws IllegalActionException { 131 Variable result = getScopedVariable(null, model, name); 132 if (result != null) { 133 return result.getType(); 134 } else { 135 return null; 136 } 137 } 138 139 public ptolemy.graph.InequalityTerm getTypeTerm(String name) 140 throws IllegalActionException { 141 Variable result = getScopedVariable(null, model, name); 142 if (result != null) { 143 return result.getTypeTerm(); 144 } else { 145 return null; 146 } 147 } 148 149 public Set identifierSet() { 150 return getAllScopedVariableNames(null, model); 151 } 152 }; 153 154 Token result = _evaluator.evaluateParseTree(node, scope); 155 156 // If a target was specified, instantiate a new token. 157 if (targetName != null) { 158 Attribute attribute = model.getAttribute(targetName); 159 if (attribute != null && !(attribute instanceof Parameter)) { 160 attribute.setContainer(null); 161 attribute = null; 162 } 163 if (attribute == null) { 164 attribute = new Parameter(model, targetName); 165 } 166 ((Parameter) attribute).setToken(result); 167 } 168 169 if (result == null) { 170 return ""; 171 } else { 172 return result.toString(); 173 } 174 } 175 176 /** 177 * Return true if the specified command is complete (ready to be 178 * interpreted). 179 * 180 * @param command 181 * The command. 182 * @return True. 183 */ 184 public boolean isCommandComplete(String command) { 185 return true; 186 } 187 188 // ///////////////////////////////////////////////////////////////// 189 // // public variables //// 190 191 /** The associated frame. */ 192 public DoubleShellTAPTableauFrame frame; 193 194 /** The contained shell. */ 195 public DoubleShellTextAreaPanel shellPanel; 196 197 // ///////////////////////////////////////////////////////////////// 198 // // private variables //// 199 200 // The parameter used for evaluation. 201 private ParseTreeEvaluator _evaluator; 202 203 // ///////////////////////////////////////////////////////////////// 204 // // inner classes //// 205 206 /** 207 * A factory that creates a control panel to display a Tcl Shell 208 */ 209 public static class Factory extends TableauFactory { 210 211 /** 212 * Create a factory with the given name and container. 213 * 214 * @param container 215 * The container. 216 * @param name 217 * The name. 218 * @exception IllegalActionException 219 * If the container is incompatible with this attribute. 220 * @exception NameDuplicationException 221 * If the name coincides with an attribute already in the 222 * container. 223 */ 224 public Factory(NamedObj container, String name) 225 throws IllegalActionException, NameDuplicationException { 226 super(container, name); 227 } 228 229 // ///////////////////////////////////////////////////////////////// 230 // // public methods //// 231 232 /** 233 * Create a new instance of ExpressionShellTableau in the specified 234 * effigy. It is the responsibility of callers of this method to check 235 * the return value and call show(). 236 * 237 * @param effigy 238 * The model effigy. 239 * @return A new control panel tableau if the effigy is a PtolemyEffigy, 240 * or null otherwise. 241 * @exception Exception 242 * If the factory should be able to create a tableau for 243 * the effigy, but something goes wrong. 244 */ 245 public Tableau createTableau(Effigy effigy) throws Exception { 246 // NOTE: Can create any number of tableaux within the same 247 // effigy. Is this what we want? 248 if (effigy instanceof DoubleShellTAPEffigy) { 249 return new DoubleShellTAPTableau((DoubleShellTAPEffigy) effigy, 250 "DoubleShellTAPTableau"); 251 } else { 252 return null; 253 } 254 } 255 } 256}