Subversion Repositories aduna

[/] [org.openrdf/] [alibaba/] [trunk/] [object-repository/] [src/] [site/] [apt/] [index.apt] - Blame information for rev 11597

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9486 james_leigh
 ----------------------------------------
2 james_leigh
 Object Repository
3 james_leigh
 ----------------
4 james_leigh
 James Leigh
5 james_leigh
 ----------------
6 11597 james_leigh
 Feb 2012
7 9423 james_leigh
 
8 9486 james_leigh
 
9 9419 james_leigh
Object Repository
10 james_leigh
 
11 james_leigh
 The Object Repository is an extension to the Sesame RDF Repository that
12 james_leigh
 allows an RDF store to function as an object store. It maps Java objects
13 james_leigh
 to and from RDF resources and OWL classes to Java classes in a
14 james_leigh
 non-intrusive manner that enables developers to work with resources
15 11450 james_leigh
 stored in an RDF Repository as objects. The Object Repository may also
16 james_leigh
 optionally be configured with a BLOB store, to store information-resources.
17 9419 james_leigh
 
18 james_leigh
 Sesame Repositories can be created using the console. Use the connect
19 james_leigh
 command to set the data directory before creating a repository using the
20 james_leigh
 create command. Once the repository has been created it can be accessed
21 james_leigh
 in Java through the RepositoryProvider's getRepositoryManager(dataDir)
22 james_leigh
 method, which takes the URI of the directory location that was used in
23 james_leigh
 the connect command of the console. Then the repository can be accessed
24 james_leigh
 using the getRepository(id) method of the returned RepositoryManager.
25 james_leigh
 
26 james_leigh
 The ObjectRepository must be created through the
27 james_leigh
 ObjectRepositoryFactory, using the createRepository method, passing an
28 james_leigh
 existing Repository. Once the ObjectRepository is created it is like
29 james_leigh
 other Sesame RDF Repositories, with full triple access, but it returns a
30 james_leigh
 ObjectConnection in the getConnection method. The ObjectConnection is an
31 james_leigh
 extension of the RepositoryConnection and includes additional methods
32 11450 james_leigh
 for working with objects and information-resources. However, before
33 james_leigh
 objects can be used, the object classes must first be created and registered.
34 9419 james_leigh
 
35 11487 james_leigh
 To create classes for the ObjectRepository add the @Iri annotation to
36 9974 james_leigh
 all classes and fields (or interfaces and property methods)
37 james_leigh
 that should be stored in the repository. Then
38 9419 james_leigh
 create an empty 'META-INF/org.openrdf.concepts' file in the root
39 9434 james_leigh
 directory (or JAR) of the annotated classes. Once the
40 9421 james_leigh
 classes have been created, as shown in Figure 5,
41 9419 james_leigh
 they can be used with new ObjectRepositories.
42 james_leigh
 
43 james_leigh
 <<Figure 5. A Class Compatible with the ObjectRepository>>
44 james_leigh
 
45 james_leigh
+--
46 james_leigh
// Document.java
47 11486 james_leigh
import org.openrdf.annotations.Iri;
48 9419 james_leigh
 
49 11487 james_leigh
@Iri(Document.NS + "Document")
50 9419 james_leigh
public class Document {
51 james_leigh
  public static final String NS = "http://meta.leighnet.ca/rdf/2009/gs#";
52 9434 james_leigh
 
53 11487 james_leigh
  @Iri(NS + "title") String title;
54 9434 james_leigh
 
55 james_leigh
  public String getTitle() {
56 james_leigh
    return title;
57 james_leigh
  }
58 james_leigh
  public void setTitle(String title) {
59 james_leigh
    this.title = title;
60 james_leigh
  }
61 9419 james_leigh
}
62 james_leigh
+--
63 james_leigh
 
64 james_leigh
 To add an object to the ObjectRepository, create an ObjectConnection and
65 james_leigh
 call the addObject method (as shown in Figure 6). This method will recursively add all other
66 james_leigh
 objects referenced from annotated fields. The addObject method can
67 james_leigh
 either automatically create a unique identifier for the object (that
68 james_leigh
 might change over time), or add the object using a provided identifier,
69 james_leigh
 called a URI. It is recommended to use a URI for any object that might
70 9973 james_leigh
 need to be referenced directly or has a conceptual identity, for all
71 10951 james_leigh
 other objects, such as anonymous collections, an automatic identifier
72 james_leigh
 may be good enough.
73 9419 james_leigh
 
74 james_leigh
 To retrieve an existing object, use the getObject(Class, Resource)
