Subversion Repositories aduna

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

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 11769 james_leigh
 method, which takes the directory location that was used in
23 9419 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 11797 james_leigh
 other Sesame RDF Repositories, with full triple access, but it returns an
30 9419 james_leigh
 ObjectConnection in the getConnection method. The ObjectConnection is an
31 james_leigh
 extension of the RepositoryConnection and includes additional methods
32 12043 james_leigh
 for working with objects and information-resources. These objects are actually
33 james_leigh
 just proxies to the ObjectConnection that returned them. However, before
34 james_leigh
 objects can be returned, object classes must first be created and registered.
35 9419 james_leigh
 
36 11487 james_leigh
 To create classes for the ObjectRepository add the @Iri annotation to
37 9974 james_leigh
 all classes and fields (or interfaces and property methods)
38 james_leigh
 that should be stored in the repository. Then
39 9419 james_leigh
 create an empty 'META-INF/org.openrdf.concepts' file in the root
40 9434 james_leigh
 directory (or JAR) of the annotated classes. Once the
41 9421 james_leigh
 classes have been created, as shown in Figure 5,
42 9419 james_leigh
 they can be used with new ObjectRepositories.
43 james_leigh
 
44 james_leigh
 <<Figure 5. A Class Compatible with the ObjectRepository>>
45 james_leigh
 
46 james_leigh
+--
47 james_leigh
// Document.java
48 11486 james_leigh
import org.openrdf.annotations.Iri;
49 9419 james_leigh
 
50 11487 james_leigh
@Iri(Document.NS + "Document")
51 9419 james_leigh
public class Document {
52 11769 james_leigh
  public static final String NS = "http://example.com/rdf/2012/gs#";
53 9434 james_leigh
 
54 11487 james_leigh
  @Iri(NS + "title") String title;
55 9434 james_leigh
 
56 james_leigh
  public String getTitle() {
57 james_leigh
    return title;
58 james_leigh
  }
59 james_leigh
  public void setTitle(String title) {
60 james_leigh
    this.title = title;
61 james_leigh
  }
62 9419 james_leigh
}
63 james_leigh
+--
64 james_leigh
 
65 james_leigh
 To add an object to the ObjectRepository, create an ObjectConnection and
66 11769 james_leigh
 call the addObject method (as shown in Figure 6). This method will recursively
67 james_leigh
 add all other objects referenced from annotated fields. The addObject method can
68 9419 james_leigh
 either automatically create a unique identifier for the object (that
69 james_leigh
 might change over time), or add the object using a provided identifier,
70 11769 james_leigh
 called a URI. If the object implements the interface RDFObject, the identifier
71 james_leigh
 can also be provided using the getResource method. Note that the getConnection
72 james_leigh
 method of RDFObject can simple return null by default since it will be
73 james_leigh
 overridden when retrieved from the store.
74 james_leigh
 
75 james_leigh
 It is recommended to use a URI for any object that might
76 james_leigh
 need to be referenced directly or has a conceptual identity. For all
77 10951 james_leigh
 other objects, such as anonymous collections, an automatic identifier
78 james_leigh
 may be good enough.
79 9419 james_leigh
 
80 james_leigh
 To retrieve an existing object, use the getObject(Class, Resource)
81 james_leigh
 method of the ObjectConnection. The method accepts a URI or an anonymous
82 james_leigh
 identifier. An anonymous identifier maybe different for different
83 james_leigh
 ObjectConnections and should only be used within a single
84 12043 james_leigh
 ObjectConnection. A URI, however, will never change and can be used in any
85 james_leigh
 connection. Once the ObjectConnection is closed, the objects it returned
86 james_leigh
 must be discarded.
87 9419 james_leigh
 
88 james_leigh
 Removing an object is more difficult, as every property of the object
89 james_leigh
 will need to be removed, by setting the fields or properties to null.
90 james_leigh
 Furthermore, the type of the object must also be removed from the
91 james_leigh
 repository, this can be done using the removeDesignation method of the
92 james_leigh
 ObjectConnection.
93 james_leigh
 
94 james_leigh
 <<Figure 6. Using an ObjectConnection>>
95 james_leigh
 
96 james_leigh
+--
97 james_leigh
// create a Document
98 james_leigh
Document doc = new Document();
99 james_leigh
doc.setTitle("Getting Started");
100 james_leigh
 
101 james_leigh
// add a Document to the repository
102 james_leigh
ObjectConnection con = repository.getConnection();
103 james_leigh
ValueFactory vf = con.getValueFactory();
104 11769 james_leigh
URI id = vf.createURI("http://example.com/data/2012/getting-started");
105 9970 james_leigh
con.addObject(id, doc);
106 9419 james_leigh
 
107 james_leigh
// retrieve a Document by id
108 james_leigh
Document doc = con.getObject(Document.class, id);
109 james_leigh
 
110 james_leigh
// remove a Document from the repository
111 james_leigh
Document doc = con.getObject(Document.class, id);
112 james_leigh
doc.setTitle(null);
113 9970 james_leigh
con.removeDesignation(doc, Document.class);
114 9434 james_leigh
+--
115 james_leigh
 
116 james_leigh
 Objects can also be retrieved by their type using the getObjects(Class)
117 james_leigh
 method, which includes subclasses. More fine grained queries can be
