Open Scripting Architecture: Scripting for the Masses
Open Scripting Architecture (OSA) gives OpenDoc users a way of customizing their documents to an extent never before possible. Many users of PC software are already familiar with the macro languages available for the more powerful spreadsheets, word processors, databases, and so forth on the market. These macro languages let you customize your application. Sometimes you can use macro languages to provide a record/playback facility, that is, a way of automatically remembering a sequence of keystrokes and then re-executing them as a single command. And, an experienced user can use a macro language to create new functions to the point where the old application is almost unrecognizable.
Sounds great, right? But there is a down-side. Each application typically has its own macro language with its own command set and syntax. This means that you have to learn and relearn macro languages as you move from one application to another. And, there is virtually no chance to interoperate with another application. The mechanisms for exchanging commands and sharing data simply aren't there. So as your sophistication grows and the number of applications you use increases, the limitations of the macro-language approach become all too apparent. And in an OpenDoc environment, where a single document can and will have multiple parts, each with their own programming model and their own data type, it's clear that the macro-language approach will not be adequate. What's needed is something powerful, flexible, easy to use, and that can be used as the common denominator between OpenDoc parts.
For OpenDoc parts to work together seamlessly, the scripting architecture has to provide solutions for a number of problems. A facility must exist for exchanging commands between parts. The commands themselves must be understood by both the parts generating them, as well as the parts receiving them. The parts must have a consistent way of naming the parameters. And finally, because an OpenDoc system is designed to work both in a network and on multiple platforms, the solution must be effective no matter where the parts reside.
OSA provides the facilities that meet these requirements. First, it defines a set of standard messages are defined called OSAEvents. OpenDoc implementations that support OSA provide an event manager that ensures that parts can send and receive OSAEvents correctly. CILabs will hold the definition of the OSAEvents that are standard among OpenDoc implementations in OSAEvent Standard Suites. Finally, parts sending OSAEvents will use a component called the Object Services Library (OSL) to encode the command and the parameters in a universally understood way. On the other end, the part receiving the OSAEvent uses the OSL to decode it.
OSA divides events into two categories: user interface events (UI events), for example mouse button down, and semantic events, for example open file. Traditional applications that provide record/playback facilities or rudimentary macro facilities often use UI events. When the application's user selects a menu pulldown, the application records the mouse movement and the action of the mouse buttons. During playback, the mouse moves to exactly the same position as during the record and generates the button event. If conditions are the same as when the recording was made, the correct menu selection is generated. But if some condition is varied, for example the position of the main window or the size or resolution of the display, the results of the playback can be unpredictable.
Semantic events rely on the meaning of the user's actions. No mouse movements or button clicks are recorded. Instead, the semantic event is generated only after the user's intentions become clear. For example, when the menu item Print is selected, the semantic event Print is sent, not the mouse x-y coordinates. The meaning is always clear; the size of the display or the position of the windows on the desktop are all irrelevant.
Semantic events, then, are the messages that parts send to each other using the OpenDoc event management component. For these messages to be useful, they must be universally understood. That's the job of the event suites.
Standard Event Suites
OSAEvents consist of verbs and object classes. They are arranged according to category of use in groups or suites. Some examples of the standard suites are:
- Required - The base set of functions that all compliant parts must support
- Core - The set of functions that defines file, edit, and basic scripting
- Text - The set of functions that defines basic text editing and formatting
- Table - The set of functions that defines table editing and formatting commands
As you can see, the suites map into various existing application types. Someone implementing a spreadsheet part for OpenDoc must support the Required, Core, and Table suites. All of the existing suites for all of the defined application types are contained in a registry owned by CILabs. The registry ensures that all developers will be using the same set of commands and the conventions for specifying parameters. As a result, applications can work together even though they were written by programmers who never met and who had no prior knowledge of the other's work. Contrast this with applications having to have a deep knowledge of each other and companies having a private contract between them. Clearly an unachievable goal except for a few suites of programs designed and built to work together!
Each standard suite can define any of the following:
- OSAEvents (the verbs)
- Object classes (the class of data or parameters operated on by the events, for example, document, selection, and text)
- Descriptor types (the type of the data or parameter, for example, record and Boolean)
- Primitive object classes (no properties and only one element, for example, RGBColor and IntlText)
- Key forms (used to specify how to search for an object, for example, range, position, and ID)
- Comparison operators (for example, contains, begins with, and equals)
A very powerful concept of OSA is the object specifier. Object specifiers let an application provide a parameter by describing the data in relative terms. They are designed to make it easy to go from a natural language construct like "the third word of the fourth line of paragraph one" to an object specifier encoded in an OSAEvent. The application uses OSL to encode the object specifier. The program calls OSL repeatedly to create a nested specifier, with the outermost container specified first. Each subsequent call uses the results of the previous call as its container.
Figure 1. Object Specifiers
At the other end, the process is reversed with the target application decoding the object specifier in a manner not unlike peeling an onion. The target application, which is OSA compliant, provides accessor functions for finding an object. As the object specifier is resolved, the appropriate accessor function is called. The function returns a token understood internally to indicate the found object. Each subsequent step for resolving the specifier uses the previously generated tokens until the complete set of tokens is generated for the objects specified. The application also provides callbacks that are used for functions that only the application itself can perform. Examples include counting, comparing, or marking objects.
Up until now, we've talked about how programs talk to one another with OSAEvents - without mentioning scripting. That's because we've saved the best for last!
OSA supports scripting components that can control an application by reading a script file and sending appropriate OSAEvents to the program. Because of the power of OSA, in general, and object specifiers, in particular, you can build scripting components that, though powerful, can be used even by the uninitiated.
OSA allows a script to be formed that closely resembles natural language. In fact, OSA makes it possible to create scripting components that are language independent. Because the underlying mechanism is through OSAEvents and object specifiers, it becomes very easy to translate the script with a simple click on the "language" radio button.
Scripts are very powerful and can create totally new applications by automating an existing program or by providing a way for two or more independent programs to operate as a unit with the script acting as the programming glue. OSA lets you attach scripts to an application or a document. Every time the program is activated or the document is selected, the script is executed.
In the OpenDoc technology, it will be possible to attach scripts to documents or to the individual parts embedded in a document. One can easily think of lots of ways in which these scripts might be used. For example, a script could be attached to a text part that invoked a spell checker (the user's favorite spell checker - not just the one shipped with the application!) when executed. Or, perhaps a graph part displayhing stock information could have a script that accessed a dial-in service to get up to the minute stock quotes - whenever the document is opened! The possibilities are limited only by the imaginations and ingenuity of the users - in other words boundless!!
If an application is factored, that is, constructed in a way that separates the user interface section from the main code of the program, you can use a record/playback tool to monitor the user's actions when driving an application. This depends on the user interface section of the code communicating with the main engine through OSAEvents. The recorder then can receive a clone of every OSAEvent sent and record them. Later the recorded events can be played back effectively automating the application. If the record/playback tool is aware of a script component, the events can be stored as a script and even displayed in realtime. The user can learn how to write a script simply by operating the application with the recorder turned on. The resulting script then can be studied or even modified. This is a very effective and quick way to start writing scripts in an OSA world.
Programmers who support OSAEvents in their applications and factor them, get a number of benefits - two of which are scriptability and recordability for their efforts. But another that they get for free is alternative input devices. Because the application is structured so that it operates entirely on the exchange of OSAEvents, its functions are independent of the source of the events. The events could have been generated by the standard user interface or by a scripting component. It doesn't matter - as long as the OSAEvents are constructed correctly it all works. Alternative input devices like voice, pen, touch screen, can be built that generate OSAEvents and they can be used to drive the application without changing a single byte in the code!
Figure 2. Generating OSAEvents With Alternate Input Devices
The OSA technology gives users the kind of flexibility and power that before was available only to the programming professional. Semantic events replace UI events as the prime mover of the program. By standardizing these events in a registry available to all developers, interoperability among documents is assured. Use of object specifiers gives users the freedom to use natural language to express their commands. And pluggable script components means that a range of script languages can be selected to suit the audience. An application can change with scripting and can be tailored with record/playback; while, new input devices will drive the OSA-compliant applications of today and the future.
- Apple Computer, Inc., Apple Event Registry: Standard Suites, Winter 1992, Developer Technical Publications, 03-1958-A
- Addison-Wesley Publishing Company, Inside Macintosh Interapplication Communication,
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation