Scripting the repository using Jython
Introduction
A detailed explanation on how to script Daisy Repository is given on this page. It is also possible to script Daisy repository in other languages than JavaScript. This topic covers the procedure on how to setup a Jython environment for Daisy Repository scripting.
Why Jython?
As you have probably noticed, JavaScript has almost nothing common with Java, but the first part of the name. Jython (actually Python) if compared to JavaScript, is a much more powerfull and flexible programming language. One more difference is that Jython comes "with batteries included" - a number of modules ported from standard Python platform.
You might find Jython useful for developing prototypes of some complex Daisy Repository client applications. Its syntax is pretty clean and can be translated to Java without significant difficulties.
Setup
First of all you have to install Jython and get the Daisy Repository client stub libraries.
To make launching Jython with required JAR files in the CLASSPATH convenient, the daisy-js batch file can be reused in the following manner.
- Set the environment variable JYTHON_HOME to your local Jython installation directory;
- Copy daisy-js file to daisy-py
- Add a check for JYTHON_HOME environment variable like this:
if [ -z "$JYTHON_HOME" ] ; then echo "JYTHON_HOME not set!" exit 1 fi
- Remove Rhino JARs from the CLASSPATH
- Replace the last line of the file, instead of executing Java VM, put this
line there:
"$JYTHON_HOME/jython" -Ddaisy.home=$DAISY_HOME $@
Now you should be able to run client scripts by executing daisy-py:
$ ./daisy-py sample_repo_access.py
Examples
Following examples perform the same functionality as JavaScript scripting examples.
Performing a query
from org.outerj.daisy.repository import *
from org.outerj.daisy.repository.clientimpl import RemoteRepositoryManager
from java.util import Locale
repositoryManager = RemoteRepositoryManager("http://localhost:9263",
Credentials('testuser', 'testuser'));
repository = repositoryManager.getRepository(Credentials('testuser', 'testuser'));
queryManager = repository.getQueryManager();
searchresults = queryManager.performQuery("select id, name where true",
Locale.getDefault());
rows = searchresults.getSearchResult().getRows().getRowArray();
for val in rows:
print "%d : %s" % (val.getValueArray(0), val.getValueArray(1))
print "Total number: %d" % len(rows)
Accessing repository directly via HTTP
Daisy Repository API offers a pretty good abstraction of repository access routines. Unfortunately, it uses a number of external libraries. In case, if you wish to have a number of used libraries as low as possible, accessing the repository directly might be useful.
The following example has a single external dependency: commons-httpclient library. It logins a user to the repository server and fetches user's roles from it. Original code was taken from commons-httpclient samples collection and modified to its current state.
from org.apache.commons.httpclient import HttpClient, UsernamePasswordCredentials from org.apache.commons.httpclient.auth import AuthScope from org.apache.commons.httpclient.methods import GetMethod # some of these imports are not actually necessary, as the classes # they import are not referenced directly. This is done with the only # purpose: simplify porting to Java from javax.xml.xpath import XPath, XPathFactory, XPathConstants from javax.xml.parsers import DocumentBuilder, DocumentBuilderFactory from java.io import ByteArrayInputStream from java.lang import String from org.w3c.dom import Document, NodeList def main(): login = 'testuser' password = 'testuser' hostname = 'localhost' request_url = "http://%s:9263/repository/userByLogin/%s" % ( hostname, login) client = HttpClient() # pass our credentials to HttpClient, they will only be used for # authenticating to servers with realm "daisy" on the host # "localhost", to authenticate against # an arbitrary realm or host change the appropriate argument to null. client.getState().setCredentials( AuthScope(hostname, AuthScope.ANY_PORT, "daisy"), UsernamePasswordCredentials(login, password)) # create a GET method that reads a file over HTTP, we're assuming # that this file requires basic authentication using the realm above. get = GetMethod(request_url); # Tell the GET method to automatically handle authentication. The # method will use any appropriate credentials to handle basic # authentication requests. Setting this value to false will cause # any request for authentication to return with a status of 401. # It will then be up to the client to handle the authentication. get.setDoAuthentication(True); try: # execute the GET status = client.executeMethod(get); # print the status and response response = get.getResponseBodyAsString() print "STATUS: " + str(status) + "\n" + response # extract role names from the response body expression = '/user/roles/role/@name' builder = DocumentBuilderFactory.newInstance().newDocumentBuilder() document = builder.parse(ByteArrayInputStream( String(response).getBytes())) # we expect that the user might have more than one role, # NODESET is specified to fetch them all xpath = XPathFactory.newInstance().newXPath() roles_set = xpath.evaluate(expression, document, XPathConstants.NODESET) roles_count = roles_set.getLength() print "The user has %d roles, they are:" % (roles_count) for i in range(0, roles_count): print roles_set.item(i).getTextContent() finally: # release any connection resources used by the method get.releaseConnection(); if __name__ == '__main__': main()



There are no comments.