118 11496 james_leigh
 created using the @Sparql annotation. This annotation should be placed
119 james_leigh
 on public or protected methods that have a @Bind annotation on their parameters and have
120 9434 james_leigh
 a return type and parameters types of registered concepts or datatypes.
121 james_leigh
 The return type may also be a java.util.Set or Result of a concept or
122 9624 james_leigh
 datatype and may also be Model and any query result, such as GraphQueryResult,
123 10835 james_leigh
 TupleQueryResult, or boolean. Public and protected methods with this annotation will be
124 9434 james_leigh
 overridden with an optimized object query execution. The parameters with
125 11769 james_leigh
 a @Bind annotation will be available in the query in the variable name
126 james_leigh
 provided. The target resource is available in the query using the
127 james_leigh
 variable "$this".
128 9419 james_leigh
 
129 9434 james_leigh
 Dynamic queries can be constructed using the prepareObjectQuery method
130 james_leigh
 or one of the other prepareQuery methods. The prepareObjectQuery method
131 james_leigh
 returns an ObjectQuery that allows objects and their type to be assigned to
132 james_leigh
 variables within the query before execution.
133 james_leigh
 
134 james_leigh
 <<Figure 7. Executing Queries>>
135 james_leigh
 
136 james_leigh
+--
137 james_leigh
 
138 9419 james_leigh
// retrieve all Documents
139 james_leigh
Result<Document> result = con.getObjects(Document.class);
140 james_leigh
while (result.hasNext()) {
141 james_leigh
  out.println(result.next().getTitle());
142 james_leigh
}
143 james_leigh
 
144 11597 james_leigh
import org.openrdf.annotations.Sparql;
145 james_leigh
import org.openrdf.annotations.Bind;
146 james_leigh
 
147 9596 james_leigh
// retrieve a Document by title using a named query
148 11769 james_leigh
@Sparql("PREFIX gs:<http://example.com/rdf/2012/gs#>\n"+
149 9434 james_leigh
  "SELECT ?doc WHERE {?doc gs:title $title}")
150 11496 james_leigh
public Document findDocumentByTitle(@Bind("title") String title) {
151 9434 james_leigh
  return null;
152 james_leigh
}
153 james_leigh
 
154 11769 james_leigh
 
155 11450 james_leigh
// retrieve a Document by title using a named query
156 james_leigh
ValueFactory vf = con.getRepository().getValueFactory();
157 11769 james_leigh
URI myQueryID = vf.createURI("http://example.com/rdf/2012/my-query");
158 james_leigh
 
159 11450 james_leigh
NamedQuery named = con.getRepository().createNamedQuery(myQueryID,
160 11769 james_leigh
  "PREFIX gs:<http://example.com/rdf/2012/gs#>\n"+
161 11450 james_leigh
  "SELECT ?doc WHERE {?doc gs:title ?title}");
162 james_leigh
 
163 james_leigh
ObjectQuery query = con.prepareObjectQuery(named.getQueryString());
164 james_leigh
query.setObject("title", "Getting Started");
165 11496 james_leigh
Document doc = query.evaluate(Document.class).singleResult();
166 11450 james_leigh
 
167 11769 james_leigh
 
168 9434 james_leigh
// retrieve a Document by title using a dynamic query
169 9419 james_leigh
ObjectQuery query = con.prepareObjectQuery(
170 11769 james_leigh
  "PREFIX gs:<http://example.com/rdf/2012/gs#>\n"+
171 9419 james_leigh
  "SELECT ?doc WHERE {?doc gs:title ?title}");
172 james_leigh
query.setObject("title", "Getting Started");
173 11496 james_leigh
Document doc = query.evaluate(Document.class).singleResult();
174 9419 james_leigh
+--
175 9434 james_leigh
 
176 11769 james_leigh
Concepts
177 james_leigh
 
178 james_leigh
 Concepts are a hierarchical model of resource classes, that include a
179 james_leigh
 description of supported operations on a type, including syntax and semantics.
180 james_leigh
 A concept defines the properties and methods available to objects retrieved from
181 james_leigh
 the store.
182 james_leigh
 
183 james_leigh
 Concepts are Java classes or interfaces that are mapped to an IRI
184 james_leigh
 (Internationalized Resource Identifier). Concepts can be mapped via an @Iri
185 james_leigh
 annotation, assigned explicitly in a META-INF/org.openrdf.concepts, or
186 11797 james_leigh
 at runtime in an ObjectRepositoryConfig passed to an ObjectRepositoryFactory.
187 11769 james_leigh
 If META-INF/org.openrdf.concepts is empty, the path is searched for Concepts
188 james_leigh
 with an @Iri annotation. If the file includes a list of class names, only those
189 james_leigh
 Concepts will be mapped to the value of their @Iri annotation value. If the file
190 james_leigh
 is a Java properties file that maps Concept class names to one or more IRI, the
191 james_leigh
 Concepts are mapped to their @Iri value (if present) and its IRIs in the files.
192 james_leigh
 
193 james_leigh
 RDF objects retrieved from the store implement all the concepts that map to one
194 james_leigh
 of the URI/IRI rdf:type values of the RDF resource. Any Java field, getter
195 james_leigh
 method, or setter method, on a concept, that includes an @Iri annotation will
196 james_leigh
 be mapped to an RDF property using the given predicate.
197 james_leigh
 
