Skip to content
Harald Pehl edited this page Oct 29, 2012 · 1 revision

References in Piriti

<wiki:toc max_depth="2" />

References in Java

When a reader / writer is instantiated it is registered against a global registry. Therefore references to other types that also have a reader / writer are recognized and mapped: public class Book { interface BookReader extends XmlReader {} public static final BookReader XML = GWT.create(BookReader.class);

    String name;
    Author author;
}
public class Author
{
    interface AuthorReader extends XmlReader<Author> {}
    public static final AuthorReader XML = GWT.create(AuthorReader.class);

    String firstname;
    String surname;
}

When reading a book from JSON / XML which also contains author information, the author is mapped and assigned to Book.author.

Requirements

In order to use references the following condition must be met: All readers / writers of types which make up the references must be initialized before the first reader / writer is used.

In the above example !AuthorReader has to be initialized before !BookReader.read() is called. Initialized means the call of GWT.create() has to happen. As long as you declare your reader / writer instances as static members, Piriti will take care of this. Once you have your reader / writer instances outside of your POJO, you have to take care of the initialization by yourself: public class Book { String name; Author author; } public class Author { String firstname; String surname; } public interface BookReader extends XmlReader {} public interface AuthorReader extends XmlReader {} public final class Readers { public static final BookReader BOOK_READER = GWT.create(BookReader.class); public static final AuthorReader AUTHOR_READER = GWT.create(AuthorReader.class);

    // Just there to have a method to call, load the class and trigger GWT.create() calls
    public void initialize() {}
}
public class AppEntryPoint implements EntryPoint
{
    public void onModuleLoad()
    {
        Readers.initialize();
        ...
    }
}

Whenever possible I strongly recommend to use GIN to create and initialize your reader / writer instances. Doing so you can be sure that all readers / writers are initialized and registered before you (de)serialize your first POJO.

Polymorphic References

Piriti supports the mapping of polymorphic references as shown in the following example (reader definitions omitted) { "mediums": [ { "id": "isbn-978-0345417954", "title": "The Hotel New Hampshire", "pages": 432 }, { "id": "cd-1234", "title": "Stadium Arcadium", "tracks": 28 }, { "id": "dvd-5678", "title": "Reservoir Dogs", "duration": 99 } ] } public class Library { List mediums; }

public abstract class Medium
{
    String id;
    String title;
}

public class Book extends Medium
{
    int pages;
}

public class Cd extends Medium
{
    int tracks;
}

public class Dvd extends Medium
{
    int duration;
} 

In order to map the medium list in Library, Piriti has to know how to create concrete instances of Medium subclasses. Therefore you have to specify an InstanceCreator for the list using the @!CreateWith annotation: public class Library { @CreateWith(MediumCreator.class) List mediums; } public class MediumCreator extends JsonInstanceCreator { @Override public Medium newInstance(JSONValue context) { Medium medium = null; JSONObject jsonObject = context.isObject(); if (jsonObject != null) { JSONValue idValue = jsonObject.get("id"); if (idValue != null) { JSONString idString = idValue.isString(); if (idString != null) { String id = idString.stringValue(); if (id.startsWith("isbn-")) { medium = new Book(); } else if (id.startsWith("cd-")) { medium = new Cd(); } if (id.startsWith("dvd-")) { medium = new Dvd(); } } } } return medium; } }

The important part here is that you need an indicator in your JSON / XML data to decide which instance to create. Otherwise polymorphic references wonn't work.

Clone this wiki locally