Class JavaScript
- java.lang.Object
-
- 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.
exports.fire = function () {... function body ...};
Alternatively, you can dovar 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.
- 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)
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description class
JavaScript.AccessorProxy
Proxy for an accessor for monitoring purposes.class
JavaScript.DeferredSend
Runnable object intended to be run inside of the fire method to send out a token that was attempted to be send out at an earlier time, asynchronous with fire.class
JavaScript.PortOrParameterProxy
Proxy for a port or parameter.-
Nested classes/interfaces inherited from class ptolemy.kernel.Entity
Entity.ContainedObjectsIterator
-
-
Field Summary
Fields Modifier and Type Field Description protected static java.lang.Object[]
_EMPTY_ARGS
Empty argument list for JavaScript function invocation.protected javax.script.ScriptEngine
_engine
JavaScript engine, shared among all instances of this class.protected boolean
_executing
True while the model is executing (between initialize() and wrapup(), including the initialize() but not wrapup().protected java.lang.Object
_exports
The exports object defined in the script that is evaluated.protected static StringToken
_INITIAL_SCRIPT
Initial script as a token.protected java.lang.Object
_instance
The instance returned when evaluating the script.protected static java.lang.String[]
_JAVASCRIPT_KEYWORDS
JavaScript keywords.protected static java.util.Set<java.lang.String>
_KEYWORDS
Keywords as a Set.protected boolean
_restricted
If set to true in the constructor of a base class, then put this actor in "restricted" mode.protected boolean
_running
True while the model is running (past initialize() and before wrapup()).TypedIOPort
error
Output port on which to produce a message when an error occurs when executing this actor.PortParameter
script
The script defining the behavior of this actor.-
Fields inherited from class ptolemy.actor.gui.AbstractPlaceableActor
_frame, _paneSize, _windowClosingAdapter, _windowProperties
-
Fields inherited from class ptolemy.actor.TypedAtomicActor
_typesValid
-
Fields inherited from class ptolemy.actor.AtomicActor
_actorFiringListeners, _initializables, _notifyingActorFiring, _stopRequested
-
Fields inherited from class ptolemy.kernel.util.NamedObj
_changeListeners, _changeLock, _changeRequests, _debugging, _debugListeners, _deferChangeRequests, _elementName, _isPersistent, _verbose, _workspace, ATTRIBUTES, CLASSNAME, COMPLETE, CONTENTS, DEEP, FULLNAME, LINKS
-
Fields inherited from interface ptolemy.actor.Executable
COMPLETED, NOT_READY, STOP_ITERATING
-
-
Constructor Summary
Constructors Constructor Description JavaScript(CompositeEntity container, java.lang.String name)
Construct an actor with the given container and name.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description protected java.lang.String
_accessorClass()
Return the name of the accessor class.protected void
_addPort(TypedIOPort port)
Override the base class so that the name of any port added is shown.protected void
_checkValidity(java.lang.String name)
Check the validity of a name.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.protected java.lang.Object
_invokeMethodInContext(java.lang.Object context, java.lang.String methodName, java.lang.Object... args)
Invoke the specified method in the context of the exports object.protected void
_setPortDescription(NamedObj portOrParameter, java.lang.String description)
Set the description of a port or parameter.void
attributeChanged(Attribute attribute)
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.void
author(java.lang.String author)
Specify author information to appear in the documentation for this actor.void
clearInterval(java.lang.Object handle)
Clear the interval with the specified handle, if it has not already executed.void
clearTimeout(java.lang.Object handle)
Clear the timeout with the specified handle, if it has not already executed.java.lang.Object
clone(Workspace workspace)
Clone the actor into the specified workspace.static javax.script.ScriptEngine
createEngine(JavaScript actor, boolean debugging, boolean restricted)
Create a script engine and initialize it.double
currentTime()
Return the current time as a number (in seconds).void
declareDelayDependency()
Declare that any output that is marked as spontaneous does does not depend on the input in a firing.void
declareIndependence(java.lang.String outputName, java.lang.String inputName)
Declare that the specified output does not depend on the specified input.void
description(java.lang.String description)
Specify a description to appear in the documentation for this actor.void
description(java.lang.String description, java.lang.String type)
Specify a description to appear in the documentation for this actor.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.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.java.lang.String
escapeForJavaScript(java.lang.String unescapedString)
Escape a string for use within JavaScript.void
fire()
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.javax.script.ScriptEngine
getEngine()
If this actor has been initialized, return the JavaScript engine, otherwise return null.static java.lang.String
getFileFromClasspathAsString(java.lang.String path)
Return the string contents of the file from the classpath.JavaScript.PortOrParameterProxy
getPortOrParameterProxy(java.lang.String name)
Get the proxy for a port or parameter with the specified name.java.lang.Object
getResource(java.lang.String uri, java.lang.Object... arguments)
Get a resource, which may be a file name or a URL, and return the value of the resource as a string.java.lang.Object[]
getTopLevelAccessors()
Provide access to the top-level accessors in this model.void
initialize()
Create a new JavaScript engine, load the default functions, and register the ports so that send() and get() can work.Token
input(java.lang.String name)
Create a new input port if it does not already exist.Token
input(java.lang.String name, java.util.Map<java.lang.String,java.lang.Object> options)
Create a new input port if it does not already exist.void
invokeCallback(java.lang.Runnable function)
Invoke the specified function in the fire() method as soon as possible.boolean
isExecuting()
Return true if the model is executing (between initialize() and wrapup(), including initialize() but not wrapup()).static boolean
isJavaScriptKeyword(java.lang.String identifier)
Return true if the specified string is a JavaScript keyword.boolean
isRestricted()
Return true if this actor is restricted.static boolean
isValidIdentifier(java.lang.String identifier)
Return true if the specified string is not a JavaScript keyword and is a valid JavaScript identifier.java.lang.String
localHostAddress()
Return the local host IP address as a string.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.void
output(java.lang.String name)
Create a new output port if it does not already exist.void
output(java.lang.String name, java.util.Map<java.lang.String,java.lang.Object> options)
Create a new output port if it does not already exist.Token
parameter(java.lang.String name)
Create a new parameter if it does not already exist.Token
parameter(java.lang.String name, java.util.Map<java.lang.String,java.lang.Object> options)
Create a new parameter if it does not already exist.void
place(java.awt.Container container)
Place the interface for this actor in the specified container.void
preinitialize()
Create a new JavaScript engine, load the default functions, and evaluate the script parameter.static java.lang.String
readFromInputStream(java.io.InputStream stream)
Deprecated.Invoke FileUtilities.readFromInputStream() directly.java.lang.Object
setInterval(java.lang.Runnable function, long milliseconds)
Invoke the specified function after the specified amount of time and again at multiples of that time.java.lang.Object
setTimeout(java.lang.Runnable function, long milliseconds)
Invoke the specified function after the specified amount of time.void
stopEnclosingModel()
Stop execution of the enclosing model.java.lang.Object
toJSArray(java.lang.Object[] array)
Convert the specified array into a native JavaScript array.void
version(java.lang.String version)
Specify version information to appear in the documentation for this actor.void
wrapup()
Execute the wrapup function, if it is defined, and exit the context for this thread.-
Methods inherited from class ptolemy.actor.gui.AbstractPlaceableActor
_exportMoMLContents, cleanUp, setFrame
-
Methods inherited from class ptolemy.actor.TypedAtomicActor
_containedTypeConstraints, _customTypeConstraints, _fireAt, _fireAt, attributeTypeChanged, clone, isBackwardTypeInferenceEnabled, newPort, typeConstraintList, typeConstraints
-
Methods inherited from class ptolemy.actor.AtomicActor
_actorFiring, _actorFiring, _declareDelayDependency, addActorFiringListener, addInitializable, connectionsChanged, createReceivers, getCausalityInterface, getDirector, getExecutiveDirector, getManager, inputPortList, isFireFunctional, isStrict, iterate, newReceiver, outputPortList, postfire, prefire, pruneDependencies, recordFiring, removeActorFiringListener, removeDependency, removeInitializable, setContainer, stop, stopFire, terminate
-
Methods inherited from class ptolemy.kernel.ComponentEntity
_adjustDeferrals, _checkContainer, _getContainedObject, _propagateExistence, getContainer, instantiate, isAtomic, isOpaque, moveDown, moveToFirst, moveToIndex, moveToLast, moveUp, propagateExistence, setName
-
Methods inherited from class ptolemy.kernel.Entity
_description, _removePort, _validateSettables, connectedPortList, connectedPorts, containedObjectsIterator, getAttribute, getPort, getPorts, linkedRelationList, linkedRelations, portList, removeAllPorts, setClassDefinition, uniqueName
-
Methods inherited from class ptolemy.kernel.InstantiableNamedObj
_setParent, exportMoML, getChildren, getElementName, getParent, getPrototypeList, isClassDefinition, isWithinClassDefinition
-
Methods inherited from class ptolemy.kernel.util.NamedObj
_addAttribute, _adjustOverride, _attachText, _cloneFixAttributeFields, _containedDecorators, _copyChangeRequestList, _debug, _debug, _debug, _debug, _debug, _executeChangeRequests, _getIndentPrefix, _isMoMLSuppressed, _markContentsDerived, _notifyHierarchyListenersAfterChange, _notifyHierarchyListenersBeforeChange, _propagateValue, _removeAttribute, _splitName, _stripNumericSuffix, addChangeListener, addDebugListener, addHierarchyListener, attributeDeleted, attributeList, attributeList, decorators, deepContains, depthInHierarchy, description, description, event, executeChangeRequests, exportMoML, exportMoML, exportMoML, exportMoML, exportMoMLPlain, getAttribute, getAttributes, getChangeListeners, getClassName, getDecoratorAttribute, getDecoratorAttributes, getDerivedLevel, getDerivedList, getDisplayName, getFullName, getModelErrorHandler, getName, getName, getSource, handleModelError, isDeferringChangeRequests, isOverridden, isPersistent, lazyContainedObjectsIterator, message, notifyOfNameChange, propagateValue, propagateValues, removeAttribute, removeChangeListener, removeDebugListener, removeHierarchyListener, requestChange, setClassName, setDeferringChangeRequests, setDerivedLevel, setDisplayName, setModelErrorHandler, setPersistent, setSource, sortContainedObjects, toplevel, toString, validateSettables, workspace
-
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface ptolemy.actor.Actor
createReceivers, getCausalityInterface, getDirector, getExecutiveDirector, getManager, inputPortList, newReceiver, outputPortList
-
Methods inherited from interface ptolemy.kernel.util.Derivable
getDerivedLevel, getDerivedList, propagateValue
-
Methods inherited from interface ptolemy.actor.Executable
isFireFunctional, isStrict, iterate, postfire, prefire, stop, stopFire, terminate
-
Methods inherited from interface ptolemy.actor.Initializable
addInitializable, removeInitializable
-
Methods inherited from interface ptolemy.kernel.util.Nameable
description, getContainer, getDisplayName, getFullName, getName, getName, setName
-
-
-
-
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 classNamedObj
- 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.
-
clearInterval
public void clearInterval(java.lang.Object handle)
Clear the interval with the specified handle, if it has not already executed.- Specified by:
clearInterval
in interfaceAccessorOrchestrator
- Parameters:
handle
- The timeout handle.- See Also:
setTimeout(Runnable, long)
,setInterval(Runnable, long)
-
clearTimeout
public void clearTimeout(java.lang.Object handle)
Clear the timeout with the specified handle, if it has not already executed.- Specified by:
clearTimeout
in interfaceAccessorOrchestrator
- Parameters:
handle
- The timeout handle.- See Also:
setTimeout(Runnable, long)
,setInterval(Runnable, long)
-
clone
public java.lang.Object clone(Workspace workspace) throws java.lang.CloneNotSupportedException
Clone the actor into the specified workspace.- Overrides:
clone
in classAbstractPlaceableActor
- 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.
-
declareDelayDependency
public void declareDelayDependency() throws IllegalActionException
Declare that any output that is marked as spontaneous does does not depend on the input in a firing. Also, declare dependencies based on prior calls to declareIndependence().- Overrides:
declareDelayDependency
in classAtomicActor<TypedIOPort>
- Throws:
IllegalActionException
- If the causality interface cannot be computed.- See Also:
AtomicActor.getCausalityInterface()
,AtomicActor._declareDelayDependency(IOPort, IOPort, double)
-
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 interfaceAccessorOrchestrator
- 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 messagethrowable
- 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:- 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.
- Next, send any outputs that have been queued to be sent by calling send() from outside any firing of this JavaScript actor.
- Next, read all available inputs, recording their values for subsequent calls to get().
- Next, invoke any pending timer tasks whose timing matches the current time.
- 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.
- Next, if the current script has a fire() function, then invoke it.
- Specified by:
fire
in interfaceExecutable
- Overrides:
fire
in classAtomicActor<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.
- 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
-
initialize
public void initialize() throws IllegalActionException
Create a new JavaScript engine, load the default functions, and register the ports so that send() and get() can work.- Specified by:
initialize
in interfaceInitializable
- Overrides:
initialize
in classAtomicActor<TypedIOPort>
- Throws:
IllegalActionException
- If a port name is either a a JavaScript keyword or not a valid identifier, if loading the default JavaScript files fails, or if the superclass throws it.
-
input
public Token input(java.lang.String name) throws IllegalActionException, NameDuplicationException
Create a new input port if it does not already exist. This port will have an undeclared type and no description.- Parameters:
name
- The name of the port.- 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.
-
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 interfaceAccessorOrchestrator
- 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 interfaceAccessorOrchestrator
- Parameters:
message
- The message
-
output
public void output(java.lang.String name) throws IllegalActionException, NameDuplicationException
Create a new output port if it does not already exist. Set the type to general.- Parameters:
name
- The name of the port.- Throws:
IllegalActionException
- If no name is given.NameDuplicationException
- If the name is a reserved word.
-
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 interfacePlaceable
- Specified by:
place
in classAbstractPlaceableActor
- Parameters:
container
- The container.
-
preinitialize
public void preinitialize() throws IllegalActionException
Create a new JavaScript engine, load the default functions, and evaluate the script parameter.- Specified by:
preinitialize
in interfaceInitializable
- Overrides:
preinitialize
in classAtomicActor<TypedIOPort>
- Throws:
IllegalActionException
- If a port name is either a a JavaScript keyword or not a valid identifier, if loading the default JavaScript files fails, or if the superclass throws it.
-
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 interfaceAccessorOrchestrator
- 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 interfaceAccessorOrchestrator
- 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.
-
wrapup
public void wrapup() throws IllegalActionException
Execute the wrapup function, if it is defined, and exit the context for this thread.- Specified by:
wrapup
in interfaceAccessorOrchestrator
- Specified by:
wrapup
in interfaceInitializable
- Overrides:
wrapup
in classAtomicActor<TypedIOPort>
- Throws:
IllegalActionException
- If the parent class throws it.
-
_accessorClass
protected java.lang.String _accessorClass()
Return the name of the accessor class. In this base class, it returns "JavaScript".- Returns:
- The string "JavaScript".
-
_addPort
protected void _addPort(TypedIOPort port) throws IllegalActionException, NameDuplicationException
Override the base class so that the name of any port added is shown.- Overrides:
_addPort
in classEntity<TypedIOPort>
- Parameters:
port
- The port to add to this entity.- Throws:
IllegalActionException
- If the superclass throws it.NameDuplicationException
- If the superclass throws it.
-
_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 classTypedAtomicActor
- 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.
-
-