198 james_leigh
Mixin Behaviours
199 james_leigh
 
200 james_leigh
 Behaviours are implementations that are mixed into objects, retrieved from the
201 james_leigh
 store. By using behaviours, code can be organized by what it does, not just by
202 james_leigh
 what it operations on. All methods and interfaces implemented in a Mixin
203 james_leigh
 Behaviour are inherited by the relevant objects retrieved from the store. Mixin
204 james_leigh
 Behaviours may extend other Mixin Behaviours to inherit and possibly override
205 james_leigh
 the super class method implementations.
206 james_leigh
 
207 james_leigh
 Behaviours are Java classes that are mapped to a Concept. Behaviours can be
208 james_leigh
 mapped by implementing a Concept interface, assigned to a Concept IRI in a
209 11797 james_leigh
 META-INF/org.openrdf.behaviours file, or at runtime in an ObjectRepositoryConfig.
210 11769 james_leigh
 If META-INF/org.openrdf.behaviours is empty, the path is searched for Behaviours
211 james_leigh
 that implement a Concept with an @Iri annotation. If the file includes a list
212 james_leigh
 of class names, only those Behaviours will be mapped to the value of their
213 james_leigh
 implementing Concept @Iri annotation value. If the file is a Java properties
214 james_leigh
 file that maps Behaviours class names to one or more IRI, the
215 james_leigh
 Behaviours are mapped to its IRIs in the files.
216 james_leigh
 
217 james_leigh
 Behaviours need not be concrete classes, they can be abstract. Abstract methods
218 james_leigh
 can be called from within a Behaviour to call methods on the proxy object
219 james_leigh
 retrieved from the store. Method
220 james_leigh
 implementations, of large Concept interfaces, can be organized into multiple
221 james_leigh
 abstract Behaviour classes that implement only particular methods. Concept's
222 james_leigh
 getter and setter methods, with @Iri annotations, need not be implemented at all.
223 james_leigh
 
224 james_leigh
 Behaviours have the same life cycle as concrete Concepts. They are created
225 james_leigh
 within an ObjectConnection for a unique object instance. The object instance
226 james_leigh
 is a proxy for the behaviour assigned to a particular resource in the store.
227 james_leigh
 The object instance should not be used once the ObjectConnection is closed,
228 james_leigh
 and multiple object instances maybe created to proxy behaviour for the same
229 james_leigh
 resource of the store within the same ObjectConnection.
230 james_leigh
 
231 10476 james_leigh
Implementing Inverse Properties
232 james_leigh
 
233 11496 james_leigh
 To simulate inverse properties in Java use named SPARQL queries for the Java getter and setter.
234 10951 james_leigh
 
235 10476 james_leigh
 <<Figure 8. Inverse Property>>
236 james_leigh
 
237 james_leigh
+--
238 11487 james_leigh
@Iri(FOAF + "Person")
239 10476 james_leigh
public interface Person {
240 11487 james_leigh
  @Iri(FOAF + "depiction")
241 10476 james_leigh
  Image getDepiction();
242 james_leigh
 
243 11487 james_leigh
  @Iri(FOAF + "depiction")
244 10476 james_leigh
  void setDepiction(Image depiction);
245 james_leigh
}
246 james_leigh
 
247 11487 james_leigh
@Iri(FOAF + "Image")
248 10476 james_leigh
public interface Image {
249 11496 james_leigh
  @Sparql(PREFIX + "SELECT ?person { ?person foaf:depiction $this }")
250 10476 james_leigh
  Person getDepicts();
251 james_leigh
 
252 11870 james_leigh
  @Sparql(PREFIX + "DELETE { ?p foaf:depiction $this } WHERE { ?p foaf:depiction $this } ;\n"+
253 11496 james_leigh
    "INSERT { $person foaf:depiction $this } WHERE {} ")
254 james_leigh
  void setDepicts(@Bind("person") Person person);
255 10476 james_leigh
}
256 james_leigh
+--
257 james_leigh
 
258 11597 james_leigh
Collections
259 james_leigh
 
260 james_leigh
 In RDF the most natural collection is an unordered set, or non-functional
261 james_leigh
 property. Sets are triples that share the same subject and predicate.
262 james_leigh
 these non-functional properties should have a java.util.Set property type in
263 james_leigh
 Java.
264 james_leigh
 
265 james_leigh
 Ordered collections in RDF include rdf:List, rdfs:Container, rdf:Seq, rdf:Alt,
266 james_leigh
 and rdf:Bag. AliBaba provides a java.util.List interface for each of these
267 james_leigh
 resource types. However, all ordered collections in the RDF store must include
268 james_leigh
 an rdf:type on the root node. Often RDF formats that include syntax sugar for
269 james_leigh
 rdf:List do not include a rdf:type and may not be readable in AliBaba. To add
270 james_leigh
 the missing add the triple rdf:type rdf:List using the add statement method of
271 james_leigh
 the ObjectConnection. Other Java collections that implement java.util.List are
272 james_leigh
 mapped to rdfs:Container when merged into the store.
273 james_leigh
 
274 james_leigh
 Most RDF stores (like SQL databases) are not optimized for generic ordered
275 james_leigh
 collections. Developers will find unordered collections have significantly
276 james_leigh
 reduce I/O and better performance. If the elements of an ordered collection
