Java API
Introduction
Daisy is written in Java and thus its native interface is a Java API. This Java API is packaged separately, and consists of two jars:
daisy-repository-api-<version>.jar daisy-repository-xmlschema-bindings-<version>.jar
The second jar, the xmlschema-bindings, are Java classes generated from XML Schemas, and form a part of the API. To write client code that talks to Daisy, at compile you need only the above two jars in the classpath (at runtime, you need a concrete implementation, see further on).
There are two implementations of this API available:
- a local implementation, this is the actual implementation in the repository server, which does the real work
- a remote implementation, this is an implementation that talks via the HTTP+XML protocol to the repository server
This is illustrated in the diagram below.
To be workable, the remote implementation caches certain information: the repository schema (document, field and part types), the collections, and the users (needed to be able to quickly map user IDs to user names). To be aware of changes done by other clients, the remote implementation can listen to the JMS events broadcasted by the server to update these caches. This is optional, for example a short-running client application that performs a specific task probably doesn't care much about this, especially since the cached information is not the kind of information that changes frequently. Even when JMS-based cache invalidation is disabled, the caches of a certain remote implementation instance are of course kept up-to-date for changes done through that specific instance.
Examples of applications making use of the remote API implementation are the Daisy Wiki, and the installation utilities daisy-wiki-init and daisy-wiki-add-site. Especially the source of those last two can serve as useful but simple examples of how to write client applications. The shell scripts to launch them show the required classpath libraries.
Quick introduction to the Java API
The Daisy Java API is quite high-level, and thus easy-to-use. The start point to do any work is the RepositoryManager interface, which has the following method:
Repository getRepository(Credentials credentials) throws RepositoryException;
The Credentials parameter is simply an object containing the user name and password. By calling the getRepository method, you get an instance of Repository, through which you can access all the repository functionality. The obtained Repository instance is specific for the user specified when calling getRepository. The Repository object does not need to be released after use. It is a quite lightweight object, mainly containing the authentication information.
Let's have a look at some of the methods of the Repository interface.
Document createDocument(String name, String documentTypeName);
Creates a new document with the given name, and using the named document type. The document is not immediately created in the repository, to do this you need to call the save() mehod on the Document. But first you need to set all required fields and parts, otherwise the save will fail (it is possible to circumvent this, see the full javadocs).
Document getDocument(long documentId, boolean updateable) throws RepositoryException;
Retrieves an existing document, specified by its ID. If the flag 'updateable' is false, the repository will return a read-only Document object, which allows it to return a shared cached copy. In the remote implementation, this doesn't matter since it doesn't perform any caching, but in the local implementation this can make a very huge difference.
RepositorySchema getRepositorySchema();
Returns an instance of RepositorySchema, through which you can inspect and modify the repository schema (these are the document, part and field types).
AccessManager getAccessManager();
Returns an instance of AccessManager, through which you can inspect and modify the ACL, and get the ACL evaluation result for a certain document-user-role combination.
QueryManager getQueryManager();
Returns an instance of QueryManager, through which you can perform queries on the repository using the Daisy Query Language.
CollectionManager getCollectionManager();
Returns an instance of CollectionManager, through which you can create, modify and delete document collections.
UserManager getUserManager();
Returns an instance of UserManager, through which you can create, modify and delete users.
The above was just to give a broad idea of the functionality available through the API. For more details, consult the complete JavaDoc of the API.
Writing a Java client application
Let's now look at a practical example.
Here's a list of jars you need in the CLASSPATH to use the remote repository API implementation (this list was last updated for Daisy 1.3-M1):
DAISY_HOME/lib/daisy/jars/daisy-repository-api-1.3.jar DAISY_HOME/lib/daisy/jars/daisy-repository-client-impl-1.3.jar DAISY_HOME/lib/daisy/jars/daisy-repository-spi-1.3.jar DAISY_HOME/lib/daisy/jars/daisy-util-1.3.jar DAISY_HOME/lib/avalon-framework/jars/avalon-framework-api-4.1.5.jar DAISY_HOME/lib/daisy/jars/daisy-repository-common-impl-1.3.jar DAISY_HOME/lib/commons-httpclient/jars/commons-httpclient-2.0-rc2.jar DAISY_HOME/lib/xmlbeans/jars/xbean-20040211.jar DAISY_HOME/lib/daisy/jars/daisy-repository-xmlschema-bindings-1.3.jar DAISY_HOME/lib/concurrent/jars/concurrent-1.3.2.jar DAISY_HOME/lib/commons-logging/jars/commons-logging-1.0.3.jar DAISY_HOME/lib/commons-collections/jars/commons-collections-3.1.jar DAISY_HOME/lib/daisy/jars/daisy-jmsclient-api-1.3.jar DAISY_HOME/lib/jms/jars/jms-1.0.2a.jar
So depending on your own habits, you could set up a project in your IDE with these jars in the classpath, or make an Ant project, or whatever.
Below a simple and harmless example is shown: performing a query on the repository.
package mypackage;
import org.outerj.daisy.repository.RepositoryManager;
import org.outerj.daisy.repository.Credentials;
import org.outerj.daisy.repository.Repository;
import org.outerj.daisy.repository.query.QueryManager;
import org.outerj.daisy.repository.clientimpl.RemoteRepositoryManager;
import org.outerx.daisy.x10.SearchResultDocument;
import java.util.Locale;
public class Search {
public static void main(String[] args) throws Exception {
RepositoryManager repositoryManager = new RemoteRepositoryManager(
"http://localhost:9263", new Credentials("testuser", "testuser"));
Repository repository =
repositoryManager.getRepository(new Credentials("testuser", "testuser"));
QueryManager queryManager = repository.getQueryManager();
SearchResultDocument searchresults =
queryManager.performQuery("select id, name where true", Locale.getDefault());
SearchResultDocument.SearchResult.Rows.Row[] rows =
searchresults.getSearchResult().getRows().getRowArray();
for (int i = 0; i < rows.length; i++) {
String id = rows[i].getValueArray(0);
String name = rows[i].getValueArray(1);
System.out.println(id + " : " + name);
}
System.out.println("Total number: " + rows.length);
}
}
The credentials supplied in the constructor of the RemoteRepositoryManager specify a user to be used for filling the caches in the repository client. This user currently needs to have the Administrator role.
Java client application with Cache Invalidation
For long-running client applications you may want to have the caches of the client invalidated when changes happen by other users. For a code sample of how to create a JMS client and pass it on to the RemoteRepositoryManager, see JMS Cache Invalidation Sample.
For this example to run, you'll need the JMS client implementation jars in the CLASSPATH, in addition to the earlier listed jars:
DAISY_HOME/lib/daisy/jars/daisy-jmsclient-impl-1.3.jar DAISY_HOME/lib/exolabcore/jars/exolabcore-0.3.7.jar DAISY_HOME/lib/openjms/jars/openjms-client-0.7.6.jar
More
It might be interesting to also have a look at the notes on scripting using Javascript, since there essentially the same API is used from a different language.



There are no comments.