Omeka REST API, Spring's RestTemplate and Jackson JSON library (part 2)

A bit of a learning curve, so there is, with regard to converting the retrieved JSON to Java objects (Plain Old Java Objects / POJOs — Spring beans). The building block of Omeka’s JSON documents is the Element. This seems to be based on Dublin Core metadata element sets, but does not seem to be a complete implementation. I still have to get my head around that side of things.

Each element can have up to 7 fields, one of which is a composite element_set containing 3 fields. This is from the Omeka documentation on the Element document:

{
  "id": 1,
  "url": "http://yourdomain.com/api/elements/1",
  "name": "Text",
  "order": 1,
  "description": "Any textual data included in the document",
  "comment": null,
  "element_set": {
    "id": 1,
    "url": "http://yourdomain.com/api/element_sets/1",
    "resource": "element_sets"
  },
}

Each element would appear to match up with Dublin Core elements, such as Title, Subject and Description. For example:

{
  "id": 41,
  "url": "http://192.168.1.17/api/elements/41",
  "name": "Description",
  "resource": "elements"
}

Omeka, it appears, only returns 4 fields for an element – at least in the example I have on my previous post.

If I want to add some text for an element, I need to use an Element Text document, within which is embedded the relevant Element document, as well as an Element Set document, which will almost certainly be a reference to Dublin Core’s element set – though it opens up the possibility for an alternative to Dublin Core metadata. The example below adds the description “Test Description” to an item or collection:

{
   "html": false,
   "text": "Test Description",
   "element_set": {
      "id": 1,
      "url": "http://192.168.1.17/api/element_sets/1",
      "name": "Dublin Core",
      "resource": "element_sets"
   },
   "element": {
      "id": 41,
      "url": "http://192.168.1.17/api/elements/41",
      "name": "Description",
      "resource": "elements"
   }
}

For now I have decided to base my Java classes (used in my Android app) on the fields in retrieved documents using Omeka’s REST API. Here are the classes required for an Element Text (with getters and setters left out to save on reading time):

public class ElementText {
  private boolean isHtml;
  private String text;
  private ElementSet elementSet;
  private Element element;

  // insert getters and setters
}
public class ElementSet {
  private int id;
  private String url;
  private String name;
  private String resource;
  private int order;
  private String description;
  private String comment;

  // insert getters and setters
}
public class Element {
  private int id;
  private String url;
  private String name;
  private String resource;
  private int order;
  private String description;
  private String comment;

  // insert getters and setters
}

Here is the Item class:

public class Item {
  private int id;
  private String url;
  private boolean isPublic;
  private boolean isFeatured;
  private Date added;
  private Date modified;
  Element itemType;
  Element collection;
  Element owner;
  Files files;
  List<Element> tags;
  List<ElementText> elementTexts;

  // insert getters and setters
}

The Files class seems to just contain the number of files and a link to where the files can be retrieved.

public class Files {
    private int count;
    private String url;
}

Now comes the hard part… the parsing from JSON and the creation of the Java objects from the JSON. I hope Spring and Jackson provide some help along the way! Let’s see what happens in part 3.

Omeka REST API, Spring’s RestTemplate and Jackson JSON library (part 1)

I had considered building my own collections management system. This would have had some advantages, but several disadvantages. The main disadvantage would have been time. Another would be the need to know the standards inside out – e.g. properly implementing / adhering to Dublin Core metadata standards.

It wasn’t difficult to find a collections management system that would provide the basis for my own collections (and those of any partner museums / galleries along the way). Omeka has some definite advantages: it is open source, so I can see why things happen the way they do and modify if necessary; it is extensible with plugin development “hooks”; it has some similarities in its philosophy with WordPress, the world’s most installed content management and blogging system; it is moving to the Zend framework – not my framework of choice, but one that is widely used and thus provides access to simplified APIs; it has a decent community of support around it.