75 james_leigh
 method of the ObjectConnection. The method accepts a URI or an anonymous
76 james_leigh
 identifier. An anonymous identifier maybe different for different
77 james_leigh
 ObjectConnections and should only be used within a single
78 9434 james_leigh
 ObjectConnection. A URI, however, will never change and can be used in any connection.
79 9419 james_leigh
 
80 james_leigh
 Removing an object is more difficult, as every property of the object
81 james_leigh
 will need to be removed, by setting the fields or properties to null.
82 james_leigh
 Furthermore, the type of the object must also be removed from the
83 james_leigh
 repository, this can be done using the removeDesignation method of the
84 james_leigh
 ObjectConnection.
85 james_leigh
 
86 james_leigh
 <<Figure 6. Using an ObjectConnection>>
87 james_leigh
 
88 james_leigh
+--
89 james_leigh
// create a Document
90 james_leigh
Document doc = new Document();
91 james_leigh
doc.setTitle("Getting Started");
92 james_leigh
 
93 james_leigh
// add a Document to the repository
94 james_leigh
ObjectConnection con = repository.getConnection();
95 james_leigh
ValueFactory vf = con.getValueFactory();
96 james_leigh
URI id = vf.createURI("http://meta.leighnet.ca/data/2009/getting-started");
97 9970 james_leigh
con.addObject(id, doc);
98 9419 james_leigh
 
99 james_leigh
// retrieve a Document by id
100 james_leigh
Document doc = con.getObject(Document.class, id);
101 james_leigh
 
102 james_leigh
// remove a Document from the repository
103 james_leigh
Document doc = con.getObject(Document.class, id);
104 james_leigh
doc.setTitle(null);
105 9970 james_leigh
con.removeDesignation(doc, Document.class);
106 9434 james_leigh
+--
107 james_leigh
 
108 james_leigh
 Objects can also be retrieved by their type using the getObjects(Class)
109 james_leigh
 method, which includes subclasses. More fine grained queries can be
110 11496 james_leigh
 created using the @Sparql annotation. This annotation should be placed
111 james_leigh
 on public or protected methods that have a @Bind annotation on their parameters and have
112 9434 james_leigh
 a return type and parameters types of registered concepts or datatypes.
113 james_leigh
 The return type may also be a java.util.Set or Result of a concept or
114 9624 james_leigh
 datatype and may also be Model and any query result, such as GraphQueryResult,
115 10835 james_leigh
 TupleQueryResult, or boolean. Public and protected methods with this annotation will be
116 9434 james_leigh
 overridden with an optimized object query execution. The parameters with
117 11496 james_leigh
 an @Bind annotation will be available in the query in the variable name
118 9434 james_leigh
 provided. The target object is available in the query using the
119 james_leigh
 variables name "this".
120 9419 james_leigh
 
121 9434 james_leigh
 Dynamic queries can be constructed using the prepareObjectQuery method
122 james_leigh
 or one of the other prepareQuery methods. The prepareObjectQuery method
123 james_leigh
 returns an ObjectQuery that allows objects and their type to be assigned to
124 james_leigh
 variables within the query before execution.
125 james_leigh
 
126 james_leigh
 <<Figure 7. Executing Queries>>
127 james_leigh
 
128 james_leigh
+--
129 james_leigh
 
130 9419 james_leigh
// retrieve all Documents
131 james_leigh
Result<Document> result = con.getObjects(Document.class);
132 james_leigh
while (result.hasNext()) {
133 james_leigh
  out.println(result.next().getTitle());
134 james_leigh
}
135 james_leigh
 
136 11597 james_leigh
import org.openrdf.annotations.Sparql;
137 james_leigh
import org.openrdf.annotations.Bind;
138 james_leigh
 
139 9596 james_leigh
// retrieve a Document by title using a named query
140 11496 james_leigh
@Sparql("PREFIX gs:<http://meta.leighnet.ca/rdf/2009/gs#>\n"+
141 9434 james_leigh
  "SELECT ?doc WHERE {?doc gs:title $title}")
142 11496 james_leigh
public Document findDocumentByTitle(@Bind("title") String title) {
143 9434 james_leigh
  return null;
144 james_leigh
}
145 james_leigh
 
146 11450 james_leigh
// retrieve a Document by title using a named query
147 james_leigh
ValueFactory vf = con.getRepository().getValueFactory();
148 james_leigh
URI myQueryID = vf.createURI("http://meta.leighnet.ca/rdf/2011/my-query");
149 james_leigh
NamedQuery named = con.getRepository().createNamedQuery(myQueryID,
150 james_leigh
  "PREFIX gs:<http://meta.leighnet.ca/rdf/2009/gs#>\n"+
151 james_leigh
  "SELECT ?doc WHERE {?doc gs:title ?title}");
