[[S5(theme=pixel)]] View this as a [../s5/OtmOverview?theme=pixel presesentation] (requires javascript). = Topaz Overview = == Contents == * Motivations * What is Topaz? * Simple Example * Mapping to RDF * Handling Blobs == Motivations == * We are using RDF to store all the application's data (except for Blob's) * Need to insert, remove, update, and query for objects, not just individual triples * Writing TQL by hand becomes really tedious really quickly * Writing TQL by hand is error prone and brittle == What is Topaz? == * An Object-Triples-Mapping library * Modeled on [http://www.hibernate.org/ Hibernate] * Define Java classes and annotate them to describe mapping into RDF * Provides automatic persistence and retrieval of objects as a whole * Provides a higher-level query languages ([wiki:Topaz/Manual/Section11 Oql] and Criteria) based on objects * Provides support for storing Blob's to a separate Blob store == Simple Example == Annotated java class (definition of ''Account'' not shown here): {{{ #!java @Entity(types = {"foaf:Person"}, model = "people") public class Person { private URI id; private String name; private Account acc; private URI blog; @Id public void setId(URI id) { this.id = id; } public URI getId() { return id; } }}} == Simple Example (Continued) == {{{ #!java @Predicate(uri = "foaf:name") public void setName(String name) { this.name = name; } public String getName() { return name; } @Predicate(uri = "foaf:holdsAccount") public void setAcc(Account acc) { this.acc = acc; } public Account getAcc() { return acc; } @Predicate(uri = "foaf:weblog") public void setBlog(URI blog) { this.blog = blog; } public URI getBlog() { return blog; } } }}} == Simple Example (Continued - usage) == Work with it: {{{ #!java Session sess = sessFactory.openSession(); Transaction txn = sess.beginTransaction(); Person p1 = new Person(...); sess.saveOrUpdate(p1); Person p2 = sess.get(Person.class, "http://some.org/people/john"); Results r = sess.createQuery( "select p from Person p where p.name = 'John Bentley';") .execute(); while (r.next()) Person p = r.get("p") txn.commit(); }}} == Simple Example Explained == `` {{{ #!java @Entity(type = {"foaf:Person"}, model = "people") public class Person { public URI id; private String name; private Account acc; private URI blog; }}} `` * `@Entity` marks the class as eligible for persistence * `type` specifies a list of rdf types * `model` specifies the model (named graph) in which instances are to be stored and found * The private internal fields are not annotated, unlike in releases up to 0.9. == Simple Example Explained (Continued) == `` {{{ #!java @Id public void setId(URI id) { this.id = id; } public URI getId() { return id; } }}} `` * `@Id` marks the setter of the field that holds the id (subject-uri) of the instance == Simple Example Explained (Continued) == `` {{{ #!java @Predicate(uri = "foaf:name") public void setName(String name) { this.name = name; } public String getName() { return name; } @Predicate(uri = "foaf:holdsAccount") public void setAcc(Account acc) { this.acc = acc; } public Account getAcc() { return acc; } @Predicate(uri = "foaf:weblog") public void setBlog(URI blog) { this.blog = blog; } public URI getBlog() { return blog; } }}} `` * `@Predicate` marks the setter of a field that gets mapped to an RDF property. This annotation configures how the field is mapped to RDF statements * `uri` specifies the predicate-uri the field maps to * the field type determines whether the field value is stored as a literal or a URI, based on a (configurable) list of serializers == Mapping to RDF == Java (application) code: {{{ #!java Person p1 = new Person(); p1.id = new URI("my:id1"); p1.name = "John Bentley"; p1.blog = new URI("http://cool.blogs.com/john"); p1.acc = new Account(new URI("my:accnt1"), "jbentley"); sess.saveOrUpdate(p1); }}} continued... == Mapping to RDF (continued) == Resulting RDF (in N-Triples format): {{{ . "John Bentley" . . . . "jbentley" . }}} == Handling Blobs == `` {{{ #!java @Entity(type = "foaf:Person", model = "people") public class Person { @Id public void setId(URI id) { this.id = id; } ... @Predicate(uri = "foaf:img") public Image pic; } @Entity(type = "foaf:Image", model = "people") public class Image { private URI id; private byte[] data; @Id public void setId(URI id) { this.id = id; } public URI getId() { return id; } @Blob public void setData(byte[] data) { this.data = data; } public byte[] getData() { return data; } } }}} == Handling Blobs (Continued) == Work with it - just like other fields and classes: {{{ #!java Session sess = sf.openSession(); Transaction txn = sess.beginTransaction(); Person p1 = new Person(...); p1.pic = new Image(); p1.pic.id = ... p1.pic.data = ... sess.saveOrUpdate(p1); Person p2 = sess.get(Person.class, "http://some.org/people/john"); display(p2.pic.data); txn.commit(); }}} == Handling Blobs Explained == `` {{{ #!java @Entity(type = "foaf:Image", model = "people") public class Image { private URI id; private byte[] data; @Id public void setId(URI id) { this.id = id; } public URI getId() { return id; } @Blob public void setData(byte[] data) { this.data = data; } public byte[] getData() { return data; } } }}} `` * `@Blob` marks the setter for the field that holds the "contents" of the object; that is, the @Id field is (also) the id of the blob in the blob-store. For this reason only one field in a class may be marked with `@Blob`. == Handling Blobs Explained (continued) == * Two types of blobs can be annotated using @Blob * byte[] or UTF-8 encoded String where the entire blob contents is copied over to the field. * org.topazproject.otm.Blob or javax.activation.!DataSource or java.io.!InputStream are managed streamable blos * For managed streamable blobs, Topaz Session is the factory class. An application cannot create an instance of the Blob and set the field value. * An entity may contain both `@Predicate` fields as well as an `@Blob` field - for a use-case see http://esw.w3.org/topic/ImageDescriptionRdfExamples .