This document presents information pertaining to a Java implementation of the scripting framework where Java code may be run as scripts or macros from within StarOffice. The information presented should be combined at a latter date into a scripting framework white paper. Some of the concepts presented may be general to other languages and corresponding frameworks and thus may form a scripting framework specification defining how a language and its scripting framework behaves according to the StarOffice scripting and its language neutral framework based around UNO components and interfaces.
Name space for scripting is crucial such that references to methods may be bound to events and these references may be bound to an implementation. In addition it is appropriate that any reference is defined without specifying the language, thus ensuring that it is possible to replace an implementation either dynamically or statically without having to change the references1.
The current name space defined by StarOffice for representing a method is a three tier hierarchy of:
Library.Module.Method
an instance of, for example, might be:
Tools.Debug.ShowArray
Where the method ShowArray from the module Debug in the library Tools is referenced. In addition StarOffice has a further level hierarchy that prefixes the method reference defining whether the method is referred to from within a document instance or the application. This may be defined as the context of the method. The context does not need to be defined in the method name space, instead it may be considered an attribute of what is being referred to. From the point of view of a user selecting a method to be bound to an event (the act of binding instantiates the method as a macro) the hierarchy is:
Context.Library.Module.Method
and an instance of this hierarchy might be:
StarOffice (application context).
Tools (library)
Debug (module)
ShowArray (method)
printdgbinfo (method)
UCB (module)
WebWizard (library)
Untitled1 (document context)
Standard (library)
Module1 (module)
Main (method)
Untitled2 (document context)
Thus there may be more than one document available to bind methods to events in either context, or create libraries/modules/methods from within the document.
This name space needs to be suitably mapped to the Java name space consisting of jar files, packages, classes and methods. Table 1 presents the proposed mapping of the Java name space to the StarOffice name space, the details of StarBasic are also presented next to the Java column.
StarOffice |
Java |
Basic |
||
---|---|---|---|---|
Context |
application |
document |
application |
document |
Library Location Language specific |
CLASSPATH Multiple jar files referenced. |
ClassLoader 'Java' directory in XML zip file contains multiple jars. |
script.xlc Defined in user configuration directory. |
script-lc.xml Defined in 'Basic' directory in XML zip file which contains multiple libraries |
Library |
package |
package |
script.xlb |
script-lb.xml |
Module |
class |
class |
<Module>.xbc |
<Module>.xml |
Method |
method |
method |
BASIC Sub/Function |
BASIC Sub/Function |
|
|
|
|
|
Table 1 Java to StarOffice name space mapping
To fully define how Java maps it is necessary to introduce a language dependent layer into the hierarchy which is part of the language dependent scripting framework. For the application context the location of jar files needs to be defined as a 'CLASSPATH' property. From this set of jar files packages may be chosen to represent a library. A class from a package may then represent a module and a method on the class a StarOffice script method. For the document context a specific 'classLoader' may be required that is able to load the Java classes (modules) from jars files stored in the XML zip file. Alternatively the relevant file may be copied to a temporary area on disk with a specific reference to what document it refers to. The latter may be more appropriate if editing and recompiling source associated with a document2.
Given this representation there are a number of observations:
The library location (CLASSPATH) and libraries (packages) represent a unit for the language. It is not possible to connect modules implemented in Java to a library defined in StarBasic. It may not be advantageous to allow for this level of indirection. The current definition may result in less name space clashes between multiple libraries that have been developed by different vendors.
For languages that leverage the JVM it may be appropriate to include other language implementations with the library since some script languages can generate Java byte code in addition to availing of Java code that might be co-packaged.
The module (class) represents the unit of computation for the language.
A deployment descriptor can be used to define what packages, classes and methods within a jar file correspond to libraries, modules and methods. This can be represented in XML and with respect to the jar be referenced:
Internally
The deployment descriptor is referenced inside the jar META-INF directory.
If copying the pattern from J2EE ear and war packaging then this jar could
be described as a Script ARchive resource
or sar file.
Externally
Since the CLASSPATH defines what jar files to reference it is equally
applicable for the same deployment descriptors to be stored externally.
For example they could be generated when a user creates a library and connects
it to an existing externally accessible jar file. The user can select packages,
classes and methods appropriately.
Other types of information may also be defined in the deployment descriptor:
Properties. When the class for the module gets instantiated certain properties can be associated with the object by using the JavaBeans approach to the getX and setX methods associated with property X. When a user deploys a sar it may also be possible to explicitly override some of these values.
State. It could be defined whether a module is stateless or stateful over multiple event invocations. In Java it is appropriate to adopt the latter as default as it is more performant and does not require a new instantiation or reset to initial state each time an event occurs.
Persistence. Script managed or module managed persistence could be defined. This is relevant to modules associated documents. When the document is loaded modules bound to events could load persistent state from the document. Likewise when the document is saved state associated with the module could be persisted.
Versioning. This could just reflect the version defined in the corresponding Java package.
Encryption of Java source code.
The XML tags should where possible be language agnostic thus could be used for other scripting languages such as Jython, perhaps just one tag reflecting the language at the library and/or module level.
A collection of deployment descriptors will represent a set of libraries, modules and methods. A Java scripting framework can create a 'module table' defining all the available libraries, modules and associated data. This can then be used to search the module space for method selection, or to obtain module information for a specific method/module. UNO interfaces and proxy implementations are required by the scripting framework and StarOffice such that the StarOffice UI can browse this space.
A Java method is bound to a method referenced by the StarOffice scripting name space. Binding will create a proxy object that is capable of invoking the corresponding Java method on the Java class corresponding to the module. This proxy object is an UNO component implemented in Java that implements a specific UNO interface which defines invoking. This is part of the Java scripting framework and thus Java developers do not need to know how to write Java UNO components. The proxy object can maintain a reference to the Java module object and method.
Binding results in a many to one instance relationship between the proxy and the object corresponding the class instance which is defined as the module. Initial binding can result in the instantiation of the class. An instance manager may manage the relationship between proxies and module objects such that binding and unbinding can be performed. In addition, given the capabilities of the module object, it could provide life cycle and run-time services:
Resource management. Module objects may require the creation and management of resources thus can be informed when resources may be created and destroyed. For example, the opening and closing of database connections. This type of management can be linked to the initial binding and unbinding of all the references to the proxies.
Concurrency management. Java developers should not deal with the complexities of thread management, re-entrant code and synchronization when it is possible that invocation can happened concurrently. The manager can ensure that only one method on a module object is capable of being called by providing locking and wait services that the proxy object may avail of.
Context. Java methods on module objects may require access to the current application or document context. This is described in more detail in the next section.
Access to the instance manager functionality via StarOffice will also be required such that binding/unbinding can occur, thus UNO wrappers will be required with corresponding UNO interfaces.
Binding context is required such that when the method is invoked the context may be obtained, for example to obtain the document associated with the method. Within StarOffice there are four possible combinations (cases) of method location and binding context as presented:
|
Context |
|
Method Location |
Application |
Document |
External |
1 |
3 |
Document |
4 |
2 |
How the method references are stored and context accessed depends on the type of binding. The four cases are described with respect to how StarOffice stores the bindings:
This is probably the simplest of the cases. With respect to StarBasic the method is stored either under the user/basic or share/basic directories. The event binding is stored as an entry in the user/config/soffice.cfg/eventbindings.xml file. The “event-library” attribute is “StarOffice”, and “macro-name” attribute corresponds to the method reference.
In the case where a binding is made for a method within a document, the binding is stored as a <script:event> element in the document's content.xml. The “location” attribute of this element is set to “document”, with the “macro-name” attribute as in case (1). The code is stored in the Basic subdirectory within the document's zip file.
The case is very similar to (2). The difference being that the <script:event> element in the document's content.xml has its “location” attribute set to “application”. The code referenced should be in the locations mentioned in case (1).
This is possibly the most complex case. The event binding is stored in the same location as in case (1), but the library name is the name of the document (e.g. “MyDoc.sxw”). The method referenced is only invoked when the document is open, or when any document of the same name, containing a macro of the same name, is open.
In StarBasic the method bound to an event which is invoked can access context of document or application via the two global variables ThisComponent and StarDesktop respectively.
With respect to Java the context is associated with the proxy object when it is created from the bind. Thus it is up to an instance manager or the proxy object to manage the context such that it may be accessed by the Java method when it is invoked.
The UNO proxy object implements an interface with an 'invoke' method that contains a general set of input arguments and returns a general argument. The proxy object can:
Use reflection to ascertain the type of the parameters and map these to the parameters on the Java method. If a Java method has no parameters it can still be invoked, the proxy assumes that the developer was not interested in what may be passed. This makes it easy for Java developers to quickly create macros and experiment.
Ensure concurrent access via the synchronization services of an instance manager.
Provide interception to services such that debugging and logging may be performed.
Assign context via the services of an instance manager. Before the Java method is invoked the context (set at the bind) can be obtained and set to the current context: by either passing as a parameter to ensuring its accessibility via a static class. This context can be either the application or document and there does not need to be a separate distinction3.
Since the creation/editing and compilation of Java source is associated with the IDE it potentially the IDEs responsibility to reference to the Java source code to the jar file associated with the CLASSPATH of the Java scripting framework. This appears to be satisfactory for the application context but not for the document context since users may want to edit, given permission, modules stored within the document. In addition it might be possible to copy code from the application context to a document context, meaning source may at some point have to be put into the sar file.
For security reasons source code may not be supplied within a sar file. Alternatively the source could be encrypted requiring a password to decrypt for editing and recompilation. The encryption and decryption of source should be handled by an IDE and use standard Java cryptography APIs.
Code may also require trusting via certificates before executing and thus may require signing. In addition code that has the ability to execute may require the use of additional resources that are not granted by the default security policy of the Java scripting framework. Permission to grant needs to be allowed by the user when code will be used e.g. opening a document or binding to an event4.
Code may also require obfuscating and again this should be a function of the IDE and its capabilities when compiling the code.
It is proposed that a prototype architecture of the naming, searching, binding and invoking aspects of a Java implementation of the language dependent parts of the scripting framework be designed and implemented based on the information described in the previous sections. This represents the core functionality required regardless of whether Java code is stored within a document or not or how script code is created, updated and debugged by an IDE.
One primary goal drives the prototype design.
It must be easy for developers to write Java code that can be used as scripts from with StarOffice.
thus with respect to the core framework developers should not have to worry about threads, writing UNO components and possibly persistence management5.
It is not necessary to integrate with StarOffice. However it is required that the lower level UNO platform is used such that UNO interfaces can be designed, implemented and tested. It is proposed that where possible 'standard' Java code should be used with UNO wrappers and proxies providing the integration layer. These choices will aid modularity and speed up prototype development time6.
Illustration 1 presents a diagram representing a high level possible class relationship for binding and invoking.
Illustration 1Binding and Invoking
A module instance is defined as a Java Object and subtype (class name of the object instance), which is defined as the ModuleBean. A standard Java class may be written and it requires no extra implementation of methods, interfaces and associated contracts to participate in the binding and invoking process.
The ModuleBean can behave as a Java bean for properties to be set when the object is instantiated.
The UNO interface that represents a bound method. Services and implementations of will implement the invoke method. The input parameters are explicitly generic, as is the return parameter. This interface is that mechanism by which StarOffice can invoke a method which is bound to an event.
The invoke method is defined to be synchronous. Any asynchronous functionality needs be defined by a separate interface.
The Java proxy object implementing of the XMethod interface. The proxy object's invoke method invokes a referenced Java Method on a referenced Java Object.
It is responsible for a number of aspects:
Input parameter mapping between generic type set for the invoke method and more specific types associated with the Java method.
Output parameter wrapping. The return parameter from the Java method may not be appropriate if the wrapped primitive type or object cannot be represented in the UNO framework.
Concurrency management via the ModuleInstanceManager7. Only one method on a module may be executed at the same time.
Interception for logging and debugging.
Context setting via the ModuleInstanceManager.
Persistence management via the ModuleInstanceManager
The ModuleInstanceManager provides functionality to bind method references to XMethodProxies and unbind to the ModuleBean implementing the methods referred.
It is responsible for:
Instantiating a ModuleBean.
Maintaining relationships between the proxies and module objects.
Providing concurrency services.
Context setting services.
Persistence services. The corresponding Module class could implement java.io.Serializable for script framework managed persistence or Externalizable for class managed persistence. The details of dealing with the persistence for example where to store and how can be hidden through standard and documented Java mechanisms.
In some respects this class could be a facade to these types of responsibilities.
The Module defines an immutable class that represents the model for the parts of a XML deployment descriptor used to describe the module. This would also include the associated Java classes and methods.
The ModuleManager manages a set of modules and provides functionality to search the Module name space, including the location context (application or document instance) in much the same way that is provided by the java.lang.ClassLoader. In addition it should provide the ability to update or add one or more Module objects that have been created given the XML deployment descriptors e.g. when a new document is opened that contains Java code.
In conjunction with the XMethod interface additional UNO interfaces are required to ensure that integration with StarOffice can eventually be achieved. Roughly these interfaces are:
XModules
Provides information about libraries, modules and methods via the set
of modules (the unit of computation available). This could wrap the ModuleManager
interface for query access.
XModule, XLibrary
Immutable interfaces or structs could be provided for representing a
module and library.
XMethodBinder
Provides the ability to bind, with associated context, or unbind an object
to a method reference or XMethod respectively.
There is also the overall script language service that has:
XMethodBinder access
XModules access
Property functionality. Perhaps including IDE related information and capabilities.
Language type description
Listeners to the opening and closing of documents such that the ModuleManager may be updated to add and remove modules.
Listeners to the saving of documents such that code and module state can be stored.
Listeners to IDE related functionality e.g. edit code hook from StarOffice, or code updated from IDE.
Security related callbacks for code. e.g. grant permissions, accept certificate.
It is believed that core aspects of naming, searching, binding and invoking are understood well enough to develop a prototype with Java code, corresponding UNO interfaces and components to test these concepts. Other areas such as code storage and persistence are understood to the extent that the core design can be aware of these requirements. As more aspects of scripting are better understood expansion of the framework Java code, UNO interfaces and components can proceed.
1Current reference to StarBasic methods include a language attribute. The reference to the method should be enough through another level of indirection to obtain the implementation. It is believed that this is especially important for documents that reference methods external to the document (e.g. application level scripts and methods). For example migration of existing StarBasic scripts to Java could be performed without having to modify existing documents or configuration files.
2Code and data (codats) only require storing back in the document when saving.
3Although a method may still require access to the application which is always present, and this could be provided by another method on the same static class.
4This is similar behaviour to applet downloading and user granting permissions for the applet to execute.
5The overall scripting strategy will require tool support (IDE) to achieve this goal.
6There is potentially significant refactoring required of StarOffice code to ensure that StarBasic is just one language implementation. The UNO interfaces and design developed in the prototype will aid this processes.
7Need to understand the relationship between UNO C++ and Java thread execution of control. This also has wider impact for features relating to asynchronous invocation and the stopping of an invoked but not yet returned method.