Configuration

Topaz being a persistence layer for the application, sits in between the persistence stores and the application. This means the configuration can be broadly categorized as the ones that are store related and the other that are application related.

In Topaz all configuration is stored in the SessionFactory. Therefore the starting point is creation of a SessionFactory instance:

import org.topazproject.otm.SessionFactory;
import org.topazproject.otm.impl.SessionFactoryImpl;
....
....
....
SessionFactory sessionFactory = new SessionFactoryImpl();

Configuring Stores

ItqlStore

Currently there is only one TripleStore implementation: org.topazproject.otm.stores.ItqlStore. ItqlStore makes use of ITQL as the query language. Currently only Mulgara supports ITQL.

Note: Recently Mulgara has added SPARQL support. However Topaz as of yet does not have a SPARQL client implementation.

The store configuration is as follows:

   sessionFactory.setTripleStore(new ItqlStore(serverUri));

From, the Javadoc for ItqlStore:

The server URI will take one of two forms:

The RMI scheme is used to access an external ITQL store. The hostname refers to the name of the computer that the store is running on. The server is the name of the server that ITQL store is providing. By default, Mulgara servers are run with a name of server1. So to access a server on the local machine, the URI might be rmi://localhost/server1.

The LOCAL scheme is used to access an embedded Mulgara database in the current JVM. The host name is null which leads to the root of the path coming immediately after the // characters. The server name is defined here in order to create the database, so it can be anything.

Creating named graphs

TripleStores are partitioned into named graphs to allow logical partitioning of RDF statements, In Mulgara, the named graphs fall under two categories:

  • System Graphs
  • Resolvers

The 'type' of the graph determines the Resolver involved or it can be null for System Graphs.

The graph identifier is a URI in Mulgara. So the {identifier, type} pair is needed for graph creations and then onwards just the identifier URI is sufficient to read, insert, delete statements or even to drop the graph.

In addition currently there are some restrictions on how graph identifier URIs can be built. It can only be built as the mulgara server URI with a fragment appended. For instance:

More recent versions of Mulgara have removed this restriction.

In addition to the {identifier URI, type URI} pair required by Mulgara, Topaz additionally allows applications to use a simple alias name to be used to refer to it. So a named graph in Topaz is configured as follows:

   String name = "users";
   URI identifier = URI.create("local:///myserver#users");
   URI type = null;

   GraphConfig gc = new GraphConfig(name, identifier, type);

   // Register this with Topaz
   sessionFactory.addGraph(gc);

It is also possible to configure this using java Annotations as explained in @Graph section.

If you are configuring a pre-existing named graph in Mulgara, your job is done at this point. However if you are configuring a new named graph, it must be created in Mulgara before it can be used.

For example the following bit of code will create the "users" graph that we just configured:

   Session session = sessionFactory.openSession();
   try {
     session.beginTransaction();
     session.createGraph("users");
     session.getTransaction().commit();
   } finally {
     try { session.close(); } catch (Throwable t) {}
   }

Note: Even though this section explained things from a Mulgara point of view, the GraphConfig is a generic concept expected to support other TripleStores also.

Configuring Prefix Resolver

As explained above, in Mulgara, resolvers allow special processing in Mulgara. One such resolver is the prefix-resolver. This is needed by Topaz to build queries that involve Rdf Containers.

In order for Topaz to make use of the Prefix Resolver, the application needs to configure that in Topaz. An application may use any identifier-URI or alias name for the prefix graph while configuring this. But it must be of type: http://mulgara.org/mulgara#PrefixGraph for Topaz and Mulgara to recognize this as a Prefix Resolver graph.

The following shows how the Prefix Resolver can be configured:

   String name = "prefix";
   URI identifier = URI.create("local:///myserver#prefix");
   URI type = URI.create("http://mulgara.org/mulgara#PrefixGraph");

   GraphConfig gc = new GraphConfig(name, identifier, type);

   sessionFactory.addGraph(gc);