277 james_leigh
 will only exist in (at most) one ordered collection, it is recommended instead
278 11797 james_leigh
 to use a typed unordered collection (non-functional property) and included a
279 11597 james_leigh
 functional index member property on the elements. The elements can then be
280 james_leigh
 sorted in memory when necessary.
281 james_leigh
 
282 james_leigh
 Figure 9 show an example of using an unordered collection with an explicit
283 james_leigh
 result order. The method getOrderedChildren() will order the nodes in the RDF
284 james_leigh
 store (often in memory), while the method getSortedChildren() will sort them in
285 james_leigh
 Java. In both cases calling java.util.List#add(Object) has no effect on the RDF
286 james_leigh
 store.
287 james_leigh
 
288 james_leigh
 <<Figure 9. Unordered Collection with element index>>
289 james_leigh
 
290 james_leigh
+--
291 james_leigh
import org.openrdf.annotations.Iri;
292 james_leigh
 
293 james_leigh
@Iri(NS + "Node")
294 james_leigh
public interface Node {
295 james_leigh
    @Iri(NS + "child")
296 james_leigh
    Set<Node> getChildren();
297 james_leigh
 
298 james_leigh
    @Iri(NS + "child")
299 james_leigh
    void setChildren(Set<Node> children);
300 james_leigh
 
301 james_leigh
    @Iri(NS + "position")
302 james_leigh
    Integer getPosition();
303 james_leigh
 
304 james_leigh
    @Iri(NS + "position")
305 james_leigh
    void setPosition(Integer position);
306 james_leigh
 
307 james_leigh
    @Sparql(PREFIX
308 james_leigh
            + "SELECT ?child { $this ex:child ?child . ?child ex:position ?position }\n"
309 james_leigh
            + "ORDER BY ?position")
310 james_leigh
    List<Node> getOrderedChildren();
311 james_leigh
 
312 james_leigh
    List<Node> getSortedChildren();
313 james_leigh
}
314 james_leigh
 
315 james_leigh
public abstract class NodeSupport implements Node {
316 james_leigh
    public List<Node> getSortedChildren() {
317 james_leigh
        Set<Node> live = getChildren();
318 james_leigh
        List<Node> memory = new ArrayList<Node>(live);
319 james_leigh
        Collections.sort(memory, new Comparator<Node>() {
320 james_leigh
            public int compare(Node o1, Node o2) {
321 james_leigh
                Integer p1 = o1.getPosition();
322 james_leigh
                Integer p2 = o2.getPosition();
323 james_leigh
                if (p1 == p2)
324 james_leigh
                    return 0;
325 james_leigh
                if (p1 == null)
326 james_leigh
                    return -1;
327 james_leigh
                if (p2 == null)
328 james_leigh
                    return 1;
329 james_leigh
                return p1.compareTo(p2);
330 james_leigh
            }
331 james_leigh
        });
332 james_leigh
        return memory;
333 james_leigh
    }
334 james_leigh
}
335 james_leigh
+--
336 james_leigh
 
337 11769 james_leigh
Aspect Behaviours
338 10951 james_leigh
 
339 james_leigh
 AliBaba allows any method call (including getters and setters) to be used as
340 11769 james_leigh
 join-points. Figure 11 show the Concept interface
341 james_leigh
 Person (with an @Iri annotation) which defines a join-point (i.e. declared method)
342 james_leigh
 execution(void setDepiction(Image)) and the abstract Behaviour class PersonSupport
343 james_leigh
 (implements a Concept interface) defines an aspect for that join-point by using
344 james_leigh
 the same method name, parameter types, and return type.
345 james_leigh
 
346 james_leigh
 Multiple aspects may each have their own implementations for the same
347 james_leigh
 join-point and, if so, they would be executed serially until all are executed
348 james_leigh
 or a non-null (nor primitive 0 nor boolean false) response is given. For more
349 james_leigh
 control over the execution order of aspects, AliBaba
350 11496 james_leigh
 provides the annotation @Precedes, which can be placed on a behaviour class
351 10951 james_leigh
 with a list of other behaviour classes, who's aspects should not be executed
352 11769 james_leigh
 before the aspects of this annotated behaviour class.
353 james_leigh
 
354 james_leigh
 Aspects can also intercept
355 11797 james_leigh
 method executions by using the annotation @ParameterTypes when declaring a
356 james_leigh
 method. The annotation should list the parameter types of the join-point, while
357 james_leigh
 the method parameter type is one of ObjectMessage, BooleanMessage, ByteMessage,
358 10951 james_leigh
 CharacterMessage, DoubleMessage, FloatMessage, IntegerMessage, LongMessage,
359 james_leigh
 ShortMessage, and VoidMessage corresponding to the object or primitive return type of the
360 11797 james_leigh
 method/join-point. When the method is executed the parameters of the method
361 11769 james_leigh
 call (thus far) and the return type are available through one of the previously
362 11597 james_leigh
 listed message interfaces. Figure 11 shows an example of an aspect, which
363 10951 james_leigh
 conditionally changes the response of a method call to ensure it is never null.
364 james_leigh
 
365 11769 james_leigh
 Aspect Behaviours have the same life cycle as Mixin Behaviours and are mapped
366 james_leigh
 to a Concept in the same way. Like Mixin Behaviours, Aspect Behaviour can be
