s.im.pl serialization tutorial
java mono-morphic

Getting Started:
Introduction

In this tutorial we give a brief example of how S.IM.PL serialization can be used to translate between xml and java annotated classes. The particular xml scheme that this example focuses on is RSS.

To view this tutorial you will need to download the entire simplTutorials, simplTranslators and ecologylabFundamental projects. Access to the ecologylab fundamental project source is available through anonymous SVN access (user: anonymous, password: anonymous).

The source for this tutorial is located under /trunk/simplTutorials/src/tutorials/

Java Annotated Classes

The following are the set of classes defined to represent the Rss xml structure. Note that each of these classes extends ElementState, which is the root class of all classes that intend to use translation. In addition to being a subclass of ElementState, each class has an annotated set of fields. These fields can either be translated into attributes of the class's tag or into elements nested within the class element.

Rss is the definition for the root Rss element. It contains a single scalar version, which is annotated by @simpl_scalar, and composite element Channel, annotated by @simpl_composite. It is important to note that class names and field names are associated with tags and attributes in the xml based on a default translation. In the case of Rss, s.im.pl serialization uses the part of the name prior to "State" by default.

//Rss.java

package ecologylab.tutorials.rss;

import ecologylab.serialization.ElementState;

public class Rss extends ElementState
{
  @simpl_scalar  float    version;
  @simpl_composite    Channel    channel;

  public Rss() {}
}


Now we'll take a look at Channel, the composite component of Rss. Channel has several sub-elements. These sub-elements are all of types that we refer to as scalar. So in this case to specify that they are sub-elements rather than attributes we use the @simple_hints(Hint.XML_LEAF) annotation.

In addition, channel contains a collection. This is a collection of "items". In Rss, this collection is not contained within a seperate element. For this reason, we specify the @simpl_nowrap annotation, which indicates that the collection should not be contained within a sub-element. The @simpl_collection("item") annotation specifies two things. First, it specifies that the collection items should be translated. Second, it associates a tag name of "item" with the collection. This ensures that the translated elements of items have the tag name "item".

//Channel.java

package ecologylab.tutorials.rss;

import java.util.ArrayList;
import ecologylab.net.ParsedURL;
import ecologylab.serialization.ElementState;

public class Channel extends ElementState
{
   @simpl_scalar @simpl_hints(Hint.XML_LEAF) String    title;
   @simpl_scalar @simpl_hints(Hint.XML_LEAF) String    description;
   @simpl_scalar @simpl_hints(Hint.XML_LEAF) ParsedURL  link;
   
   @simpl_nowrap
   @simpl_collection("item"
   ArrayList<Item>     items;
   
   public Channel() { }

   public ArrayList<Item> getItems() 
   {
     return items;
   }
}


Finally, we define the item class. An item has several sub elements, each of which is a leaf. An item may also have a collection of category elements. Here we use the same annotation as before with items.

//Item.java

package ecologylab.tutorials.rss;

import java.util.ArrayList;
import ecologylab.net.ParsedURL;
import ecologylab.serialization.ElementState;

public class Item extends ElementState
{
   @simpl_scalar @simpl_hints(Hint.XML_LEAF) String      title;
   @simpl_scalar @simpl_hints(Hint.XML_LEAF) String      description;
   @simpl_scalar @simpl_hints(Hint.XML_LEAF) ParsedURL    link;
   @simpl_scalar @simpl_hints(Hint.XML_LEAF) ParsedURL    guid;
   @simpl_scalar @simpl_hints(Hint.XML_LEAF) String      author;
   
   @simpl_nowrap
   @simpl_collection("category"
   ArrayList<String>    categorySet;
   
   public Item() {}
}
Translation Scopes

Translation scopes are used to specify the set of classes available for translation when translating from xml. Here we define a class with a static method that returns a translation scope referencing all of the Rss classes: Rss, Channel, and Item.

//RssTranslations.java

package ecologylab.tutorials.rss;

import ecologylab.generic.Debug;
import ecologylab.serialization.TranslationScope;

public class RssTranslations extends Debug
{
   public static TranslationScope get()
   {
     return TranslationScope.get("rss", Rss.class, Channel.class, Item.class);
   
}
Translating XML

In order to translate from XML we must acquire the proper translation scope.

public static void main(String[] argsthrows IOException,
      XMLTranslationException
  {
    
    TranslationScope rssTranslations = RssTranslations.get();

Next we'll read in the Rss feed for a comparison with the translated version.

    URL url = new URL("http://www.xkcd.com/rss.xml");
    String rssContent = readURL(url);

    System.out.println("Raw RSS Feed:");
    System.out.println(rssContent);

Now we'll translate the xml feed into an Rss object and then translate back to xml. Notice how if there are parts of the xml that are not annotated with the classes that they are simply ignored. In this case channel's language element and item's pubDate element.

    Rss feed = (RssrssTranslations.deserialize(url);
    
    System.out.println("\nFeed translated back to xml by s.im.pl serialization:");
    System.out.println(feed.serialize());

In this last section we will create our own channel item and then put it in the Rss feed. Note we can just create an instance of item and set all of it's instance variables to the values that we wish. Then we just add the new item to the channel's list of items and translate back to xml.

    Item ecologylabItem = new Item();
    ecologylabItem.setTitle("The Interface Ecology Lab");
    ecologylabItem
        .setDescription("Highlights the cool research going on at the lab.");
    ecologylabItem.setAuthor("Dr. Andruid Kerne");
    ecologylabItem
        .setLink(new ParsedURL(new URL("http://www.ecologylab.net")));

    feed.getChannel().getItems().add(0, ecologylabItem);

    System.out.println("\nFeed translated to xml with our added item:");
    System.out.println(feed.serialize());
  }
an interface ecology lab production