Class JavaScript

  • All Implemented Interfaces:
    java.lang.Cloneable, Actor, Executable, FiringsRecordable, Placeable, Initializable, AccessorOrchestrator, TypedActor, Changeable, Debuggable, DebugListener, Derivable, Instantiable, ModelErrorHandler, MoMLExportable, Moveable, Nameable
    Direct Known Subclasses:
    JSAccessor

    public class JavaScript
    extends AbstractPlaceableActor
    implements AccessorOrchestrator
    An actor whose functionality is given in JavaScript using the accessor interface defined at https://accessors.org. Refer to that page for complete documentation of the functions and modules that are provided to the script.

    The script defines one or more functions that configure this actor with ports and parameters, initialize the actor, perform runtime functions such as reacting to inputs and producing outputs, and perform finalization (wrapup) functions. The script may be provided as the textual value of the script parameter, or as an input on the script port. You can add to the script or modify function definitions on each firing.

    To use this actor, specify a script. Define an exports.setup() function that declares inputs, outputs, and parameters.

    Your script can define zero or more of the following functions:

    • exports.setup. This function is invoked when the script parameter is first set and whenever the script parameter is updated. This function can be used to configure this actor with input and output ports and parameters. For example,
           exports.setup = function() {
               this.input('foo', {'type':'string'});
           }
         
      will create an input port named "foo" (if one does not already exist), and set its type to "string", possibly overriding any previously set data type. The methods that are particularly useful to use in setup are input, output, parameter, instantiate, and connect.
    • exports.initialize. This function is invoked each time this actor is initialized. This function should not read inputs or produce outputs.
    • exports.fire. This function is invoked each time this actor fires. It can read inputs using get() and write outputs using send(). This actor will consume at most one input token from each input port on each firing, if one is available. Any number of calls to get() during the firing will return the same consumed value, or will return null if there is no available input on that firing. If you want it to instead return a previously read input, then mark the port persistent by giving it a value option when you call input() in setup(). This provides a default value and makes any newly provided values persistent.
    • exports.wrapup. This function is invoked at the end of execution of of the model. It can read parameters, but normally should not read inputs nor write outputs.
    These functions are fields of the exports object, as usual JavaScript CommonJS modules. For example, to define the fire function, specify code like this:
          exports.fire = function () {... function body ...};
       
    Alternatively, you can do
          var fire = function() {... function body ...};
          exports.fire = fire;
       
    When these functions are invoked, 'this' will be bound to the accessor instance.

    Your script may also register input handler functions by invoking

          var handle = this.addInputHandler(portName, function);
       

    Normally you would do this in initialize(). The returned handle can be used to call this.removeInputHandler(). Handlers will be automatically unregistered upon wrapup(), so unless you want to cancel a handler earlier, you do not need to explicitly unregister a handler.

    The function specified as the input handler will be invoked whenever the port receives a new input. Note that the fire() function, if defined, will also be invoked (after the specified function) and will see the same input. If the specified function is null, then only the fire() function will be invoked. If the portName is null, then the handler will be invoked whenever a new input arrives on any input, after which the fire function will be invoked, if it exists.

    Often you can leave the types of input and output ports unspecified. Sometimes, however, you will need to explicitly set the types of the output ports. You can do this by specifying a 'type' option to the input() function in setup(). This implementation extends the accessor interface definition by allowing any Ptolemy II type to be specified. Keep in mind, however, that if you specify Ptolemy II types that are not also accessor types, then your script will likely not work in some other accessor host.

    You may also need to set the type of input ports. Usually, forward type inference will work, and the type of the input port will be based on the source of data. However, if the input comes from an output port whose output is undefined, such as JSONToToken, then you may want to enable backward type inference, and specify here the type of input that your script requires. Again, you do this with a 'type' option to the input() function in setup().

    The accessor instance (the value of 'this' inside setup(), initialize(), fire(), and wrapup()) has the following functions, at least:

    • addInputHandler(function, input): Specify a function to invoke when the input with name input (a string) receives a new input value. Note that after that function is invoked, the accessor's fire() function will also be invoked, if it is defined. If the specified function is null, then only the fire() function will be invoked. If the input argument is null or omitted, then the specified function will be invoked when any new input arrives to the accessor. This function returns a handle that can be used to call removeInputHandler().
    • get(portName): get an input from a port on channel 0.
    • getParameter(parameterName): get a value from a parameter.
    • removeInputHandler(handle): Remove the callback function with the specified handle (returned by addInputHandler()).
    • send(portName, value): send a value to an output port on channel 0
    • setParameter(parameterName, value): set the value of a parameter of this JavaScript actor.
    In addition, there are some top-level functions provided (which do not require a this prefix):
    • alert(string): pop up a dialog with the specified message.
    • clearInterval(int): clear an interval with the specified handle.
    • clearTimeout(int): clear a timeout with the specified handle.
    • currentTime(): return the current time as a number (in seconds).
    • error(string): send a message to error port, or throw an exception if the error port is not connected.
    • httpRequest(url, method, properties, body, timeout): HTTP request (GET, POST, PUT, etc.)
    • localHostAddress(): If not in restricted mode, return the local host IP address as a string.
    • print(string): print the specified string to the console (standard out).
    • readURL(string): read the specified URL and return its contents as a string (HTTP GET).
    • require(string): load and return a CommonJS module by name. See https://accessors.org for supported modules. See http://wiki.commonjs.org/wiki/Modules for what a CommonJS module is.
    • setInterval(function, long): set the function to execute after specified time and then periodically and return handle.
    • setTimeout(function, long): set the function to execute after specified time and return handle.

    Note that get() may be called within a JavaScript callback function. In that case, if the callback function is invoked during the firing of this actor, then the get() will return immediately. Otherwise, the get() method will request a firing of this actor at the current time and block the JavaScript thread until this actor is in that firing. This way, this actor ensures that get() reads a proper input. Note that although blocking JavaScript functions is not normally done, this actor has its own JavaScript engine, so no other JavaScript anywhere in the model will be affected. Those JavaScript threads are not blocked.

    The following example script calculates the factorial of the input.

       exports.setup = function() {
           this.input('input', {'type':'int'});
           this.output('output', {'type':'int'});
       }
       exports.fire = function() {
           var value = this.get('input');
           if (value < 0) {
               error("Input must be greater than or equal to 0.");
           } else {
               var total = 1;
               while (value > 1) {
                   total *= value;
                   value--;
               }
               this.send('output', total);
           }
       }
       

    Your script may also store values from one firing to the next, or from initialization to firing. For example,

       exports.setup = function() {
           this.output('output', {'type':'int'});
       }
       var init;
       exports.initialize() = function() {
           init = 0;
       }
       exports.fire = function() {
           init = init + 1;
           this.send('output', init);
       }
       

    will send a count of firings to the output named "output".

    In addition, the symbols "actor" and "accessor" are defined to be the instance of this actor. In JavaScript, you can invoke methods on it. (Note that in an accessor, which is implemented by a subclass of this JavaScript actor, invocation of these functions is blocked for security reasons.) For example, the JavaScript

       actor.toplevel().getName();
       

    will return the name of the top-level composite actor containing this actor.

    This actor can be used in any Ptolemy II model and can interact with native Ptolemy II actors through its ports. However, not all Ptolemy II data types translate naturally to JavaScript types. Simple types will "just work." This actor converts Ptolemy types int, double, string, and boolean to and from equivalent JavaScript types when sending and getting to and from ports. In addition, arrays at input ports are converted to native JavaScript arrays. When sending a JavaScript array to an output port, it will be converted into a Ptolemy II array, but keep in mind that Ptolemy II arrays have a single element type, namely a type that every element can be converted to. So, for example, sending the JavaScript array [1, 2, "foo"] to an output port will result in the Ptolemy II array {"1", "2", "foo"}, an array of strings. If you wish to send a JavaScript array (or any other JavaScript object) without modifying it, wrap it in an ObjectToken, as in this example:

       var ObjectToken = Java.type('ptolemy.data.ObjectToken');
       exports.fire = function() {
          var token = new ObjectToken([1, 2, 'foo']);
          this.send('output', token);
       }
       

    The type of the output port will need to be set to object or general. If you send this to another JavaScript actor, that actor can retrieve the original JavaScript object as follows:

       var ObjectToken = Java.type('ptolemy.data.ObjectToken');
       exports.fire = function() {
          var token = this.get('input');
          var array = token.getValue();
          ... operate on array, which is the original [1, 2, 'foo'] ...
       }
       

    Ptolemy II records are also converted into JavaScript objects, and JavaScript objects with enumerable properties into records. When converting a JavaScript object to a record, each enumerable property (own or inherited) is included as a field in the resulting record, with the value of the field is converted in the same manner. To send a JavaScript object without any conversion, wrap it in an ObjectToken as with the array example above.

    These automatic conversions do not cover all cases of interest. For example, if you provide inputs to this JavaScript actor that cannot be converted, the script will see the corresponding Token object. For example, if you send a number of type long to an input of a JavaScript actor, the script (inside a fire() function):

          var value = this.get('input');
          print(value.getClass().toString());
       

    will print on standard out the string

          "class ptolemy.data.LongToken"
       

    JavaScript does not have a long data type (as of this writing), so instead the get() call returns a JavaScript Object wrapping the Ptolemy II LongToken object. You can then invoke methods on that token, such as getClass(), as done above.

    When sending tokens using send(), you can explicitly prevent any conversions from occurring by creating a Ptolemy II token explicitly and sending that. For example, the JavaScript nested array [[1, 2], [3, 4]] will be automatically converted into a Ptolemy II array of arrays {{1,2}, {3,4}}. If instead you want to send a Ptolemy II integer matrix [1,2;3,4], you can do this:

       var IntMatrixToken = Java.type('ptolemy.data.IntMatrixToken');
       exports.fire = function() {
          var token = new IntMatrixToken([[1, 2], [3, 4]]);
          this.send('output', token);
       }
       

    Scripts can instantiate Java classes and invoke methods on them. For example, the following script will build a simple Ptolemy II model and execute it each time this JavaScript actor fires.

       var Ramp = Java.type('ptolemy.actor.lib.Ramp');
       var FileWriter = Java.type('ptolemy.actor.lib.FileWriter');
       var SDFDirector = Java.type('ptolemy.domains.sdf.kernel.SDFDirector');
       var TypedCompositeActor = Java.type('ptolemy.actor.TypedCompositeActor');
       var Manager = Java.type('ptolemy.actor.Manager');
    
       var toplevel = new TypedCompositeActor();
       var ramp = new Ramp(toplevel, "ramp");
       var writer = new FileWriter(toplevel, "writer");
    
       toplevel.connect(ramp.output, writer.input);
    
       var director = new SDFDirector(toplevel, "SDFDirector");
       director.getAttribute('iterations').setExpression("10");
       var manager = new Manager();
       toplevel.setManager(manager);
    
       exports.fire = function() {
          manager.execute();
       }
       

    You can even send this model out on an output port. For example,

       exports.fire = function() {
          this.send('output', toplevel);
       }
       
    where "output" is the name of the output port. Note that the manager does not get included with the model, so the recipient will need to associate a new manager to be able to execute the model. Note further that you may want to declare the type of the output to be 'actor', a Ptolemy II type.

    Subclasses of this actor may put it in "restricted" mode, which limits the functionality as follows:

    • The "actor" variable (referring to this instance of the actor) provides limited capabilities.
    • The localHostAddress() function throws an error.
    • The readURL and httpRequest function only support the HTTP protocol (in particular, they do not support the "file" protocol, and hence cannot access local files).

    For debugging, it can be useful to right click on this actor and select Listen to Actor. Refer to https://accessors.org for a complete definition of the available functionality. For example, it is explained there how to create composite accessors, which instantiate and connect multiple subaccessors within this one.

    Since:
    Ptolemy II 11.0
    Version:
    $Id$
    Author:
    Edward A. Lee
    Pt.AcceptedRating:
    Red (bilung)
    Pt.ProposedRating:
    Yellow (eal)
    • Field Detail

      • error

        public TypedIOPort error
        Output port on which to produce a message when an error occurs when executing this actor. Note that if nothing is connected to this port, then an error will cause this JavaScript actor to throw an exception. Otherwise, a description of the error will be produced on this port and the actor will continue executing. Note that any errors that occur during loading the script or invoking the initialize() or wrapup() functions always result in an exception, since it makes no sense to produce an output during those phases of execution.
      • script

        public PortParameter script
        The script defining the behavior of this actor.
      • _EMPTY_ARGS

        protected static final java.lang.Object[] _EMPTY_ARGS
        Empty argument list for JavaScript function invocation.
      • _engine

        protected javax.script.ScriptEngine _engine
        JavaScript engine, shared among all instances of this class.
      • _executing

        protected boolean _executing
        True while the model is executing (between initialize() and wrapup(), including the initialize() but not wrapup(). This is the phase of execution during which it is OK to send outputs.
      • _exports

        protected java.lang.Object _exports
        The exports object defined in the script that is evaluated.
      • _INITIAL_SCRIPT

        protected static final StringToken _INITIAL_SCRIPT
        Initial script as a token.
      • _instance

        protected java.lang.Object _instance
        The instance returned when evaluating the script.
      • _JAVASCRIPT_KEYWORDS

        protected static final java.lang.String[] _JAVASCRIPT_KEYWORDS
        JavaScript keywords.
      • _KEYWORDS

        protected static final java.util.Set<java.lang.String> _KEYWORDS
        Keywords as a Set.
      • _restricted

        protected boolean _restricted
        If set to true in the constructor of a base class, then put this actor in "restricted" mode. This limits the functionality as described in the class comment.
      • _running

        protected boolean _running
        True while the model is running (past initialize() and before wrapup()). This is the phase of execution during which it is OK to get inputs.
    • Constructor Detail

      • JavaScript

        public JavaScript​(CompositeEntity container,
                          java.lang.String name)
                   throws NameDuplicationException,
                          IllegalActionException
        Construct an actor with the given container and name. In addition to invoking the base class constructors, construct the error port and the script port parameter. Initialize script to a block of JavaScript.
        Parameters:
        container - The container.
        name - The name of this actor.
        Throws:
        IllegalActionException - If the actor cannot be contained by the proposed container.
        NameDuplicationException - If the container already has an actor with this name.
    • Method Detail

      • attributeChanged

        public void attributeChanged​(Attribute attribute)
                              throws IllegalActionException
        React to a change in an attribute, and if the attribute is the script parameter, and the script parameter possibly contains a 'setup' function, then evaluate that function. This means that as soon as this script parameter is set, any ports that are created in setup will appear. Note that the JavaScript engine that evaluates setup is discarded, and a new one is created when the model executes.
        Overrides:
        attributeChanged in class NamedObj
        Parameters:
        attribute - The attribute that changed.
        Throws:
        IllegalActionException - If evaluating the script fails.
      • author

        public void author​(java.lang.String author)
        Specify author information to appear in the documentation for this actor.
        Parameters:
        author - Author information to appear in documentation.
      • clone

        public java.lang.Object clone​(Workspace workspace)
                               throws java.lang.CloneNotSupportedException
        Clone the actor into the specified workspace.
        Overrides:
        clone in class AbstractPlaceableActor
        Parameters:
        workspace - The workspace for the new object.
        Returns:
        A new actor.
        Throws:
        java.lang.CloneNotSupportedException - If a derived class contains an attribute that cannot be cloned.
        See Also:
        Object.clone()
      • createEngine

        public static javax.script.ScriptEngine createEngine​(JavaScript actor,
                                                             boolean debugging,
                                                             boolean restricted)
                                                      throws IllegalActionException
        Create a script engine and initialize it.
        Parameters:
        actor - The JavaScript actor that is to use the script engine. If the actor parameter is null, then the restricted parameter must be false. The actor parameter is also used for exception handling. The JavaScriptApplication class typically passes a null value for this parameter.
        debugging - True if the _debug JavaScript variable should be set to true.
        restricted - True if script engine should be restricted so that it can execute unrusted code. The default is typically false.
        Returns:
        The JavaScript engine.
        Throws:
        IllegalActionException - If the "nashorn" JavaScript engine cannot be found. The Nashorn engine is only present in JDK 1.8 and later.
      • currentTime

        public double currentTime()
        Return the current time as a number (in seconds).
        Returns:
        The current time.
      • declareIndependence

        public void declareIndependence​(java.lang.String outputName,
                                        java.lang.String inputName)
        Declare that the specified output does not depend on the specified input.
        Parameters:
        outputName - The name of the output.
        inputName - The name of hte input.
      • description

        public void description​(java.lang.String description)
        Specify a description to appear in the documentation for this actor. The assume format for documentation is HTML.
        Parameters:
        description - A description to appear in documentation.
      • description

        public void description​(java.lang.String description,
                                java.lang.String type)
        Specify a description to appear in the documentation for this actor. The recommended format for documentation is HTML, Markdown, or plain text.
        Parameters:
        description - A description to appear in documentation.
        type - The type, which should be one of "text/html" (the default if null is given), "text/markdown", or "text/plain".
      • error

        public void error​(java.lang.String message)
        If the model is executing and the error port is connected, then send the message to the error port; otherwise, use the MessageHandler to display the error. Note that this should not be used for fatal errors, because it returns. For fatal errors, a script should throw an exception. In addition, if debugging is turned on, then send the specified message to the _debug() method, and otherwise send it out to stderr.
        Specified by:
        error in interface AccessorOrchestrator
        Parameters:
        message - The message
      • error

        public void error​(java.lang.String message,
                          java.lang.Throwable throwable)
        If the model is executing and the error port is connected, then send the message to the error port; otherwise, use the MessageHandler to display the error. Note that this should not be used for fatal errors, because it returns. For fatal errors, a script should throw an exception. In addition, if debugging is turned on, then send the specified message to the _debug() method, and otherwise send it out to stderr.
        Parameters:
        message - The message
        throwable - The throwable
      • escapeForJavaScript

        public java.lang.String escapeForJavaScript​(java.lang.String unescapedString)
                                             throws IllegalActionException
        Escape a string for use within JavaScript.
        Parameters:
        unescapedString - The unescaped string to be escaped for use in JavaScript.
        Returns:
        The encodedString
        Throws:
        IllegalActionException - If the string cannot be escaped.
      • fire

        public void fire()
                  throws IllegalActionException
        Produce any pending outputs specified by send() since the last firing, invoke any timer tasks that match the current time, and invoke the fire function. Specifically:
        1. First, if there is a new token on the script input port, then evaluate the script specified on that port. Any previously defined methods such as fire() will be replaced if the new script has a replacement, and preserved otherwise. If the new script has an initialize() method, that method will not be invoked until the next time this actor is initialized.
        2. Next, send any outputs that have been queued to be sent by calling send() from outside any firing of this JavaScript actor.
        3. Next, read all available inputs, recording their values for subsequent calls to get().
        4. Next, invoke any pending timer tasks whose timing matches the current time.
        5. After updating all the inputs, for each input port that had a new token on any channel and for which there is a handler function bound to that port via the addInputHandler() method, invoke that function. Such a function will be invoked in the order that the inputs are defined in the accessor.
        6. Next, if the current script has a fire() function, then invoke it.
        Specified by:
        fire in interface Executable
        Overrides:
        fire in class AtomicActor<TypedIOPort>
        Throws:
        IllegalActionException - If calling send() or super.fire() throws it.
      • getFileFromClasspathAsString

        public static java.lang.String getFileFromClasspathAsString​(java.lang.String path)
                                                             throws java.io.IOException
        Return the string contents of the file from the classpath.
        Parameters:
        path - The location. This is used in localFunctions.js. The path should be a relative path.
        Returns:
        The contents as a string, assuming the default encoding of this JVM (probably utf-8).
        Throws:
        java.io.IOException - If the file cannot be read.
      • getEngine

        public javax.script.ScriptEngine getEngine()
        If this actor has been initialized, return the JavaScript engine, otherwise return null.
        Returns:
        The JavaScript engine for this actor.
      • getPortOrParameterProxy

        public JavaScript.PortOrParameterProxy getPortOrParameterProxy​(java.lang.String name)
        Get the proxy for a port or parameter with the specified name. This is an object on which JavaScript can directly invoke methods.
        Parameters:
        name - The name of the port or parameter.
        Returns:
        The proxy for the specified name, or null if there is none.
      • getResource

        public java.lang.Object getResource​(java.lang.String uri,
                                            java.lang.Object... arguments)
                                     throws IllegalActionException
        Get a resource, which may be a file name or a URL, and return the value of the resource as a string. If this instance of JavaScript is restricted (e.g., it is an accessor), then restrict relative file names to be in the same directory where the model is located or in a subdirectory, or if the resource begins with "$CLASSPATH/", to the classpath of the current Java process. If the accessor is not restricted, the $KEYSTORE is resolved to $HOME/.ptKeystore. The options parameter may have the following values:
        • If the type of the options parameter is a Number, then it is assumed to be the timeout in milliseconds.
        • If the type of the options parameter is a String, then it is assumed to be the encoding, for examle "UTF-8". If the value is "Raw" or "raw" then the data is returned as an unsigned array of bytes. For backward compatibility, if the encoding is not set, it is assumed to be the default encoding of the platform, see Charset
        • If the type of the options parameter is an Object, then it may have the following optional fields:
          • encoding {string} The encoding of the file, see above for values.
          • returnURI {string} If true, then return the URI of the resource instead of the contents. The default is false.
          • timeout {number} The timeout in milliseconds.
        If the callback parameter is not present, then getResource() will be synchronous read like Node.js's fs.readFileSync() If the callback argument is present, then getResource() will be asynchronous like fs.readFile().
        Parameters:
        uri - A specification for the resource.
        arguments - A variable number of arguments, where the first optional argument is an Object that can be a String (the encoding), an integer (the timeout) or a JSON object with encoding and timeout fields, See above. The second optional argument is a callback, the first argument to the callback is the error, if any, the second element is the data, if any.
        Returns:
        The contents of the resource.
        Throws:
        IllegalActionException - If the uri specifies any protocol other than "http" or "https", or if the uri contains any "../", or if the uri begins with "/".
      • getTopLevelAccessors

        public java.lang.Object[] getTopLevelAccessors()
                                                throws java.lang.Exception
        Provide access to the top-level accessors in this model.
        Returns:
        An array of instances of the JavaScript Accessor class.
        Throws:
        java.lang.Exception
      • input

        public Token input​(java.lang.String name,
                           java.util.Map<java.lang.String,​java.lang.Object> options)
                    throws IllegalActionException,
                           NameDuplicationException
        Create a new input port if it does not already exist. The options argument can specify a "type", a "description", and/or a "value". If a type is given, and neither the port nor its corresponding parameter contain a TypeAttribute, then set the type as specified. Otherwise, leave the type unspecified so that it will be inferred. If a description is given, then create, append to, or modify the DocAttribute named "documentation" contained by this actor to include documentation of this output. If a value is given, then create a PortParameter instead of an ordinary port and set its default value, unless it already has a value that overrides the default. In that case, the prior value will be returned. Otherwise, null will be returned. If a Parameter already exists with the same name, then convert it to a PortParameter and preserve and return its value. The options can also include a field "visibility" with one of the values "none", "expert", "noteditable" or "full" (the default). This is a hint to restrict visibility that a user has of the port.
        Parameters:
        name - The name of the port.
        options - The options, or null to accept the defaults. To give options, this argument must implement the Map interface.
        Returns:
        The previous value of this input, if it has one, and null otherwise.
        Throws:
        IllegalActionException - If no name is given.
        NameDuplicationException - If the name is a reserved word.
      • invokeCallback

        public void invokeCallback​(java.lang.Runnable function)
                            throws IllegalActionException
        Invoke the specified function in the fire() method as soon as possible. If this is called within the director thread and we are currently inside the fire() function, then invoke the function immediately. Otherwise, defer it using the director's fireAtCurrentTime() function.
        Specified by:
        invokeCallback in interface AccessorOrchestrator
        Parameters:
        function - The function to invoke.
        Throws:
        IllegalActionException - If the director cannot respect the request.
      • isExecuting

        public boolean isExecuting()
        Return true if the model is executing (between initialize() and wrapup(), including initialize() but not wrapup()). This is (more or less) the phase of execution during which it is OK to send outputs. Note that if an asynchronous callback calls send() when this returns true, the output may still not actually reach its destination. It is possible that the last firing has already occurred, but wrapup() has not yet been called.
        Returns:
        true if the model is executing.
      • isJavaScriptKeyword

        public static boolean isJavaScriptKeyword​(java.lang.String identifier)
        Return true if the specified string is a JavaScript keyword.
        Parameters:
        identifier - The identifier name.
        Returns:
        True if it is a JavaScript keyword.
      • isRestricted

        public boolean isRestricted()
        Return true if this actor is restricted. A restricted instance of this actor limits the capabilities available to the script it executes so that it can execute untrusted code. This base class is not restricted, but subclasses may be.
        Returns:
        True if this actor is restricted.
      • isValidIdentifier

        public static boolean isValidIdentifier​(java.lang.String identifier)
        Return true if the specified string is not a JavaScript keyword and is a valid JavaScript identifier.
        Parameters:
        identifier - The proposed name.
        Returns:
        True if it is a valid identifier name.
      • localHostAddress

        public java.lang.String localHostAddress()
                                          throws java.net.UnknownHostException,
                                                 java.lang.SecurityException
        Return the local host IP address as a string.
        Returns:
        A string representation of the local host address.
        Throws:
        java.net.UnknownHostException - If the local host is not known.
        java.lang.SecurityException - If this actor is in restricted mode.
      • log

        public void log​(java.lang.String message)
        If debugging is turned on, then send the specified message to the _debug() method, and otherwise send it out to stdout.
        Specified by:
        log in interface AccessorOrchestrator
        Parameters:
        message - The message
      • output

        public void output​(java.lang.String name,
                           java.util.Map<java.lang.String,​java.lang.Object> options)
                    throws IllegalActionException,
                           NameDuplicationException
        Create a new output port if it does not already exist. The options argument can specify a "type" and/or a "description". If a type is given and the port does not contain a TypeAttribute, then set the type as specified. Otherwise, set the type to general. If a description is given, then create, append to, or modify the DocAttribute named "documentation" contained by this actor to include documentation of this output.
        Parameters:
        name - The name of the port.
        options - The options, or null to accept the defaults. To give options, this argument must implement the Map interface.
        Throws:
        IllegalActionException - If no name is given.
        NameDuplicationException - If the name is a reserved word.
      • parameter

        public Token parameter​(java.lang.String name)
                        throws IllegalActionException,
                               NameDuplicationException
        Create a new parameter if it does not already exist. This parameter will have an undeclared type and no description.
        Parameters:
        name - The name of the parameter.
        Returns:
        The previous value of this parameter, if it has one, and null otherwise.
        Throws:
        IllegalActionException - If no name is given, or if the model is executing.
        NameDuplicationException - If the name is a reserved word, or if an attribute already exists with the name and is not a parameter.
      • parameter

        public Token parameter​(java.lang.String name,
                               java.util.Map<java.lang.String,​java.lang.Object> options)
                        throws IllegalActionException,
                               NameDuplicationException
        Create a new parameter if it does not already exist. The options argument can specify a "type", a "description", "visibility", and/or a "value". If a type is given, set the type as specified. Otherwise, leave the type unspecified so that it will be inferred from the value. If a description is given, then create, append to, or modify the DocAttribute named "documentation" contained by this actor to include documentation of this output. If a value is given, then set the default value of the parameter if it does not already have a value.
        Parameters:
        name - The name of the parameter.
        options - The options, or null to accept the defaults.
        Returns:
        The previous value of this parameter, if it has one, and null otherwise.
        Throws:
        IllegalActionException - If no name is given.
        NameDuplicationException - If the name is a reserved word, or if an attribute already exists with the name and is not a parameter.
      • place

        public void place​(java.awt.Container container)
        Place the interface for this actor in the specified container. This method does nothing because we expect any JavaScript actor that has a GUI to create that GUI in its own frame. This actor does not support placement of that GUI in a run control panel, for example.
        Specified by:
        place in interface Placeable
        Specified by:
        place in class AbstractPlaceableActor
        Parameters:
        container - The container.
      • readFromInputStream

        @Deprecated
        public static java.lang.String readFromInputStream​(java.io.InputStream stream)
                                                    throws java.io.IOException
        Deprecated.
        Invoke FileUtilities.readFromInputStream() directly.
        Utility method to read a string from an input stream.
        Parameters:
        stream - The stream.
        Returns:
        The string.
        Throws:
        java.io.IOException - If the stream cannot be read.
      • setInterval

        public java.lang.Object setInterval​(java.lang.Runnable function,
                                            long milliseconds)
                                     throws IllegalActionException
        Invoke the specified function after the specified amount of time and again at multiples of that time. The time will be added to the current time of the director, and fireAt() request will be made of the director. If the director cannot fulfill the request, this method will throw an exception. Note that if you want real-time behavior, then the director's synchronizeToRealTime parameter needs to be set to true.
        Specified by:
        setInterval in interface AccessorOrchestrator
        Parameters:
        function - The function to invoke.
        milliseconds - The number of milliseconds in the future to invoke it.
        Returns:
        A unique ID for this callback.
        Throws:
        IllegalActionException - If the director cannot respect the request.
        See Also:
        clearTimeout(Object)
      • setTimeout

        public java.lang.Object setTimeout​(java.lang.Runnable function,
                                           long milliseconds)
                                    throws IllegalActionException
        Invoke the specified function after the specified amount of time. The time will be added to the current time of the director, and fireAt() request will be made of the director. If the director cannot fulfill the request, this method will throw an exception. Note that if you want real-time behavior, then the director's synchronizeToRealTime parameter needs to be set to true.
        Specified by:
        setTimeout in interface AccessorOrchestrator
        Parameters:
        function - The function to invoke.
        milliseconds - The number of milliseconds in the future to invoke it.
        Returns:
        A unique ID for this callback.
        Throws:
        IllegalActionException - If the director cannot respect the request.
        See Also:
        clearTimeout(Object)
      • stopEnclosingModel

        public void stopEnclosingModel()
        Stop execution of the enclosing model.
      • toJSArray

        public java.lang.Object toJSArray​(java.lang.Object[] array)
                                   throws IllegalActionException
        Convert the specified array into a native JavaScript array.
        Parameters:
        array - The array to convert.
        Returns:
        The native JavaScript array.
        Throws:
        IllegalActionException - If the conversion fails.
      • version

        public void version​(java.lang.String version)
        Specify version information to appear in the documentation for this actor.
        Parameters:
        version - Version information to appear in documentation.
      • _accessorClass

        protected java.lang.String _accessorClass()
        Return the name of the accessor class. In this base class, it returns "JavaScript".
        Returns:
        The string "JavaScript".
      • _checkValidity

        protected void _checkValidity​(java.lang.String name)
                               throws IllegalActionException
        Check the validity of a name. This implementation throws an exception if either the name is not a valid JavaScript identifier or it is a JavaScript keyword.
        Parameters:
        name - The name to check.
        Throws:
        IllegalActionException - If the name is either not a valid identifier or is a keyword.
      • _defaultTypeConstraints

        protected java.util.Set<Inequality> _defaultTypeConstraints()
        Return null, because the default type constraints, where output types are greater than or equal to all input types, make no sense for this actor. Output types need to be set explicitly or inferred from backward type inference, and input types need to be set explicitly or inferred from forward type inference.
        Overrides:
        _defaultTypeConstraints in class TypedAtomicActor
        Returns:
        Null.
      • _invokeMethodInContext

        protected java.lang.Object _invokeMethodInContext​(java.lang.Object context,
                                                          java.lang.String methodName,
                                                          java.lang.Object... args)
                                                   throws IllegalActionException
        Invoke the specified method in the context of the exports object. If there is no such method in that context, attempt to invoke the method in the top-level context. The exports object becomes the value of the 'this' variable during execution of the method.
        Parameters:
        context - The context.
        methodName - The method name.
        args - Arguments to pass to the function.
        Returns:
        Whatever the function returns.
        Throws:
        IllegalActionException - If the method does not exist in either context, or if an error occurs invoking the method.
      • _setPortDescription

        protected void _setPortDescription​(NamedObj portOrParameter,
                                           java.lang.String description)
        Set the description of a port or parameter.
        Parameters:
        portOrParameter - The port.
        description - The description.