Collection-JSON-parser is a small library for reading and writing JSON in collection+json (from @mamund) format. It was born because I wanted to build a prototype for the office and was in need of pet-project.
The library provides a Java model for Collections
, Queries
, Tempaltes
, Items
and Data from Cj. Futhermore it provives a
Serializer` which converts any of the above mentioned classes to and from JSON.
For people building a client that uses Cj, the library provides a CjClient
which takes care of building requests
and parsing responses. Users will need to implement a small HTTPClient
which is used by the CjClient
to handle
communication.
To make building of Collections
easier, a set of builders are provided, such as
CollectionBuilder
DataEntryBuilder
andDataEntryFactory
ErrorBuilder
ItemBuilder
LinkBuilder
TemplateBuilde
Finally, to convert between Items
in a Collection
and your domain model, the library makes use of Transformers
.
There are two ways of getting the library:
Simply clone the repository
git clone https://github.com/felipesere/collection-json-parser.git
and then build it with Maven
maven clean install
Or add the following as a repositry to your pom:
<repositories>
<repository>
<id>github-mvn-repo</id>
<url>https://raw.github.com/felipesere/collection-json-parser/mvn-repo/</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
Finally, you need to add it as a dependency to your Maven project using the following coordinates
<dependency>
<groupId>de.fesere.hypermedia</groupId>
<artifactId>collection-json-parser</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
Then you can proceed to create your own Collections or read them from Strings.
The tests in /src/main/test/java
mostly show how to use the library.
In a gist, the usage pattern is the following:
If you receive a String
containing a Collection
in JSON, you can serialize it as such:
String json = "{...}";
Serializer serializer = new Serializer();
Collection collection = serializer.deserialize(json, Collection.class);
If you then want to extract the Items
and convert them to some domain object, e.g. Foo
,
you have to implement the ReadTransformer<T>
interface and pass it to the convert method:
FooTransformer fooTransformer = new FooTransfomer();
List<Foo> foos = collection.transform(fooTransformer);
The implementation of FooTransformer
get each Item
of the Collection
one at a time.
It should use the methods on Item
to extract values.
The methods are:
getString(String name)
to get aString
valuegetInt(Stirng name)
to get anint
getDouble(String name)
to get adouble
getBoolean(String name)
to get aboolean
getObject(String name)
to get the value independent of its typeisNullValue(String name)
to check whether a value isnull
(the JSON type)
These methods throw an ElementNotFoundException
if no element named name
is found
and both getInt
and getDouble
throw a MalformedDataValueException
if the value
can not be properly converted.
Writing a Collection
is fairly easy.
Simply use the differnet builders in de.fesere.hypermedia.cj.model.builder
to construct the differnet objects.
For example, if you want to create a Collection
with a single Item
and two Links
, you could the follwing
CollectionBuilder collectionBuilder = new CollectionBuilder(URI.create("http://example.com"));
collectionBuilder.getLinkBuilder().addLink("documentation","/documentation/v1")
.addLink("questions", URI.create("http://stackoverflow.com")).build();
ItemBuilder itemBuilder = new ItemBuilder(URI.create("http;//example.com/item/1"));
itemBuilder.addData(DataEntryFactory.create("name", "Bob", "Users first name"));
itemBuilder.addData(DataEntryFactory.create("age", 24, "Users age"));
itemBuilder.addData(DataEntryFactory.create("height", 0.00192, "Users height in km"));
itemBuilder.addData(DataEntryFactory.create("payed", false, "User payed fee"));
Collection collection = collectionBuilder.addItem(itemBuilder.build()).build();
Serializer serializer = new Serializer();
System.out.println(serializer.serialize(collection));
The DataEntry
can be any of
StringDataEntry
to addString
to the data of an entity/templateNumberDataEntry
to add anything that implements the JavaNumber
interface, such asint
anddouble
BooleanDataEntry
to add aboolean
to the item/templateNullDataEntry
to add an explicitnull
value to the item/temaplate
You should use the DataEntryFactory
method for simplicty.
It offers methods for creating regular DataEntry
objects, as well as NullDataEntries
and EmptyDataEntries
.
The EmptyDataEntry
has a name and possibly a prompt, but no value. It is especially usefull for Templates
.
The Java code from above results in
{
"collection": {
"version": "1.0",
"href": "http://example.com",
"links": [
{
"rel": "documentation",
"href": "http://example.com/documentation/v1"
},
{
"rel": "questions",
"href": "http://stackoverflow.com"
}
],
"items": [
{
"href": "http;//example.com/item/1",
"data": [
{
"name": "name",
"value": "Bob",
"prompt": "Users first name"
},
{
"name": "age",
"value": 24,
"prompt": "Users age"
},
{
"name": "height",
"value": 0.00192,
"prompt": "Users height in km"
},
{
"name": "payed",
"value": false,
"prompt": "User payed fee"
}
]
}
]
}
}
I try to follow the Git flow model by having a master and a develop branch. Please branch from the develop branch and send me pull requests.
Currently there is no differnce between master and develop, but this will change once there are stable releases.
Branch | Status |
---|---|
Development | |
Master: |