[Hop] new feature: script any java object

Hannes Wallnoefer hannes at helma.at
Mon Sep 10 17:58:44 CEST 2001


Today's snapshot brings an nice new feature to Helma: It's now possible
to script any Java object with Helma. Scripting here does not mean
accessing an object via JavaScript (which has been possible all along),
but extending it via scripted functions, practically subclassing it,
i.e. adding JavaScript functions to the methods defined by the object's
class. 

There are two applications for this:

 * if you use a Java object from within Helma, you can use 
   this to create friendlier, higher level functions to 
   access and manipulate the object.

 * You can use any Java object as part of a Helma URL tree, 
   adding script, action and skin files to them. Previously this 
   has been possible just for Java objects that implement the 
   IPathElement interface.

The way to do this is pretty easy: Just create a file called
"class.properties" in the application directory and add an entry for
each java class you want to sub-script with the name of the prototype to
use for scripting it. 

java.util.Hashtable = Hashtable
com.foo.Bar = foobar

In the above example, if you created a Hashtable object by calling its
constructor 

  var table = new java.util.Hashtable()

you could call all the public methods defined for java.util.Hashtable
*plus* the JavaScript functions defined in the Hashtable prototype. In
the Hashtable prototype, you can use the "this" keyword to access this
extended Hashtable object.

If you want to use generic Java objects as path elements of an
application's URL tree, there are a few additional things to do. First,
you have to tell the application that you want to use a custom Java
object as root object. There are two ways to achieve this:

The first is to set the rootObject property in your app.properties file
to the class name of the Java object to be used as root object. An
object of this class will be created. Previously, the root object class
had to implement the IPathElement interface, this is no longer
necessary.

The second way is to explicitly set the root object by calling the
setDataRoot() method in the application class. This is useful for
running Helma in embedded mode, i.e. as part of another Java
application. It's already entirely possible to use Helma this way - the
Java code to get a Helma app running in embedded mode including setting
up the web server is less than 10 lines. This will be described in a
future HOWTO, still fixing some details.

Now in both cases, the key to get generic Java objects (that don't
implement the IPathElement interface) to function as Path elements in a
Helma app is to implement the necessary methods of the IPathElement in
JavaScript. More precisely, you have to: 

 * implement getChildElement(str) to enable URL path resolution 
   from the current object to its (potential) child objects. If 
   not implemented, accessing a child object will always cause a 404.

 * implement getParentElement() and getElementName() if you want 
   href() to work. If not implemented, href() will return "/".


I put a little demo app online which demonstrates some of the above. 

http://helma.org/download/contrib/base.zip

It's called "base" since it'll probably be the starting point for the
new Helma base application, running in / and linking to all other active
applications. The special thing about it is that its root element is the
Helma server itself, so you can use it for introspection on the running
server - for now, this means just getting an up-to-date list of running
applications and linking to them. To get the app running, you have to
add it as 

  base=self 

in the apps.properties file instead of just "base" - that's the
temporary hack to let  the application manager know it has to to set the
application's root object to the Helma server object itself.

phew, quite a long mail. I hope it works and I didn't forget anything
important and you have fun with it.

Hannes



More information about the Helma-user mailing list