152 james_leigh
 
153 james_leigh
ObjectQuery query = con.prepareObjectQuery(named.getQueryString());
154 james_leigh
query.setObject("title", "Getting Started");
155 11496 james_leigh
Document doc = query.evaluate(Document.class).singleResult();
156 11450 james_leigh
 
157 9434 james_leigh
// retrieve a Document by title using a dynamic query
158 9419 james_leigh
ObjectQuery query = con.prepareObjectQuery(
159 james_leigh
  "PREFIX gs:<http://meta.leighnet.ca/rdf/2009/gs#>\n"+
160 james_leigh
  "SELECT ?doc WHERE {?doc gs:title ?title}");
161 james_leigh
query.setObject("title", "Getting Started");
162 11496 james_leigh
Document doc = query.evaluate(Document.class).singleResult();
163 9419 james_leigh
+--
164 9434 james_leigh
 
165 10476 james_leigh
Implementing Inverse Properties
166 james_leigh
 
167 11496 james_leigh
 To simulate inverse properties in Java use named SPARQL queries for the Java getter and setter.
168 10951 james_leigh
 
169 10476 james_leigh
 <<Figure 8. Inverse Property>>
170 james_leigh
 
171 james_leigh
+--
172 11487 james_leigh
@Iri(FOAF + "Person")
173 10476 james_leigh
public interface Person {
174 11487 james_leigh
  @Iri(FOAF + "depiction")
175 10476 james_leigh
  Image getDepiction();
176 james_leigh
 
177 11487 james_leigh
  @Iri(FOAF + "depiction")
178 10476 james_leigh
  void setDepiction(Image depiction);
179 james_leigh
}
180 james_leigh
 
181 11487 james_leigh
@Iri(FOAF + "Image")
182 10476 james_leigh
public interface Image {
183 11496 james_leigh
  @Sparql(PREFIX + "SELECT ?person { ?person foaf:depiction $this }")
184 10476 james_leigh
  Person getDepicts();
185 james_leigh
 
186 11496 james_leigh
  @Sparql(PREFIX + "DELETE { ?p foaf:depiction $this }\n"+
187 james_leigh
    "INSERT { $person foaf:depiction $this } WHERE {} ")
188 james_leigh
  void setDepicts(@Bind("person") Person person);
189 10476 james_leigh
}
190 james_leigh
+--
191 james_leigh
 
192 11597 james_leigh
Collections
193 james_leigh
 
194 james_leigh
 In RDF the most natural collection is an unordered set, or non-functional
195 james_leigh
 property. Sets are triples that share the same subject and predicate.
196 james_leigh
 these non-functional properties should have a java.util.Set property type in
197 james_leigh
 Java.
198 james_leigh
 
199 james_leigh
 Ordered collections in RDF include rdf:List, rdfs:Container, rdf:Seq, rdf:Alt,
200 james_leigh
 and rdf:Bag. AliBaba provides a java.util.List interface for each of these
201 james_leigh
 resource types. However, all ordered collections in the RDF store must include
202 james_leigh
 an rdf:type on the root node. Often RDF formats that include syntax sugar for
203 james_leigh
 rdf:List do not include a rdf:type and may not be readable in AliBaba. To add
204 james_leigh
 the missing add the triple rdf:type rdf:List using the add statement method of
205 james_leigh
 the ObjectConnection. Other Java collections that implement java.util.List are
206 james_leigh
 mapped to rdfs:Container when merged into the store.
207 james_leigh
 
208 james_leigh
 Most RDF stores (like SQL databases) are not optimized for generic ordered
209 james_leigh
 collections. Developers will find unordered collections have significantly
210 james_leigh
 reduce I/O and better performance. If the elements of an ordered collection
211 james_leigh
 will only exist in (at most) one ordered collection, it is recommended instead
212 james_leigh
 to use a typed unordered collection (functional property) and included a
213 james_leigh
 functional index member property on the elements. The elements can then be
214 james_leigh
 sorted in memory when necessary.
215 james_leigh
 
216 james_leigh
 Figure 9 show an example of using an unordered collection with an explicit
217 james_leigh
 result order. The method getOrderedChildren() will order the nodes in the RDF
218 james_leigh
 store (often in memory), while the method getSortedChildren() will sort them in
219 james_leigh
 Java. In both cases calling java.util.List#add(Object) has no effect on the RDF
220 james_leigh
 store.
221 james_leigh
 