367 james_leigh
 abstract, and any interface they implement will also be implemented by the
368 james_leigh
 relevant objects retrieved from the store. The use of @PameterTypes and/or
369 james_leigh
 @Precedes annotations distinguish an Aspect Behaviour class from a Mixin
370 james_leigh
 Behaviour class.
371 james_leigh
 
372 11597 james_leigh
 <<Figure 11. Intercept method call>>
373 10951 james_leigh
 
374 james_leigh
+--
375 11487 james_leigh
@Iri(FOAF + "Person")
376 10951 james_leigh
public interface Person {
377 11487 james_leigh
  @Iri(FOAF + "depiction")
378 10951 james_leigh
  Image getDepiction();
379 james_leigh
 
380 11487 james_leigh
  @Iri(FOAF + "depiction")
381 10951 james_leigh
  void setDepiction(Image depiction);
382 james_leigh
}
383 james_leigh
 
384 james_leigh
public abstract class PersonSupport implements Person, RDFObject {
385 11496 james_leigh
  @ParameterTypes({})
386 james_leigh
  public Image getDepiction(ObjectMessage msg) throws RepositoryException {
387 10951 james_leigh
     Image depiction = (Image) msg.proceed();
388 james_leigh
     if (depiction == null) {
389 james_leigh
        return (Image) getObjectConnection().getObject(DEFAULT_IMAGE_URI);
390 james_leigh
     }
391 james_leigh
     return depiction;
392 james_leigh
  }
393 11597 james_leigh
 
394 james_leigh
  void setDepiction(Image depiction) {
395 11725 james_leigh
    // When @ParameterTypes is not used, proceed() is automatically called
396 11597 james_leigh
    System.out.println("setDepiction called with: " + depiction);
397 james_leigh
  }
398 10951 james_leigh
}
399 james_leigh
+--
400 james_leigh
 
401 11769 james_leigh
Advice
402 james_leigh
 
403 james_leigh
 Advice is code that is executed around a method execution. Unlike Aspect
404 james_leigh
 Behaviours, Advice has a static life cycle. It is reused for multiple proxy
405 11797 james_leigh
 object instances across multiple ObjectConnections. Advice allows the
406 11769 james_leigh
 implementation of concerns that crosscut many different methods.
407 james_leigh
 
408 james_leigh
 Advice is mapped to method executions based on the retained annotation types
409 james_leigh
 declared on the method. For example, the Advice in Figure 12 check that the
410 james_leigh
 caller's code source has permission to call the method.
411 james_leigh
 
412 james_leigh
 List the full class name of an AdviceProvider in the provider services file to
413 james_leigh
 assign an AdviceFactory to an retained annotation type. The AdviceFactory
414 james_leigh
 assigns Advice to declared methods, with that annotation type, in objects
415 james_leigh
 retrieved from the store.
416 james_leigh
 
417 james_leigh
 <<Figure 12. Advice Security>>
418 james_leigh
 
419 james_leigh
+--
420 james_leigh
@Retention(RetentionPolicy.RUNTIME)
421 james_leigh
@Target(ElementType.METHOD)
422 james_leigh
public @interface ProtectedBy {
423 james_leigh
  String value();
424 james_leigh
}
425 james_leigh
 
426 james_leigh
@Iri(FOAF + "Person")
427 james_leigh
public interface Person {
428 james_leigh
  @ProtectedBy("somethingImportantPermission")
429 james_leigh
  void doSomethingImportant();
430 james_leigh
}
431 james_leigh
 
432 james_leigh
public class ProtectedAdvice implements Advice {
433 james_leigh
  private SecurityManager sm;
434 james_leigh
  private String directive;
435 james_leigh
  public ProtectedAdvice(SecurityManager sm, String directive) {
436 james_leigh
    this.sm = sm;
437 james_leigh
    this.directive = directive;
438 james_leigh
  }
439 james_leigh
 
440 james_leigh
  public Object intercept(ObjectMessage msg) throws Exception {
441 james_leigh
    sm.checkSecurityAccess(directive);
442 james_leigh
    return msg.proceed();
443 james_leigh
  }
444 james_leigh
}
445 james_leigh
 
446 james_leigh
public static class ProtectedAdviceFactory implements AdviceFactory, AdviceProvider {
447 james_leigh
  private SecurityManager sm = System.getSecurityManager();
448 james_leigh
  public AdviceFactory getAdviserFactory(Class<?> annotationType) {
449 james_leigh
    if (sm != null && ProtectedBy.class.equals(annotationType))
450 james_leigh
      return this;
451 james_leigh
    return null;
452 james_leigh
  }
453 11812 james_leigh
  public Advice createAdvice(Method method) {
454 11769 james_leigh
    ProtectedBy ann = method.getAnnotation(ProtectedBy.class);
455 james_leigh
    return new ProtectedAdvice(sm, ann.value());
456 james_leigh
  }
457 james_leigh
}
458 james_leigh
 
459 james_leigh
# META-INF/services/org.openrdf.repository.object.advice.AdviceProvider
460 james_leigh
ProtectedAdviceFactory
461 james_leigh
+--
462 james_leigh
 
463 11450 james_leigh
Information Resources (BLOBs)
464 james_leigh
 
465 11769 james_leigh
 The method getBlobObject can be used to retrieve a FileObject interface of an
