001/* Parameter is a subclass of Variable with support for strings. 002 003 Copyright (c) 1998-2015 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 027 028 */ 029package ptolemy.data.expr; 030 031import java.io.IOException; 032import java.io.Writer; 033import java.util.ArrayList; 034import java.util.List; 035 036import ptolemy.data.StringToken; 037import ptolemy.kernel.util.IllegalActionException; 038import ptolemy.kernel.util.NameDuplicationException; 039import ptolemy.kernel.util.NamedObj; 040import ptolemy.kernel.util.Settable; 041import ptolemy.kernel.util.Workspace; 042import ptolemy.util.StringUtilities; 043 044/////////////////////////////////////////////////////////////////// 045//// Parameter 046 047/** 048 <p>Parameter extends Variable with additional support for string-valued 049 variables that makes these friendlier at the user interface level. 050 In particular, this class supports an annotation that specifies 051 choices for values. A user interface can use this to present a 052 choice dialog that offers the specified values. This is typically 053 used when a particular set of choices make sense. The values can 054 be any expression, or if used in conjunction with string mode, 055 any string.</p> 056 <p> 057 By default, an instance of Parameter, unlike Variable, is persistent.</p> 058 <p> 059 By convention, an instance of NamedObj has a set of attributes, 060 some of which are visible to users and some of which are not. 061 When a user interface presents these attributes 062 for editing, it presents only those that are visible. 063 By default, an instance of Parameter is visible, as indicated by the fact 064 that it returns FULL in its getVisibility() method. This can be overridden 065 by calling setVisibility().</p> 066 067 @author Neil Smyth, Edward A. Lee, Xiaojun Liu 068 @version $Id$ 069 @since Ptolemy II 0.2 070 @Pt.ProposedRating Yellow (eal) 071 @Pt.AcceptedRating Red (cxh) 072 073 @see ptolemy.data.expr.PtParser 074 @see ptolemy.data.Token 075 076 */ 077public class Parameter extends Variable { 078 /** Construct a parameter in the default workspace with an empty 079 * string as its name. The parameter is added to the list of 080 * objects in the workspace. 081 * Increment the version number of the workspace. 082 */ 083 public Parameter() { 084 super(); 085 setVisibility(Settable.FULL); 086 087 // Override the base class setting persistence to false, 088 // making it once again unspecified. 089 _isPersistent = null; 090 } 091 092 /** Construct a parameter in the specified workspace with an empty 093 * string as a name. You can then change the name with setName(). 094 * If the workspace argument is null, then use the default workspace. 095 * The object is added to the list of objects in the workspace. 096 * Increment the version number of the workspace. 097 * @param workspace The workspace that will list the parameter. 098 */ 099 public Parameter(Workspace workspace) { 100 super(workspace); 101 setVisibility(Settable.FULL); 102 103 // Override the base class setting persistence to false, 104 // making it once again unspecified. 105 _isPersistent = null; 106 } 107 108 /** Construct a parameter with the given name contained by the specified 109 * entity. The container argument must not be null, or a 110 * NullPointerException will be thrown. This parameter will use the 111 * workspace of the container for synchronization and version counts. 112 * If the name argument is null, then the name is set to the empty string. 113 * The object is not added to the list of objects in the workspace 114 * unless the container is null. 115 * Increment the version of the workspace. 116 * @param container The container. 117 * @param name The name of the parameter. 118 * @exception IllegalActionException If the parameter is not of an 119 * acceptable class for the container. 120 * @exception NameDuplicationException If the name coincides with 121 * a parameter already in the container. 122 */ 123 public Parameter(NamedObj container, String name) 124 throws IllegalActionException, NameDuplicationException { 125 super(container, name); 126 setVisibility(Settable.FULL); 127 128 // Override the base class setting persistence to false, 129 // making it once again unspecified. 130 _isPersistent = null; 131 } 132 133 /** Construct a Parameter with the given container, name, and Token. 134 * The container argument must not be null, or a 135 * NullPointerException will be thrown. This parameter will use the 136 * workspace of the container for synchronization and version counts. 137 * If the name argument is null, then the name is set to the empty string. 138 * The object is not added to the list of objects in the workspace 139 * unless the container is null. 140 * Increment the version of the workspace. 141 * If the name argument is null, then the name is set to the empty 142 * string. 143 * @param container The container. 144 * @param name The name. 145 * @param token The Token contained by this Parameter. 146 * @exception IllegalActionException If the parameter is not of an 147 * acceptable class for the container. 148 * @exception NameDuplicationException If the name coincides with 149 * an parameter already in the container. 150 */ 151 public Parameter(NamedObj container, String name, ptolemy.data.Token token) 152 throws IllegalActionException, NameDuplicationException { 153 super(container, name, token); 154 setVisibility(Settable.FULL); 155 156 // Override the base class setting persistence to false, 157 // making it once again unspecified. 158 _isPersistent = null; 159 } 160 161 /////////////////////////////////////////////////////////////////// 162 //// public methods //// 163 164 /** Add a choice. 165 * @param choice A choice to offer to the user. 166 * @see #removeChoice(String) 167 */ 168 public void addChoice(String choice) { 169 if (_choices == null) { 170 _choices = new ArrayList(); 171 } 172 if (!_choices.contains(choice)) { 173 _choices.add(choice); 174 } 175 } 176 177 /** Clone the object into the specified workspace. 178 * @param workspace The workspace for the new object. 179 * @return A new NamedObj. 180 * @exception CloneNotSupportedException If any of the attributes 181 * cannot be cloned. 182 */ 183 @Override 184 public Object clone(Workspace workspace) throws CloneNotSupportedException { 185 Parameter newObject = (Parameter) super.clone(workspace); 186 if (_choices != null) { 187 newObject._choices = new ArrayList(_choices); 188 } 189 190 return newObject; 191 } 192 193 /** Write a MoML description of this object, unless this object is 194 * not persistent. MoML is an XML modeling markup language. 195 * In this class, the object is identified by the "property" 196 * element, with "name" and "class" (XML) attributes. 197 * The body of the element, between the "<property>" 198 * and "</property>", is written using 199 * the _exportMoMLContents() protected method, so that derived classes 200 * can override that method alone to alter only how the contents 201 * of this object are described. 202 * The text that is written is indented according to the specified 203 * depth, with each line (including the last one) 204 * terminated with a newline. 205 * @param output The output stream to write to. 206 * @param depth The depth in the hierarchy, to determine indenting. 207 * @param name The name to use instead of the current name. 208 * @exception IOException If an I/O error occurs. 209 * @see #isPersistent() 210 */ 211 @Override 212 public void exportMoML(Writer output, int depth, String name) 213 throws IOException { 214 if (_isMoMLSuppressed(depth)) { 215 return; 216 } 217 218 // NOTE: This used to read as follows, but this is problematic 219 // because you may actually want a parameter value to be an 220 // empty string (e.g., in InteractiveShell for the prompt). 221 // Unfortunately, we can't use getExpression(), because it 222 // substitutes null with an empty string, which isn't what 223 // we want. So we have to duplicate the code of getExpression(). 224 // EAL 8/8/06. 225 // String value = getExpression(); 226 // if ((value != null) && !value.equals("")) { 227 String value = _getCurrentExpression(); 228 if (value == null) { 229 ptolemy.data.Token token = null; 230 try { 231 token = getToken(); 232 } catch (IllegalActionException ex) { 233 // token will remain null if the value is invalid. 234 } 235 if (token != null) { 236 if (isStringMode()) { 237 value = ((StringToken) token).stringValue(); 238 } else { 239 value = token.toString(); 240 } 241 } 242 } 243 244 String valueTerm = ""; 245 if (value != null) { 246 valueTerm = " value=\"" + StringUtilities.escapeForXML(value) 247 + "\""; 248 } 249 250 // escape any < character in name. unescapeForXML occurs in 251 // NamedObj.setName(String) 252 name = StringUtilities.escapeForXML(name); 253 254 output.write(_getIndentPrefix(depth) + "<" + _elementName + " name=\"" 255 + name + "\" class=\"" + getClassName() + "\"" + valueTerm 256 + ">\n"); 257 _exportMoMLContents(output, depth + 1); 258 output.write(_getIndentPrefix(depth) + "</" + _elementName + ">\n"); 259 } 260 261 /** Get choices. 262 * @return An array of choices, or null if there are none. 263 * @see #addChoice(String) 264 */ 265 public String[] getChoices() { 266 if (_choices == null || _choices.size() == 0) { 267 return null; 268 } else { 269 return (String[]) _choices.toArray(new String[_choices.size()]); 270 } 271 } 272 273 /** Remove all the choices. 274 * @see #removeChoice(String) 275 */ 276 public void removeAllChoices() { 277 _choices = null; 278 } 279 280 /** Remove a choice. 281 * @param choice A choice to remove from the list offered to the user. 282 * @see #addChoice(String) 283 * @see #removeAllChoices() 284 */ 285 public void removeChoice(String choice) { 286 if (_choices != null) { 287 _choices.remove(choice); 288 } 289 } 290 291 /////////////////////////////////////////////////////////////////// 292 //// private variables //// 293 // The List of choices. 294 private List _choices; 295}