222 james_leigh
 <<Figure 9. Unordered Collection with element index>>
223 james_leigh
 
224 james_leigh
+--
225 james_leigh
import org.openrdf.annotations.Iri;
226 james_leigh
 
227 james_leigh
@Iri(NS + "Node")
228 james_leigh
public interface Node {
229 james_leigh
    @Iri(NS + "child")
230 james_leigh
    Set<Node> getChildren();
231 james_leigh
 
232 james_leigh
    @Iri(NS + "child")
233 james_leigh
    void setChildren(Set<Node> children);
234 james_leigh
 
235 james_leigh
    @Iri(NS + "position")
236 james_leigh
    Integer getPosition();
237 james_leigh
 
238 james_leigh
    @Iri(NS + "position")
239 james_leigh
    void setPosition(Integer position);
240 james_leigh
 
241 james_leigh
    @Sparql(PREFIX
242 james_leigh
            + "SELECT ?child { $this ex:child ?child . ?child ex:position ?position }\n"
243 james_leigh
            + "ORDER BY ?position")
244 james_leigh
    List<Node> getOrderedChildren();
245 james_leigh
 
246 james_leigh
    List<Node> getSortedChildren();
247 james_leigh
}
248 james_leigh
 
249 james_leigh
public abstract class NodeSupport implements Node {
250 james_leigh
    public List<Node> getSortedChildren() {
251 james_leigh
        Set<Node> live = getChildren();
252 james_leigh
        List<Node> memory = new ArrayList<Node>(live);
253 james_leigh
        Collections.sort(memory, new Comparator<Node>() {
254 james_leigh
            public int compare(Node o1, Node o2) {
255 james_leigh
                Integer p1 = o1.getPosition();
256 james_leigh
                Integer p2 = o2.getPosition();
257 james_leigh
                if (p1 == p2)
258 james_leigh
                    return 0;
259 james_leigh
                if (p1 == null)
260 james_leigh
                    return -1;
261 james_leigh
                if (p2 == null)
262 james_leigh
                    return 1;
263 james_leigh
                return p1.compareTo(p2);
264 james_leigh
            }
265 james_leigh
        });
266 james_leigh
        return memory;
267 james_leigh
    }
268 james_leigh
}
269 james_leigh
+--
270 james_leigh
 
271 10951 james_leigh
Aspect-Oriented Programming
272 james_leigh
 
273 james_leigh
 AliBaba allows any method call (including getters and setters) to be used as
274 11597 james_leigh
 join-points for cross cutting concerns. Figure 11 show the concept interface
275 james_leigh
 Person (with an @Iri annotation) which defines a join-point
276 james_leigh
 setDepiction(Image):void and the abstract behaviour class PersonSupport
277 10951 james_leigh
 (implements a concept interface) defines an aspect for that join-point by using
278 james_leigh
 the same method name, parameter types, and return type. Other classes may
279 james_leigh
 implement their own aspects using the same join-point and would be executed
280 james_leigh
 serially until all are executed or a non-null (nor 0 nor false) response is given.
281 james_leigh
 
282 james_leigh
 For more control over the execution order of aspects, AliBaba
283 11496 james_leigh
 provides the annotation @Precedes, which can be placed on a behaviour class
284 10951 james_leigh
 with a list of other behaviour classes, who's aspects should not be executed
285 james_leigh
 before the aspects of this annotated behaviour class. Aspects can also intercept
286 11496 james_leigh
 method executions by using the annotation @ParameterTypes when declaring the
287 10951 james_leigh
 aspect. The annotation should list the parameter types of the join-point, while
288 james_leigh
 the aspect parameter type is one of ObjectMessage, BooleanMessage, ByteMessage,
289 james_leigh
 CharacterMessage, DoubleMessage, FloatMessage, IntegerMessage, LongMessage,
290 james_leigh
 ShortMessage, and VoidMessage corresponding to the object or primitive return type of the
291 james_leigh
 aspect/join-point. When the aspect is executed the parameters of the method
292 james_leigh
 call and the return type (thus far) are available through one of the previously
293 11597 james_leigh
 listed message interfaces. Figure 11 shows an example of an aspect, which
294 10951 james_leigh
 conditionally changes the response of a method call to ensure it is never null.
295 james_leigh
 
296 11597 james_leigh
 <<Figure 11. Intercept method call>>
297 10951 james_leigh
 
298 james_leigh
+--
299 11487 james_leigh
@Iri(FOAF + "Person")
300 10951 james_leigh
public interface Person {
301 11487 james_leigh
  @Iri(FOAF + "depiction")
302 10951 james_leigh
  Image getDepiction();
303 james_leigh
 
304 11487 james_leigh
  @Iri(FOAF + "depiction")
305 10951 james_leigh
  void setDepiction(Image depiction);
306 james_leigh
}
307 james_leigh
 
