What is it?
Rhino Components is a library of (popular) Java API’s, adapted to be useful in a Javascript framework called Mozilla Rhino.
How was the project conceived?
The idea for these components were conceived during a project which needed a clear separation between ‘business’ features and ‘technical’ features. In fact, the developers in the team had no experience to program in Java, and didn’t know how to distinguish the purpose of the tiers, API’s and components used in the project.
In order to ease the separation I introduced a scripting framework (Mozilla Rhino) in which all business logic would be written, exposing just a few Java API’s and components to execute database queries and SOAP calls.
It turned out to work great for everyone involved, and so the project Rhino Components started to consolidate the ideas from that project into something more substantial.
What is the usecase of Rhino Components?
Serverside Scripting
Rhino Components is basically a means to support Serverside Scripting. Just like you would ’script’ the components of the browser (DOM tree, HTTP connection, Mouse, Keyboard), you could ’script’ the components (or services) of the Java EE server to a functional piece of business code.
Separation of concerns
The Rhino runtime environment enforces a Sandbox in which to execute the code. The developers would provide a ‘technical’ platform in which every service or component is provided to the scripter. The scripter creates the Business Logic by wiring all necessary components and services together in Javascript.
Simple and Readable code
The Scripting code is only covering the business logic – for every ‘outward’ call it needs to use the provided components and services. This results in code without too much technical details (as much as possible anyway
)
Where can I find it?
The code is in CVS at SourceForge. Unfortunately, no (in)formal releases yet…
Examples
For a good overview of the capabilities of the Rhino Components library, the testcases are a good place to start. For your convenience we show some of the examples below:
Spreadsheet component
This component uses Jakarta POI to read (and write) Microsoft Excel-formatted spreadsheets.
The component is initialized as follows:
var spreadsheet = new Spreadsheet('file://my-spreadsheet.xls');
This is the way to reference cell ‘B10′ on the sheet named ‘Sheet1′:
var b10 = spreadsheet.Sheet1.B10;
or by using Array indexes:
var b10 = spreadsheet.Sheet1[1][9];
JDBC component
The JDBC component leverages the JDBC API to perform database calls.
This way you could connect to a database (please note that in the released version this must be provided for you):
var db = new Database("jdbc:url", username, passwd);
This is how to get a scalar value from a query:
name = db.getValue("select name from person where height = 2.02");
This is the way to iterate over query result data:
var records = db.getRecords("select * from person");
for (var rec = records.next(); rec != null; rec = records.next()) {
for (attr in rec) {
log.info(" value: " + attr + "=" + rec[attr]);
}
log.info("name: " + rec.NAME + ", dob: " + rec.DOB + ", height: " + rec.HEIGHT);
}
A very powerful feature is the ability to create Javascript functions out of SQL queries:
var getPersonsYoungerThan = db.prepareQuery("select * from person where dob > ?", true, Date);
var records = getPersonsYoungerThan(new Date(1950, 1, 1));
WSDL component
The WSDL component gives you the ability to turn SOAP methods into Javascript functions (only if RPC-encoded). It works like this:
var wsdl = new WSDL("http://localhost:8080/EchoHeaders.jws?wsdl");
var response = wsdl.echo("Hello there! Echo!");
// response == "Hello there! Echo!";
This piece of code uses the example webservice from Apache Axis to operate on.
XMLHTTP component
This component is the same component you would use in the browser to perform Ajax calls, and is widely known as the XmlHttpRequest (or XHR) object. It uses the same API as the Firefox/IE/Opera/Safari editions, with a small difference: instead of DOM XML objects it uses (native) E4X XML objects. The following code calls a SOAP method, for instance, the same as the WSDL sample uses above:
xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "http://localhost:8080/EchoHeaders.jws", false);
xmlhttp.setRequestHeader("SOAPAction", "echo");
xmlhttp.setRequestHeader("Content-Type", "text/xml");
xmlhttp.send(
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:echo xmlns:ns1="http://localhost:8080/EchoHeaders.jws"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<arg0 xsi:type="xsd:string">Hello Rhino Components User!</arg0>
</ns1:echo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>);
statusCode = xmlhttp.status;
statusText = xmlhttp.statusText;
text = xmlhttp.responseText;
xml = xmlhttp.responseXML;
state = xmlhttp.readyState;
soapNs = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
ehNs = new Namespace("http://localhost:8080/EchoHeaders.jws");
response = xml.soapNs::Body.ehNs::echoResponse.echoReturn;
assert.assertEquals("HTTP statuscode must be right!", 200, statusCode);
assert.assertEquals("SOAP response must be right!", "Hello Rhino Components User!", response);
assert.assertEquals("The property 'xmlhttp.readyState' must be 4!", 4, state);
XSLT component
The XSLT component leverages the Java TRaX API to perform XSLT transformations. The component works like this:
var processor = new XsltProcessor(
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:param name="prefix" />
<xsl:template match="*">
<message>
<xsl:value-of select="concat('Hello ', $prefix, ' ', @name, '!')" />
</message>
</xsl:template>
</xsl:stylesheet>);
var input = <text name="Bart Guijt" />;
var expected = <message>Hello Dr. Bart Guijt!</message>;
var result = processor.transform(input, {prefix: "Dr."});
log.debug("Input: " + input.toSource());
log.debug("Result: " + result.toSource());
assert.assertEquals("XML Result must be same as expected!", expected.toSource(), result.toSource());
Cool, right?
Status of the software
The software is still in an unreleased status, ‘alpha’ quality. Use at your own risk