I initially tried setting everything up myself with Omeka – I created a VirtualBox Ubuntu virtual server and eventually got it working, though there was a lot of flapping around with Apache and modrewrite. Later, though, I discovered a Turnkey Linux Omeka install. While it is possible to install the operating system (Debian Linux), apache, PHP, MySQL, and Omeka, from a downloaded ISO image (once burned to CD or mounted directly while starting a virtual server), the easiest approached is to download the VMDK disk image and use that when creating a Linux virtual server with VirtualBox or VMWare. These Turnkey Linux images tend to be cut down to almost the bare minimum. The Omeka one is a headless server – that is, there is no desktop with mouse and pointer. It only takes up 238 MB of space and can run with a fairly small memory footprint – easily under 512MB. Whether or not I would use one of the Turnkey Linux images for a production server, I am not sure – might need more optimisation – but for development purposes it is perfect. I can have many instances of Omeka installed and run the ones I want.

The Turnkey Linux Omeka image was only at version 2.0.1, but was easily upgraded to the latest version (2.1.4).


Spring for Android provides support for, amongst other things, Spring’s RestTemplate class. This allows an Android app to connect to a REST API and retrieve resource data in some representation or other. In the case of Omeka, from version 2.1 there is support for REST with JSON documents returned. The REST API is turned off by default and must be explicitly turned on in Omeka’s admin control panel. In addition, only items and collections marked as public will be returned to a REST API request.

The following is an example of a JSON document returned from a request to http://192.168.1.17/api/items/1 (running in a VirtualBox virtual server on my Linux PC):

{"id":1,"url":"http://192.168.1.17/api/items/1","public":true,"featured":false,"added":"2014-05-12T20:14:59+00:00","modified":"2014-05-12T20:20:43+00:00","item_type":null,"collection":null,"owner":{"id":1,"url":"http://192.168.1.17/api/users/1","resource":"users"},"files":{"count":0,"url":"http://192.168.1.17/api/files?item=1","resource":"files"},"tags":[],"element_texts":[{"html":false,"text":"Test Title","element_set":{"id":1,"url":"http://192.168.1.17/api/element_sets/1","name":"Dublin Core","resource":"element_sets"},"element":{"id":50,"url":"http://192.168.1.17/api/elements/50","name":"Title","resource":"elements"}},{"html":false,"text":"Test Description","element_set":{"id":1,"url":"http://192.168.1.17/api/element_sets/1","name":"Dublin Core","resource":"element_sets"},"element":{"id":41,"url":"http://192.168.1.17/api/elements/41","name":"Description","resource":"elements"}}],"extended_resources":[]}

Not particularly easy to read, is it? The only data of real interest to my consuming Android app for this particular item is the id number (1), the title (“Test Title”) and the description (“Test Description”). Pretty much everything else can be ignored. Part of the reason it is difficult to read is because each item (our cultural objects are just known as items) is made up of elements. Each field value, such as title, description, creator, and so on, are stored as separate rows in the element_texts table.