As of Mulgara 2.0, the prefix Resolver will create a graph named sys:prefix by default. This means we can avoid the create-Graph step altogether. If you used any other identifier you would need to ensure that a graph with that identifier is created in Mulgara.

SimpleBlobStore

Currently there is only one BlobStore implementation: org.topazproject.otm.stores.SimpleBlobStore. SimpleBlobStore is an embedded store thar runs in the current JVM. It makes use of a directory in the local fileSystem as the root of the store. Each Blob is stored as a separate file underneath this root directory.

Notes:

  • There are no plans to add RMI support for SimpleBlobStore to work as a stand-alone server.
  • Instead, the Akubra project is the one that will provide blob-store implementations.
  • There is also a FedoraBlobStore implementation that stores the Blobs as Fedora 2.1 Server objects. However this usage is deprecated in favor of Akubra.

The store configuration is as follows:

   sessionFactory.setBlobStore(new SimpleBlobStore(root));

The root here is the root directory used by SimpleBlobStore to store the files corresponding to the Blobs.

Configuring Application Metadata

In order for Topaz to persist objects, Topaz needs to know:

  • the mapping information for the objects
  • the named graph in the TripleStore where object information is to be stored.

Mapping information for objects is split into :

  • Definition
  • Binder

Definition refers to information that is independent of the EntityMode?. This includes the RDF related configuration information such as rdf:type or the predicate-URI or the rdfs:range etc. These definitions are contained in org.topazproject.otm.metadata

Binding refers to how the values are bound to instances of application accessible objects. See Binder.

APIs exist on Topaz SessionFactory to register Definition and Binder objects. This is the core Topaz configuration API.

For EntityMode?.POJO, Topaz defines java annotations that simplifies this configuration. See Topaz/Manual/Section04 for these annotations and their equivalent SessionFactory API calls.

When using Java annotations, there are two ways to let Topaz know about the annotated classes:

  • Manual registration of each annotated class
  • Automatic registration by letting Topaz scan selected portions of the applications class-path.

Manual registration

An annotated class can be manually registered with Topaz as follows:

   sessionFactory.preload(clazz);
   ....
   ....
   // before starting to use the configuration, must call validate()
   sessionFactory.validate();

Here the clazz is any class that the application wishes to persist in the database.

Notes:

  • preload() will recursively preload() all implemented interfaces and the super-class of the given class.
  • All java package level annotations are also picked up by preload(). This would mean anything in the package-info.java. This is how URI [<insert-link> aliases] and [<insert-link> graph configurations] are picked up.

WARN:

  • URI aliases are expanded during preload(). Therefore it is important to ensure that all aliases that are used in the annotations (eg. @Predicate(uri='dc:creator ....)) are registered in the SessionFactory prior to its usage. It is usually better to do this by adding all alias definitions in the package-info.java file. Topaz processes package level annotations before processing the class level ones. An example can be found at: Topaz/Manual/Section01/01#Thepackage-info.javafile
  • All Serializers for literal values must also be defined before preload(). Please see Literal values to learn how to define custom Serializers.

Automatic registration

Automatic registration avoids the trouble for applications to call preload() explicitly and instead allows Topaz to scan selected portions of the class-path to look for classes to be preloaded. Applications can initiate this scan as follows:

   sessionFactory.preloadFromClasspath();
   ....
   ....
   // before starting to use the configuration, must call validate()
   sessionFactory.validate();

This method looks for a marker file as a resource, and then performs scans in that part of the classpath. The default marker is the file topaz.xml. An example can be found at Topaz/Manual/Section01/01#Thetopaz.xmlfile

It is possible to override this:

  sessionFactory.preloadFromClasspath(path);
   ....
   ....
   // before starting to use the configuration, must call validate()
   sessionFactory.validate();

The path parameter here can be a marker file, or even a package root directory, such as "org" or "org/topazproject".

  sessionFactory.preloadFromClasspath("com/my/project/models");
  sessionFactory.preloadFromClasspath("org/topazproject");
   ....
   ....
   // before starting to use the configuration, must call validate()
   sessionFactory.validate();

Classes are only preloaded if the class is marked with any of the following annotations: