Developer:MyJPI

From myExperiment
Revision as of 16:20, 20 July 2008 by MarkBorkum (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The myExperiment Java API (MyJPI) is a thin wrapper around the myExperiment REST API written in Java and maintained by Mark Borkum. The library is current in beta status and will be available from Autumn 2008.

Features

MyJPI provides Java classes which wraps the DOM entities returned by the myExperiment REST API.

  • XML elements have equivalent Java classes
  • XML attributes have equivalent Java methods

In addition to the thin wrapper, MyJPI provides the following additional functionality:

  • REST calls have equivalent static Java methods
  • Transparent object caching (improves execution speed and minimises bandwidth usage)
  • HTTP connection pooling
  • User authentication (with a secure credentials storage system)
  • XML builders interface for custom Java objects
  • Java dot "." notation for nested objects

Singleton Classes

MyJPI uses two singleton classes (a singleton class is instantiated exactly once per session), ObjectBroker and ObjectCache.

ObjectBroker

The Object Broker class provides the core HTTP and XML processing functionality that is used by all MyJPI classes. The broker delegates XML processing tasks to the appropriate class at runtime using the Java Reflection API. Finally, the broker provides Java methods which implement the the REST functions in the myExperiment REST API.

find

 /**
  * Returns an instance of a Java class which corresponds to the supplied URI.
  * @param klass  Java class (e.g. User.class)
  * @param uri  myExperiment REST object URI (e.g. http://www.myexperiment.org/user.xml?id=10&all_elements=yes)
  * @return  instance of Java class if found, otherwise returns null
  */
 public MyObject find(Class klass, String uri) {
   ...
 }

The find method takes 2 parameters, a Java klass and a URI. The URI is retrieved using an HTTP-GET request. If the request has a 200 status code, the response is passed to the XML builder for the supplied Java class. The following code uses the broker to obtain an instance of User #10 [1]:

 User user = (User) ObjectBroker.getObjectBroker().find(User.class, "http://www.myexperiment.org/user.xml?id=10&all_elements=yes");

All MyJPI classes provide two utility methods as a shorthand for the above:

 User user = User.find("http://www.myexperiment.org/user.xml?id=10&all_elements=yes"); // find by URI
 User user = User.find(10); // find by ID
Listing my friends

After obtaining the root (the object obtained using the find method), all nested objects are available using Java dot "." notation:

 public static void main(String[] args) {
   User user = User.find(10);
   for (User friend : user.getFriends()) {
     System.out.println(user.getName() + " is friends with " + friend.getName());
   }
 }

Running the Java code shown above prints the following result to the output stream:

 $> java MyJPIUserTest.class
 Mark Borkum is friends with Carole Goble
 Mark Borkum is friends with David De Roure
 Mark Borkum is friends with David R Newman
 Mark Borkum is friends with David Withers
 Mark Borkum is friends with Don Cruickshank
 Mark Borkum is friends with Franck Tanoh
 Mark Borkum is friends with Frank Terpstra
 Mark Borkum is friends with Jiten Bhagat
 Mark Borkum is friends with Marco Roos
 Mark Borkum is friends with Matt Lee
 Mark Borkum is friends with Paul Fisher

findAll

 /**
  * Returns a list of myExperiment object URIs.
  * @param klass  Java class (e.g. User.class)
  * @param options  3-dimensional object array of options (e.g. new Object[][] { { "tag", "qrcode" } })
  * @return  list of myExperiment object URIs if successful, otherwise returns null
  */
 public ArrayList<String> findAll(Class klass, Object[][] options) {
   ...
 }

The findAll method takes 2 parameters, a Java klass and an array of options:

  • num (Integer) - the number of results
  • page (Integer) - selected page numbed (used for pagination)
  • tag (String) - optional tag
  • sort (String) - order results by title, created, updated (or name if appropriate)
  • order (String) - use reverse to reverse the results
Top 10 latest users

The list of myExperiment User URIs is obtained by passing an options array to the findAll method of the User class. The results are passed to the find method of the User class in order to obtain an ordered list of User objects:

 ArrayList<User> users = 
   User.find(
     User.findAll(
       new Object[][] { 
         { "sort", "created" }, { "order", "reverse" }, 
         { "num", 10 }, { "page", 1 } 
       }
     )
   );
 System.out.println("Top 10 Latest Users");
 for (int i = 0; i < users.size(); ++i) {
   System.out.println((i + 1) + ": " + users.get(i).getName());
 }

Running the Java code shown above prints the following result to the output stream:

 Top 10 Latest Users
 1: http://rockmonaco.myopenid.com/
 2: http://alesicoli.myvirgilio.it/
 3: Megan Squire
 4: http://pwaring.myopenid.com/
 5: Yanbo
 6: rjoy
 7: ds10
 8: Woloski
 9: clockwork59
 10: Hamid nazarian

ObjectCache

The Object Cache is a minimal Java cache. The caching functionality is encapsulated in this class in order to minimise the costs of switching to an industry grade cache.

keySet

The keySet method returns the set of myExperiment object URIs which are cached at that moment in the execution trace. The following code prints the URIs of all cached objects:

 System.out.println("Cached " + ObjectCache.getObjectCache().keySet().size() + " URIs!");
 for (String uri : ObjectCache.getObjectCache().keySet()) {
   System.out.println(uri);
 }

Abstract Classes

Error creating thumbnail: Unable to save thumbnail to destination
The Announcement class is obtained using the find method. The author attribute returns an instance of the User class.

MyJPI provides 2 abstract Java classes, MyObject and MyBuilder that are implemented by all MyJPI object classes.

MyObject

The MyObject abstract class requires sub-classes to implement 4 methods:

  • getBuilder - returns the MyBuilder implementation for this class
  • getURI - returns the URI for the class
  • getNodeName - returns the DOM node name used by this class in REST function calls for find methods
  • getCollectionName - returns the DOM node name used by this class in REST function calls for findAll methods
 <collectionName>
   <nodeName uri="http://www.myexperiment.org/nodeName.xml?id=1" 
             resource="http://www.myexperiment.org/collectionName/1" />
 </collectionName>

MyBuilder

The MyBuilder abstract class requires sub-classes to implement a single method:

  • build - parses the supplied XML document and returns an instance of a myExperiment Java object

The MyBuilder class also provides static utility methods which can be used to extract common data-types and attributes from the XML document.