466 11450 james_leigh
 information resource by URI. The FileObject interface includes methods to open
467 james_leigh
 an InputStream and an OutputStream and will be stored by URI to the configured
468 james_leigh
 directory. Changes to the blobs will be isolated from other connections until
469 james_leigh
 the changes are committed (if not in autoCommit mode).
470 james_leigh
 
471 james_leigh
 The delegate BlobStore can be set using the setBlobStore method of the
472 james_leigh
 ObjectRepository before use. BlobStores are created using the BlobStoreFactory
473 james_leigh
 openBlobStore(File) method.
474 james_leigh
 
475 9434 james_leigh
Generating Concepts
476 9419 james_leigh
 
477 james_leigh
 Compatible class files can be created from RDFS/OWL files, for use with
478 james_leigh
 the ObjectRepository in Java, by using the provided owl-compiler.sh (or
479 james_leigh
 .bat) file, with main class
480 james_leigh
 org.openrdf.repository.object.compiler.Compiler. Use the '-h' option to
481 james_leigh
 review the available command line options.
482 james_leigh
 
483 11769 james_leigh
 When precompiled concept interfaces files are not needed in advance, the
484 9419 james_leigh
 ObjectRepository can compile them itself. When the AliBaba JARs are
485 james_leigh
 added to the console, additional repository templates are included to
486 james_leigh
 facilitate creating the ObjectRepository. These include object-memory
487 james_leigh
 and object-native (among others). When creating the repository with the
488 james_leigh
 console, it will prompt for an OWL Ontology file that should contain the
489 james_leigh
 classes and properties needed and/or reference them using owl:imports
490 james_leigh
 statements within the file.
491 james_leigh
 
492 11769 james_leigh
 <<Figure 13. Creating ObjectRepository from the Console>>
493 9419 james_leigh
 