308 james_leigh
public abstract class PersonSupport implements Person, RDFObject {
309 11496 james_leigh
  @ParameterTypes({})
310 james_leigh
  public Image getDepiction(ObjectMessage msg) throws RepositoryException {
311 10951 james_leigh
     Image depiction = (Image) msg.proceed();
312 james_leigh
     if (depiction == null) {
313 james_leigh
        return (Image) getObjectConnection().getObject(DEFAULT_IMAGE_URI);
314 james_leigh
     }
315 james_leigh
     return depiction;
316 james_leigh
  }
317 11597 james_leigh
 
318 james_leigh
  void setDepiction(Image depiction) {
319 james_leigh
    // With @ParameterTypes is not used call automatically proceeds
320 james_leigh
    System.out.println("setDepiction called with: " + depiction);
321 james_leigh
  }
322 10951 james_leigh
}
323 james_leigh
+--
324 james_leigh
 
325 11450 james_leigh
Information Resources (BLOBs)
326 james_leigh
 
327 11597 james_leigh
 The method getBlobObject can be used to retrive an FileObject interface of an
328 11450 james_leigh
 information resource by URI. The FileObject interface includes methods to open
329 james_leigh
 an InputStream and an OutputStream and will be stored by URI to the configured
330 james_leigh
 directory. Changes to the blobs will be isolated from other connections until
331 james_leigh
 the changes are committed (if not in autoCommit mode).
332 james_leigh
 
333 james_leigh
 The delegate BlobStore can be set using the setBlobStore method of the
334 james_leigh
 ObjectRepository before use. BlobStores are created using the BlobStoreFactory
335 james_leigh
 openBlobStore(File) method.
336 james_leigh
 
337 9434 james_leigh
Generating Concepts
338 9419 james_leigh
 
339 james_leigh
 Compatible class files can be created from RDFS/OWL files, for use with
340 james_leigh
 the ObjectRepository in Java, by using the provided owl-compiler.sh (or
341 james_leigh
 .bat) file, with main class
342 james_leigh
 org.openrdf.repository.object.compiler.Compiler. Use the '-h' option to
343 james_leigh
 review the available command line options.
344 james_leigh
 
345 james_leigh
 When precompiled class files are not needed in advance, the
346 james_leigh
 ObjectRepository can compile them itself. When the AliBaba JARs are
347 james_leigh
 added to the console, additional repository templates are included to
348 james_leigh
 facilitate creating the ObjectRepository. These include object-memory
349 james_leigh
 and object-native (among others). When creating the repository with the
350 james_leigh
 console, it will prompt for an OWL Ontology file that should contain the
351 james_leigh
 classes and properties needed and/or reference them using owl:imports
352 james_leigh
 statements within the file.
353 james_leigh
 
354 11597 james_leigh
 <<Figure 12. Creating ObjectRepository from the Console>>
355 9419 james_leigh
 
