https://github.com/stardog-union/pinto
Pinto: A lightweight framework for mapping Java Beans into RDF and back again
https://github.com/stardog-union/pinto
java-bean rdf
Last synced: 19 days ago
JSON representation
Pinto: A lightweight framework for mapping Java Beans into RDF and back again
- Host: GitHub
- URL: https://github.com/stardog-union/pinto
- Owner: stardog-union
- License: apache-2.0
- Created: 2015-03-31T16:22:54.000Z (about 10 years ago)
- Default Branch: develop
- Last Pushed: 2019-12-13T03:09:52.000Z (over 5 years ago)
- Last Synced: 2025-03-30T07:32:28.748Z (21 days ago)
- Topics: java-bean, rdf
- Language: Java
- Size: 174 KB
- Stars: 40
- Watchers: 34
- Forks: 16
- Open Issues: 18
-
Metadata Files:
- Readme: readme.md
- License: COPYING
Awesome Lists containing this project
- awesome-java-rdf - Pinto
- awesome-java-rdf - Pinto
README
# Pinto

Pinto is a Java framework for transforming Java beans into RDF (and back).
The current version is 2.0 as of 2016-06-14. We're using [git flow](http://nvie.com/posts/a-successful-git-branching-model/)
for development.Inspired by [Jackson](https://github.com/FasterXML/jackson) and [Empire](http://github.com/mhgrove/Empire), it aims to
be simple and easy to use. No annotations or configuration are required. If you have a compliant Java bean Pinto will
turn it into RDF.The [rdf4j](http://rdf4j.com) framework is used to represent RDF primitives such as Graph and Statement.
## Building
To create the artifacts:
```bash
$ gradle jar
```And to run the tests:
```bash
$ gradle test
```## Example Usage
Given this simple Java Bean:
```java
public static final class Person {
private String mName;public Person() {
}public Person(final String theName) {
mName = theName;
}public String getName() {
return mName;
}public void setName(final String theName) {
mName = theName;
}@Override
public int hashCode() {
return Objects.hashCode(mName);
}@Override
public boolean equals(final Object theObj) {
if (theObj == this) {
return true;
}
else if (theObj instanceof Person) {
return Objects.equal(mName, ((Person) theObj).mName);
}
else {
return false;
}
}
}
```You can easily serialize it as RDF:
```java
Graph aGraph = RDFMapper.create().writeValue(new Person("Michael Grove"));
```And `aGraph` serialized as NTriples:
```
"Michael Grove"^^ .
```And if you have that RDF, you can turn it back into a `Person`:
```java
final Person aPerson RDFMapper.create().readValue(aGraph, Person.class)
```This is the quick and dirty example, but for more detailed examples, check out the tests.
## Annotations
Pinto does not require annotations to serialize Beans as RDF, but does support a few basic annotations so you can
control how the object is serialized.### `@RdfId`
An annotation which specifies the properties to be used for generating the URI of the object. By default, a hash of
the object itself is used to generate a URI. But when present on a getter or setter of one or more properties on the
bean, the values of those properties will be used as the seed for the URI.Note: There is a secondary mechanism for controlling the URI of an object. If the object implements `Identifiable` the
mapper will use the URI returned by `#id` ignoring any `@RdfId` annotated properties.### `@RdfProperty`
An annotation which can be applied to a property on a bean, either the getter or the setter, which specifies the
URI of the property when generating RDF for the bean. Normally, a URI for the property is auto-generated, but when
this annotation is present, the URI specified in the annotation is used instead. The value of the annotation can also
be a QName.### `@RdfsClass`
An annotation which can be applied to a class to specify the `rdf:type` of the class when generating the RDF. Can be
a QName or a URI. When not present, no `rdf:type` assertion is generated for the object.### `@Iri`
Annotation which can be used to control the URI assigned to an `Enum`. Normally the URI's are generated by Pinto, but
if you want to map them to specific constants in your ontology, you can use `Iri` to explicitly identify the objects.```java
public enum TestEnum {
@Iri("urn:my_ontology:test:Foo")
Foo,@Iri("urn:my_ontology:test:Bar")
Bar,
}
```## Configuration
By default, `RDFMapper` does not require any configuration, it's meant to generate reasonable RDF out of the box. There
are a couple (de)serialization options which are specified by `MappingOptions`:* `REQUIRE_IDS` - By default, Pinto will auto-generate URIs for objects when `@RdfId` is not specified. By setting this property to `true` the mapper will not auto-generate URIs, they must be specified explicitly. (default: `false`)
* `SERIALIZE_COLLECTIONS_AS_LISTS` - When true, collections are serialized as RDF lists. Otherwise, they're serialized using `Collection#size` separate property assertions. (default: `false`)
* `IGNORE_INVALID_ANNOTATIONS` - Whether or not to ignore an annotation which is invalid, such as `@RdfProperty` which defines a property with an invalid URI. Properties with invalid/ignored annotations are simply not used when generating a Bean or RDF. (default: `true`)Beyond these configuration options, `RDFMapper` has a few other configuration mechanisms that can be specified on its
`Builder` when creating the mapper:* `#map(URI, Class)` - Specify the provided type corresponds to instances of the given Java class. Functions like the `@RdfsClass` annotation.
* `#namespace(...)` - Methods to specify namespace mappings which are used to expand any QNames used in the annotations
* `#valueFactory(ValueFactory)` - Provide the `ValueFactory` to be used when creating RDF from a bean
* `#collectionFactory(CollectionFactory)` - The factory to be used for creating instances of `java.util.Collection`. Defaults to `DefaultCollectionFactory`
* `#mapFactory(MapFactory)` - The factory to be used for creating instances of `java.util.Map`. Defaults to `DefaultMapFactory`## Custom serialization
In some cases, an object won't adhere to the Java Bean specification, or it's a third-party class that you don't control
so you cannot add annotations, but you need a specific serialization. For these cases `RDFCodec` can be used. It's
a small plugin to `RDFMapper` which will handle transforming a Java object to/from RDF. Pinto includes an example
implementation of a codec for `java.util.UUID` called `UUIDCodec`.Codecs are registered when the `RDFMapper` is created via its builder: `Builder.codec(Class, RDFCodec)`
## Why Pinto?
Why create Pinto when there are similar frameworks available? Well, the other frameworks, like
[Empire](http://github.com/mhgrove/Empire) or [Alibaba](https://bitbucket.org/openrdf/alibaba) are focused on more than
just transforming Beans into RDF and back. Neither are a good fit for _just_ round-tripping between beans and RDF.A good example is if you're building a JAX-RS based web service and you have some bean in your domain that you'd like
to serialize as RDF, or accept as RDF, that's normally done with a custom implementation of
`MessageBodyReader`/`MessageBodyWriter`. But that implementation is not straight-forward with the heavier-weight
frameworks. With Pinto, it's a single line of code.