494 james_leigh
+--
495 james_leigh
Commands end with '.' at the end of a line
496 james_leigh
Type 'help.' for help
497 9590 james_leigh
> connect data.
498 9419 james_leigh
Disconnecting from default data directory
499 9590 james_leigh
Connected to data
500 9419 james_leigh
> create object-native.
501 james_leigh
Please specify values for the following variables:
502 james_leigh
Repository ID [native]: foaf
503 james_leigh
Repository title [Native store]: FOAF Store
504 10691 james_leigh
Rollback if multiple states observed (enforce snapshot)? (false|true) [false]:
505 james_leigh
Rollback if outdated state observed (enforce serializable)? (false|true) [false]:
506 james_leigh
Changeset namespace [urn:trx:localhost:]:
507 10840 james_leigh
Archive all removed data (false|true) [false]:
508 james_leigh
If not, archive transactions with removed triples less than [100]:
509 10691 james_leigh
Minimum recent transactions [100]:
510 james_leigh
Maximum recent transactions [1000]:
511 james_leigh
Triple indexes [spoc,posc]:
512 james_leigh
Max Query Time [0]:
513 james_leigh
Default Query Language [SPARQL]:
514 9419 james_leigh
Ontology [http://www.w3.org/2002/07/owl]: http://xmlns.com/foaf/spec/index.rdf
515 9596 james_leigh
Read Schema from Repository [false]:
516 9419 james_leigh
Repository created
517 10691 james_leigh
 
518 9419 james_leigh
> quit.
519 9590 james_leigh
Disconnecting from data
520 9419 james_leigh
Bye
521 james_leigh
+--
522 james_leigh
 
523 james_leigh
 Scripts can be streamlined by allowing the ObjectRepository to compile
524 11769 james_leigh
 the ontology. Shown in Figure 14 is jrunscript (in
525 9419 james_leigh
 JavaScript) that outputs a new FOAF file, demonstrating how RDF/Objects
526 james_leigh
 can be used without compiling Java files.
527 james_leigh
 
528 11769 james_leigh
 <<Figure 14. JRunScript and ObjectRepository>>
529 9419 james_leigh
 
530 james_leigh
+--
531 9974 james_leigh
$ jrunscript -J-Djava.ext.dirs=lib:dist
532 9590 james_leigh
js> var rm = org.openrdf.repository.manager.RepositoryProvider.getRepositoryManager("data")
533 9419 james_leigh
js> var repo = rm.getRepository("foaf")
534 james_leigh
js> var con = repo.getConnection()
535 10691 james_leigh
js> con.setAutoCommit(false)
536 james_leigh
js> var Person = "http://xmlns.com/foaf/0.1/Person"
537 james_leigh
js> var base = "http://example.com/person/"
538 james_leigh
js> var james = con.addDesignation(con.getObject(base+"james"), Person)
539 9977 james_leigh
js>
540 11496 james_leigh
js> james.foafFirstName.add("James")
541 james_leigh
js> james.foafSurname.add("Leigh")
542 james_leigh
js> james.foafInterest.add("RDF")
543 10691 james_leigh
js> var arjohn = con.addDesignation(con.getObject(base+"arjohn"), Person)
544 11496 james_leigh
js> arjohn.foafFirstName.add("Arjohn")
545 9434 james_leigh
js> james.foafKnows.add(arjohn)
546 9977 james_leigh
js>
547 10691 james_leigh
js> con.setNamespace("foaf", "http://xmlns.com/foaf/0.1/")
548 9419 james_leigh
js> con['export'](new org.openrdf.rio.rdfxml.RDFXMLWriter(java.lang.System.out), [])
549 james_leigh
<?xml version="1.0" encoding="UTF-8"?>
550 james_leigh
<rdf:RDF
551 james_leigh
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
552 james_leigh
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
553 james_leigh
 
554 9434 james_leigh
<rdf:Description rdf:about="http://meta.leighnet.ca/data/rdf/2009/foaf/james">
555 9419 james_leigh
    <rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person"/>
556 james_leigh
    <foaf:firstName>James</foaf:firstName>
557 james_leigh
    <foaf:surname>Leigh</foaf:surname>
558 james_leigh
    <foaf:interest>RDF</foaf:interest>
559 james_leigh
    <foaf:knows rdf:resource="http://meta.leighnet.ca/data/rdf/2009/foaf/arjohn"/>
560 james_leigh
</rdf:Description>
561 james_leigh
 
562 james_leigh
<rdf:Description rdf:about="http://meta.leighnet.ca/data/rdf/2009/foaf/arjohn">
563 james_leigh
    <rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person"/>
564 james_leigh
    <foaf:firstName>Arjohn</foaf:firstName>
565 james_leigh
</rdf:Description>
566 james_leigh
 
567 james_leigh
</rdf:RDF>
568 james_leigh
js> con.close()
569 james_leigh
+--
570 9973 james_leigh
 
571 9974 james_leigh
Message Vocabulary
572 9973 james_leigh
 
573 10951 james_leigh
 In addition to the RDFS and OWL vocabulary, the object repository also supports
574 11769 james_leigh
 its own vocabulary for declaring methods (describing messages). This vocabulary
575 james_leigh
 can be used to declare interface methods. These abstract methods or message classes
576 10951 james_leigh
 can be created by extending the class msg:Message and creating restrictions for
577 james_leigh
 its msg:target and response properties (msg:object msg:objectSet msg:literal
578 11769 james_leigh
 msg:literalSet).
579 james_leigh
 
580 james_leigh
 Method annotations and parameter annotations can be added to the generated
581 james_leigh
 interfaces by using OWL annotation properties. Generated Java annotations
582 james_leigh
 are created with String array values.
583 james_leigh
 
584 james_leigh
 To add the @Sparql annotation use the OWL annotation property msg:sparql on
585 james_leigh
 the message class.
586 9974 james_leigh
 
587 11769 james_leigh
 Show in
588 james_leigh
 Figure 15 is a sample of what a message might look like in turtle.
589 james_leigh
 
590 james_leigh
 <<Figure 15. Sample Usage of Message Vocabulary>>
591 9973 james_leigh
 
592 9974 james_leigh
+--
593 james_leigh
@prefix xsd:<http://www.w3.org/2001/XMLSchema#>.
594 james_leigh
@prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#>.
595 james_leigh
@prefix owl:<http://www.w3.org/2002/07/owl#>.
596 10835 james_leigh
@prefix msg:<http://www.openrdf.org/rdf/2011/messaging#>.
597 11769 james_leigh
@prefix :<http://example.com/rdf/2012/example#>.
598 9973 james_leigh
 
599 9974 james_leigh
# Declare classes and properties for this example
600 11769 james_leigh
:Mammal rdfs:subClassOf owl:Thing.
601 9974 james_leigh
:Person rdfs:subClassOf :Mammal.
602 james_leigh
:Dog rdfs:subClassOf :Mammal.
603 james_leigh
 
604 11769 james_leigh
:dateOfBirth a owl:FunctionalProperty, owl:DatatypeProperty;
605 9974 james_leigh
    rdfs:domain :Mammal;
606 james_leigh
    rdfs:range xsd:date.
607 james_leigh
 
608 9977 james_leigh
# Common message that responds with the current date time
609 10835 james_leigh
:GetCurrentTime rdfs:subClassOf msg:Message;
610 11769 james_leigh
    rdfs:subClassOf [owl:onProperty msg:target; owl:allValuesFrom :Mammal];
611 10835 james_leigh
    rdfs:subClassOf [owl:onProperty msg:literal; owl:allValuesFrom xsd:dateTime];
612 11769 james_leigh
    msg:sparql "SELECT (now() AS ?now) {}".
613 9974 james_leigh
 
614 11769 james_leigh
# Declare method that take a date time and responds with the mammal's age at that time
615 james_leigh
# This message uses the parameter "when" as a query parameter
616 james_leigh
:GetAgeAt rdfs:subClassOf msg:Message;
617 james_leigh
    rdfs:subClassOf [owl:onProperty msg:target; owl:allValuesFrom :Mammal];
618 james_leigh
    rdfs:subClassOf [owl:onProperty msg:literal; owl:allValuesFrom xsd:integer];
619 james_leigh
    msg:sparql """
620 james_leigh
        PREFIX :<http://example.com/rdf/2012/example#>
621 james_leigh
        SELECT DISTINCT ((year($when) - year(?birth)) AS ?age) {
622 james_leigh
            $this :dateOfBirth ?birth
623 james_leigh
        }
624 9974 james_leigh
    """.
625 james_leigh
 
626 11769 james_leigh
:when a owl:FunctionalProperty, owl:DatatypeProperty;
627 james_leigh
    rdfs:domain :GetAgeAt;
628 9974 james_leigh
    rdfs:range xsd:dateTime.
629 james_leigh
 
630 james_leigh
# Dog's age is calculated differently than other mammals
631 11769 james_leigh
# This message is a specialization of the previous and overrides it for all dogs
632 james_leigh
:GetDogAgeAt owl:intersectionOf (:GetAgeAt [owl:onProperty msg:target; owl:allValuesFrom :Dog]);
633 james_leigh
    msg:sparql """
634 james_leigh
        PREFIX :<http://example.com/rdf/2012/example#>
635 james_leigh
        SELECT DISTINCT ((year($when) * 7 - year(?birth) * 7) AS ?age) {
636 james_leigh
            $this :dateOfBirth ?birth
637 9974 james_leigh
        }
638 james_leigh
    """.
639 james_leigh
 
640 james_leigh
# Some sample data to test with
641 james_leigh
:jack a :Dog;
642 james_leigh
    :dateOfBirth "2005-02-18"^^xsd:date.
643 james_leigh
 
644 james_leigh
:mel a :Person;
645 james_leigh
    :dateOfBirth "1956-01-03"^^xsd:date.
646 james_leigh
 
647 james_leigh
:lucia a :Person;
648 james_leigh
    :dateOfBirth "2009-10-30"^^xsd:date.
649 james_leigh
+--
650 james_leigh
 
651 11769 james_leigh
 When an object repository is set to use the Ontology in Figure 15, the
652 11797 james_leigh
 repository in Figure 16 can be used to evaluate the messages and calculate the
653 11769 james_leigh
 age as shown in Figure 17. Since an empty prefix was used in the ontology, no prefix is used when
654 james_leigh
 calling messages (or properties). If the schema changes at runtime the method
655 james_leigh
 ObjectConnection#recompileSchemaOnClose() should be called to compile the
656 james_leigh
 changes within the ObjectConnection#close() method.
657 9974 james_leigh
 
658 11769 james_leigh
 <<Figure 16. Creating ObjectRepository from the Console>>
659 9974 james_leigh
 
660 james_leigh
+--
661 10840 james_leigh
Commands end with '.' at the end of a line
662 james_leigh
Type 'help.' for help
663 james_leigh
> connect data.
664 james_leigh
Disconnecting from default data directory
665 james_leigh
Connected to data
666 james_leigh
> create object-native.
667 james_leigh
Please specify values for the following variables:
668 james_leigh
Repository ID [native]: mammals
669 james_leigh
Repository title [Native store]: Mammal Store
670 james_leigh
Rollback if multiple states observed (enforce snapshot)? (false|true) [false]:
671 james_leigh
Rollback if outdated state observed (enforce serializable)? (false|true) [false]:
672 james_leigh
Changeset namespace [urn:trx:localhost:]:
673 james_leigh
Archive all removed data (false|true) [false]:
674 james_leigh
If not, archive transactions with removed triples less than [100]:
675 james_leigh
Minimum recent transactions [100]:
676 james_leigh
Maximum recent transactions [1000]:
677 james_leigh
Triple indexes [spoc,posc]:
678 james_leigh
Max Query Time [0]:
679 james_leigh
Default Query Language [SPARQL]:
680 james_leigh
Ontology [http://www.w3.org/2002/07/owl]:
681 james_leigh
Read Schema from Repository [false]: true
682 james_leigh
Repository created
683 james_leigh
 
684 james_leigh
> open mammals.
685 james_leigh
Opened repository 'mammals'
686 11769 james_leigh
mammals> load mammal.ttl.
687 10840 james_leigh
Loading data...
688 james_leigh
Data has been added to the repository (3048 ms)
689 james_leigh
mammals> quit.
690 james_leigh
Closing repository 'mammals'...
691 james_leigh
Disconnecting from data
692 james_leigh
Bye
693 james_leigh
+--
694 james_leigh
 
695 11769 james_leigh
 <<Figure 17. Calling Object Messages from JavaScript>>
696 10840 james_leigh
 
697 james_leigh
+--
698 james_leigh
$ jrunscript -J-Djava.ext.dirs=lib:dist
699 james_leigh
js> var rm = org.openrdf.repository.manager.RepositoryProvider.getRepositoryManager("data")
700 james_leigh
js> var repo = rm.getRepository("mammals")
701 9974 james_leigh
js> var con = repo.getConnection()
702 11769 james_leigh
js> var jack = con.getObject("http://example.com/rdf/2012/example#jack")
703 james_leigh
js> var mel = con.getObject("http://example.com/rdf/2012/example#mel")
704 james_leigh
js> var lucia = con.getObject("http://example.com/rdf/2012/example#lucia")
705 james_leigh
js> var now = jack.GetCurrentTime()
706 james_leigh
js> jack.GetAgeAt(now)
707 james_leigh
49
708 james_leigh
js> mel.GetAgeAt(now)
709 james_leigh
56
710 james_leigh
js> lucia.GetAgeAt(now)
711 james_leigh
3
712 9974 james_leigh
js> con.close()
713 james_leigh
+--
714 james_leigh
 
715 9419 james_leigh
 The ObjectRepository simplifies interacting with RDF resources in OO
716 james_leigh
 languages on the JVM. By bridging RDF properties and object properties,
717 james_leigh
 creating and manipulating RDF resources is as easy as manipulating objects.
718 james_leigh
 
719 9486 james_leigh