356 james_leigh
+--
357 james_leigh
Commands end with '.' at the end of a line
358 james_leigh
Type 'help.' for help
359 9590 james_leigh
> connect data.
360 9419 james_leigh
Disconnecting from default data directory
361 9590 james_leigh
Connected to data
362 9419 james_leigh
> create object-native.
363 james_leigh
Please specify values for the following variables:
364 james_leigh
Repository ID [native]: foaf
365 james_leigh
Repository title [Native store]: FOAF Store
366 10691 james_leigh
Rollback if multiple states observed (enforce snapshot)? (false|true) [false]:
367 james_leigh
Rollback if outdated state observed (enforce serializable)? (false|true) [false]:
368 james_leigh
Changeset namespace [urn:trx:localhost:]:
369 10840 james_leigh
Archive all removed data (false|true) [false]:
370 james_leigh
If not, archive transactions with removed triples less than [100]:
371 10691 james_leigh
Minimum recent transactions [100]:
372 james_leigh
Maximum recent transactions [1000]:
373 james_leigh
Triple indexes [spoc,posc]:
374 james_leigh
Max Query Time [0]:
375 james_leigh
Default Query Language [SPARQL]:
376 9419 james_leigh
Ontology [http://www.w3.org/2002/07/owl]: http://xmlns.com/foaf/spec/index.rdf
377 9596 james_leigh
Read Schema from Repository [false]:
378 9419 james_leigh
Repository created
379 10691 james_leigh
 
380 9419 james_leigh
> quit.
381 9590 james_leigh
Disconnecting from data
382 9419 james_leigh
Bye
383 james_leigh
+--
384 james_leigh
 
385 james_leigh
 Scripts can be streamlined by allowing the ObjectRepository to compile
386 11597 james_leigh
 the ontology. Shown in Figure 13 is jrunscript (in
387 9419 james_leigh
 JavaScript) that outputs a new FOAF file, demonstrating how RDF/Objects
388 james_leigh
 can be used without compiling Java files.
389 james_leigh
 
390 11597 james_leigh
 <<Figure 13. JRunScript and ObjectRepository>>
391 9419 james_leigh
 
392 james_leigh
+--
393 9974 james_leigh
$ jrunscript -J-Djava.ext.dirs=lib:dist
394 9590 james_leigh
js> var rm = org.openrdf.repository.manager.RepositoryProvider.getRepositoryManager("data")
395 9419 james_leigh
js> var repo = rm.getRepository("foaf")
396 james_leigh
js> var con = repo.getConnection()
397 10691 james_leigh
js> con.setAutoCommit(false)
398 james_leigh
js> var Person = "http://xmlns.com/foaf/0.1/Person"
399 james_leigh
js> var base = "http://example.com/person/"
400 james_leigh
js> var james = con.addDesignation(con.getObject(base+"james"), Person)
401 9977 james_leigh
js>
402 11496 james_leigh
js> james.foafFirstName.add("James")
403 james_leigh
js> james.foafSurname.add("Leigh")
404 james_leigh
js> james.foafInterest.add("RDF")
405 10691 james_leigh
js> var arjohn = con.addDesignation(con.getObject(base+"arjohn"), Person)
406 11496 james_leigh
js> arjohn.foafFirstName.add("Arjohn")
407 9434 james_leigh
js> james.foafKnows.add(arjohn)
408 9977 james_leigh
js>
409 10691 james_leigh
js> con.setNamespace("foaf", "http://xmlns.com/foaf/0.1/")
410 9419 james_leigh
js> con['export'](new org.openrdf.rio.rdfxml.RDFXMLWriter(java.lang.System.out), [])
411 james_leigh
<?xml version="1.0" encoding="UTF-8"?>
412 james_leigh
<rdf:RDF
413 james_leigh
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
414 james_leigh
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
415 james_leigh
 
416 9434 james_leigh
<rdf:Description rdf:about="http://meta.leighnet.ca/data/rdf/2009/foaf/james">
417 9419 james_leigh
    <rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person"/>
418 james_leigh
    <foaf:firstName>James</foaf:firstName>
419 james_leigh
    <foaf:surname>Leigh</foaf:surname>
420 james_leigh
    <foaf:interest>RDF</foaf:interest>
421 james_leigh
    <foaf:knows rdf:resource="http://meta.leighnet.ca/data/rdf/2009/foaf/arjohn"/>
422 james_leigh
</rdf:Description>
423 james_leigh
 
424 james_leigh
<rdf:Description rdf:about="http://meta.leighnet.ca/data/rdf/2009/foaf/arjohn">
425 james_leigh
    <rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person"/>
426 james_leigh
    <foaf:firstName>Arjohn</foaf:firstName>
427 james_leigh
</rdf:Description>
428 james_leigh
 
429 james_leigh
</rdf:RDF>
430 james_leigh
js> con.close()
431 james_leigh
+--
432 9973 james_leigh
 
433 9974 james_leigh
Message Vocabulary
434 9973 james_leigh
 
435 10951 james_leigh
 In addition to the RDFS and OWL vocabulary, the object repository also supports
436 james_leigh
 its own vocabulary for describing messages. This vocabulary can be used to
437 11597 james_leigh
 declare interface methods and implementations. These messages
438 10951 james_leigh
 can be created by extending the class msg:Message and creating restrictions for
439 james_leigh
 its msg:target and response properties (msg:object msg:objectSet msg:literal
440 james_leigh
 msg:literalSet). Implementations can be created in ECMA script, sparql, or
441 james_leigh
 xslt. Parameters (message properties) and the variable "this" is available in
442 james_leigh
 the implementations as (prefix + initcap local part) of the property URI or
443 james_leigh
 just the local part if no prefix is defined. msg:script code also has the
444 james_leigh
 method proceed() available to execute other implementations of the message. The
445 james_leigh
 last parameter (alpha sorted) is the body input of an msg:xslt message. Show in
446 11597 james_leigh
 Figure 14 is a sample of what a message might look like in turtle.
447 9974 james_leigh
 
448 11597 james_leigh
 <<Figure 14. Sample Usage of Object Vocabulary>>
449 9973 james_leigh
 
450 9974 james_leigh
+--
451 james_leigh
@prefix xsd:<http://www.w3.org/2001/XMLSchema#>.
452 james_leigh
@prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#>.
453 james_leigh
@prefix owl:<http://www.w3.org/2002/07/owl#>.
454 10835 james_leigh
@prefix msg:<http://www.openrdf.org/rdf/2011/messaging#>.
455 9974 james_leigh
@prefix :<http://data.leighnet.ca/rdf/2009/example#>.
456 9973 james_leigh
 
457 9974 james_leigh
# Declare classes and properties for this example
458 james_leigh
:Mammal rdfs:subClassOf rdfs:Resource.
459 james_leigh
:Person rdfs:subClassOf :Mammal.
460 james_leigh
:Dog rdfs:subClassOf :Mammal.
461 james_leigh
 
462 james_leigh
:dateOfBirth a owl:DatatypeProperty; a owl:FunctionalProperty;
463 james_leigh
    rdfs:domain :Mammal;
464 james_leigh
    rdfs:range xsd:date.
465 james_leigh
 
466 9977 james_leigh
# Common message that responds with the current date time
467 10835 james_leigh
:GetCurrentTime rdfs:subClassOf msg:Message;
468 james_leigh
    rdfs:subClassOf [owl:onProperty msg:literal; owl:allValuesFrom xsd:dateTime];
469 james_leigh
    msg:imports <java:javax.xml.datatype.DatatypeFactory>;
470 james_leigh
    msg:imports <java:java.util.GregorianCalendar>;
471 james_leigh
    msg:script """
472 10541 james_leigh
        var df = DatatypeFactory.newInstance();
473 9977 james_leigh
        return df.newXMLGregorianCalendar(new GregorianCalendar());
474 9974 james_leigh
    """.
475 james_leigh
 
476 9977 james_leigh
# Common message that take a date time and responds with the duration since then
477 10835 james_leigh
# This message uses the parameter when and the previous message to compute a new value
478 james_leigh
:GetDurationSince rdfs:subClassOf msg:Message;
479 james_leigh
    rdfs:subClassOf [owl:onProperty msg:literal; owl:allValuesFrom xsd:duration];
480 james_leigh
    msg:imports <java:javax.xml.datatype.DatatypeFactory>;
481 james_leigh
    msg:script """
482 10541 james_leigh
        var df = DatatypeFactory.newInstance();
483 10835 james_leigh
        var now = this.GetCurrentTime().toGregorianCalendar().getTimeInMillis();
484 10691 james_leigh
        var since = when.toGregorianCalendar().getTimeInMillis();
485 james_leigh
        return df.newDuration(now - since);
486 9974 james_leigh
    """.
487 james_leigh
 
488 10691 james_leigh
:when a owl:DatatypeProperty; a owl:FunctionalProperty;
489 james_leigh
    rdfs:domain :GetDurationSince;
490 9974 james_leigh
    rdfs:range xsd:dateTime.
491 james_leigh
 
492 james_leigh
# Message for the age of a Mammal
493 10541 james_leigh
# This message is written in ECMA script and uses a compact syntax
494 10835 james_leigh
:GetCurrentAge rdfs:subClassOf msg:Message;
495 james_leigh
    rdfs:subClassOf [owl:onProperty msg:target; owl:allValuesFrom :Mammal];
496 james_leigh
    rdfs:subClassOf [owl:onProperty msg:literal; owl:allValuesFrom xsd:int];
497 james_leigh
    msg:script "return this.GetDurationSince(this.dateOfBirth).years".
498 9974 james_leigh
 
499 james_leigh
# Dog's age is calculated differently than other mammals
500 9977 james_leigh
# This message is a specialisation of the previous and overrides it for all dogs
501 10541 james_leigh
# The proceed() method is used to call and return the response from intercepted methods
502 10835 james_leigh
:GetCurrentDogAge owl:intersectionOf (:GetCurrentAge [owl:onProperty msg:target; owl:allValuesFrom :Dog]);
503 10840 james_leigh
    msg:script "return proceed() * 7".
504 9974 james_leigh
 
505 james_leigh
# Intercepts the age message and checks if the mammal is less then a year old
506 10691 james_leigh
:GetCurrentAgeInMonths owl:equivalentClass :GetCurrentAge;
507 10835 james_leigh
    msg:script """
508 10541 james_leigh
        var year = proceed();
509 9974 james_leigh
        if (year < 2) {
510 10835 james_leigh
            var duration = this.GetDurationSince(this.dateOfBirth);
511 10691 james_leigh
            return duration.years * 12 + duration.months;
512 9974 james_leigh
        }
513 james_leigh
        return year;
514 james_leigh
    """.
515 james_leigh
 
516 james_leigh
# Some sample data to test with
517 james_leigh
:jack a :Dog;
518 james_leigh
    :dateOfBirth "2005-02-18"^^xsd:date.
519 james_leigh
 
520 james_leigh
:mel a :Person;
521 james_leigh
    :dateOfBirth "1956-01-03"^^xsd:date.
522 james_leigh
 
523 james_leigh
:lucia a :Person;
524 james_leigh
    :dateOfBirth "2009-10-30"^^xsd:date.
525 james_leigh
+--
526 james_leigh
 
527 11597 james_leigh
 When an object repository is set to use the Ontology in Figure 14, the connection in Figure 15 can be used to evaluate the messages and calulate the age. Since an empty prefix was used in the ontology, no prefix is used when calling messages (or properties). If the schema changes at runtime the method ObjectConnection#recompileSchemaOnClose() should be called to compile the changes within the ObjectConnection#close() method.
528 9974 james_leigh
 
529 11597 james_leigh
 <<Figure 15. Creating ObjectRepository from the Console>>
530 9974 james_leigh
 
531 james_leigh
+--
532 10840 james_leigh
Commands end with '.' at the end of a line
533 james_leigh
Type 'help.' for help
534 james_leigh
> connect data.
535 james_leigh
Disconnecting from default data directory
536 james_leigh
Connected to data
537 james_leigh
> create object-native.
538 james_leigh
Please specify values for the following variables:
539 james_leigh
Repository ID [native]: mammals
540 james_leigh
Repository title [Native store]: Mammal Store
541 james_leigh
Rollback if multiple states observed (enforce snapshot)? (false|true) [false]:
542 james_leigh
Rollback if outdated state observed (enforce serializable)? (false|true) [false]:
543 james_leigh
Changeset namespace [urn:trx:localhost:]:
544 james_leigh
Archive all removed data (false|true) [false]:
545 james_leigh
If not, archive transactions with removed triples less than [100]:
546 james_leigh
Minimum recent transactions [100]:
547 james_leigh
Maximum recent transactions [1000]:
548 james_leigh
Triple indexes [spoc,posc]:
549 james_leigh
Max Query Time [0]:
550 james_leigh
Default Query Language [SPARQL]:
551 james_leigh
Ontology [http://www.w3.org/2002/07/owl]:
552 james_leigh
Read Schema from Repository [false]: true
553 james_leigh
Repository created
554 james_leigh
 
555 james_leigh
> open mammals.
556 james_leigh
Opened repository 'mammals'
557 james_leigh
mammals> load mammals.ttl.
558 james_leigh
Loading data...
559 james_leigh
Data has been added to the repository (3048 ms)
560 james_leigh
mammals> quit.
561 james_leigh
Closing repository 'mammals'...
562 james_leigh
Disconnecting from data
563 james_leigh
Bye
564 james_leigh
+--
565 james_leigh
 
566 11597 james_leigh
 <<Figure 16. Calling Object Messages from JavaScript>>
567 10840 james_leigh
 
568 james_leigh
+--
569 james_leigh
$ jrunscript -J-Djava.ext.dirs=lib:dist
570 james_leigh
js> var rm = org.openrdf.repository.manager.RepositoryProvider.getRepositoryManager("data")
571 james_leigh
js> var repo = rm.getRepository("mammals")
572 9974 james_leigh
js> var con = repo.getConnection()
573 james_leigh
js> var jack = con.getObject("http://data.leighnet.ca/rdf/2009/example#jack")
574 james_leigh
js> var mel = con.getObject("http://data.leighnet.ca/rdf/2009/example#mel")
575 james_leigh
js> var lucia = con.getObject("http://data.leighnet.ca/rdf/2009/example#lucia")
576 10691 james_leigh
js> jack.GetCurrentAge()
577 james_leigh
35
578 james_leigh
js> mel.GetCurrentAge()
579 james_leigh
54
580 james_leigh
js> lucia.GetCurrentAge()
581 james_leigh
13
582 9974 james_leigh
js> con.close()
583 james_leigh
+--
584 james_leigh
 
585 9419 james_leigh
 The ObjectRepository simplifies interacting with RDF resources in OO
586 james_leigh
 languages on the JVM. By bridging RDF properties and object properties,
587 james_leigh
 creating and manipulating RDF resources is as easy as manipulating objects.
588 james_leigh
 
589 9486 james_leigh