It’s a little clearer when the JSON is formatted with proper indentation (e.g. using one of many free sites like http://www.freeformatter.com/json-formatter.html):

{
   "id": 1,
   "url": "http://192.168.1.17/api/items/1",
   "public": true,
   "featured": false,
   "added": "2014-05-12T20:14:59+00:00",
   "modified": "2014-05-12T20:20:43+00:00",
   "item_type": null,
   "collection": null,
   "owner": {
      "id": 1,
      "url": "http://192.168.1.17/api/users/1",
      "resource": "users"
   },
   "files": {
      "count": 0,
      "url": "http://192.168.1.17/api/files?item=1",
      "resource": "files"
   },
   "tags": [],
   "element_texts": [
      {
         "html": false,
         "text": "Test Title",
         "element_set": {
            "id": 1,
            "url": "http://192.168.1.17/api/element_sets/1",
            "name": "Dublin Core",
            "resource": "element_sets"
         },
         "element": {
            "id": 50,
            "url": "http://192.168.1.17/api/elements/50",
            "name": "Title",
            "resource": "elements"
         }
      },
      {
         "html": false,
         "text": "Test Description",
         "element_set": {
            "id": 1,
            "url": "http://192.168.1.17/api/element_sets/1",
            "name": "Dublin Core",
            "resource": "element_sets"
         },
         "element": {
            "id": 41,
            "url": "http://192.168.1.17/api/elements/41",
            "name": "Description",
            "resource": "elements"
         }
      }
   ],
   "extended_resources": []
}

We can see more easily that the owner is the Omeka user with id 1, that there are no connected files (count is 0) and that there are no tags (annotations). There is a sub-document of element_texts which causes some complication. It would be nice if we could drill-down into each element text and immediately see that one is a title, another a description, and so on. What we get, though, is the value first and the element name within a further sub-document (the element). This isn’t insurmountable, but probably means that using automagic to automatically populate Java classes is out of the question (e.g. using RestTemplate’s getForObject… restTemplate.getForObject(url, Item.class);) – though I haven’t ruled this approach out just yet.


So where am I now? I can get the Android app to connect to the Omeka site and retrieve a JSON document for the RESTFul url supplied. However, I have yet to map the retrieved document to my internal Java Item class. Hopefully in part 2 I can get a bit closer to that goal.

Android development – NFC / REST / Android Studio

Since the last post, I submitted a first draft literature review. It wasn’t particularly long and it probably still meanders a bit too much. Since submitting, I have continued to try to narrow my focus. Whereas before I intended to keep the technological augmentation of the museum to a minimum, with electronic id tagging of objects being as far as that went, I have now explored more advanced augmentation with Raspberry Pi and Arduino to the fore, both of which individually or combined provide access to a wide range of sensors and actuators that can be used to build interactive exhibits, for example.

However, the original plan to explore RFID and NFC on Android-enabled mobile devices is continuing. While I have Java experience, I have no Android experience. The Android SDK provides a whole new framework to learn with various files in various locations that you need to become familiar with. I don’t find it nearly as intuitive as getting to grips with a web MVC framework, as I have done recently with Laravel for PHP and Spring MVC for Java. But I am persevering and making slow progress.

There are a number of tools available for Android development. The most commonly-used is Android Developer Tools (ADT) plugin for Eclipse. My first Android adventures began with ADT. However, when I tried to get it working with a package / build manager – specifically Maven – I ran into all kinds of problems. I also tried the new Android Studio, which is still far from stable. Android Studio is built on the IntelliJ platform, which competes with Eclipse. An advantage it does have over ADT/Eclipse is Gradle integration. Gradle provides a package manager to download dependencies, much like you would inside a Project Object Model file (pom.xml) in Maven. I’ve only just started to feel comfortable with Maven and now I have yet another Ant-style tool to learn.

While obviously less stable than the more mature Eclipse + ADT, I am going to persevere with Android Studio. I get the feeling that Google is putting its weight behind it, offering integration with various Google cloud services, such as App Engine, as well as more specific Android features. Gradle also seems to simplify package and build management in comparison to Maven, for example.

In addition, I have been looking at the Spring for Android project. The Spring Framework for Java provides a means of developing applications that provides layers of abstraction for various complex technologies, or technologies with a lot of configuration overhead or that require lots of code to check for errors, etc. For these technologies, Spring simplifies configuration and through something called Aspect Oriented Programming (AOP), reduces the amount of “boilerplate” code needed (i.e. repetitive code that is error prone due to bad habits like copying and pasting). There is also a Spring Mobile project which is not Android specific and instead is for developing cross-platform web-based solutions using Spring MVC. That sounds great on the face of it, but I want to develop a native Android app to ensure I can get the maximum out of the platform and have proper access to hardware features, such as NFC.

I hit a few issues when trying to build even the Hello World project when trying to include Spring libraries. I found a solution here: http://forum.spring.io/forum/spring-projects/android/743289-importing-android-spring-with-gradle-cause-error-mutiple-dex-files

What have I achieved thus far with Android? I added code to read an RF tag. The test tag I used was taken from the plastic bag covering exam papers I had to correct. It contained some simple text data: “DATA8002 – 24012”. That’s the module code and a unique id number identifying the teaching instance of the module. For test purposes, this is all I need. However, as time goes on, I will need to get some fresh RF tags and use an NFC writer to add my own id data. In addition, I will need to get my hands on some more advanced NFC cards so that I can put some user data on there, most likely encrypted.

I was able to test that the device I was using – a Google Nexus 7 tablet – was able to read the data from the tag. The NFC TagInfo Android app allowed me to verify that. Then I found a useful Android NFC tutorial that saved some time: http://code.tutsplus.com/tutorials/reading-nfc-tags-with-android–mobile-17278

The end result isn’t Earth-shattering. I was able to develop a simple app that could intercept NFC tag reads and display data on the screen. The next post will detail how I managed to connect to a collections management system, Omeka, using the REST protocol (thanks to Spring Android) to retrieve Dublin Core-compliant object/item metadata in JSON format for display on my tablet.