The intention is to be able to specify how a model is constructed using a configuration file, input stream, URL, or other way of getting RDF into a Jena process, and for this configuration to be capable of specifying anything that the ModelFactory class can construct.
A more formal document is available: the ModelSpec design document. Here we concentrate on how to use ModelSpecs in general.
The ModelSpec descriptions use the Jena Model Specification
vocabulary, which is available in the vocabulary class JMS
and which will be referred to using the prefix jms
.
Jena defines this vocabulary namespace as
http://jena.hpl.hp.com/2003/08/jms#
Shared
to allow values to be
shared by specifications.
ModelSpec
s are created by calling one of the ModelFactory
methods named createSpec
, which create a ModelSpec from
an RDF description. There are three variants of createSpec
:
m
rooted at r
. The resource r
identifies
the model specification. Model specifications are described in
detail in [A LATER SECTION].
m
rooted at the unique resource with type
jms:ModelSpec
.
createSpec( r, r.getModel() )
.
createModel()
: create a new model according to
the specification. This method is used by
ModelFactory.createModel(ModelSpec)
. You may need
to cast this model to the appropriate type - in particular,
if you're expecting an OntModel
.
[Should we provide createOntModel and createInfModel as wrappers for these cases?]
createModelOver(String name)
: most ModelSpec
s
have an underlying
ModelMaker
. This method creates a new Model where
any underlying Model has the given name
in that ModelMaker.
For particularly simple ModelSpec
s, the result is that
Model. The usual case of interest is when the ModelSpec creates
models in a database.
getDescription()
: returns an RDF description which
describes this ModelSpec. If the original RDF description had no
superfluous statements, this model is likely "the same" as that
original, ie isomorphic. This is a useful way to save an RDF
description to be used in a later createSpec
.
_:this rdf:type jms:DefaultModelSpec .This will construct a default model (ie the same kind of Model that
ModelFactory.createDefaultModel()
will construct). If anything more complicated that this is
required, then a model maker must be specified.
_:this jms:maker _:maker .It happens that this specificiation, where a model maker is identified but not further described, also produces a ModelSpec that makes default models. Pick whichever you find most pleasing.
If you wish to create models with different reification styles, then the maker can specify the style explicitly.
_:this jms:maker _:maker . _:maker jms:reificationStyle jms:rsMinimal .This will produce models which have the minimal reification style. (For an explanation of the different styles, see THAT DOCUMENT.
This fragment may disappear if we can eliminate reification styles completely.])
fileBase
, the directory in which the
file is found, has to be specified.
_:this jms:maker _:maker . _:maker jms:fileBase "/tmp" .Filing-system names are of course implementation-specific, so if you expect to move
fileBase
-using ModelSpecs
between systems, take care.
A file-based ModelSpec can use createModelOver(String s)
to create models loaded from the file whose name is s
within the fileBase
. If the file does not exist, the
model will initially be empty, but will be written back when closed.
Of course, a refication style can be specified as well as a filebase. There is no need for a file-based model to be opened with the same style each time it is used - the reification style is not preserved.
_:this jms:maker _:maker . _:maker jms:reificationMode jms:rsStandard . _:maker jms:hasConnection _:conn . _:conn jms:dbURL "jdbc:mysql://some.database.machine.eg/jenaDB" . _:conn jms:dbUser "william.blake" . _:conn jms:dbPassword "tyger, tyger" . _:conn jms:dbType "MySQL" .The model-maker is specified as being a Jena RDB model-maker by the
hasConnection
. Several models may share the same
(or similar) connections.
The connection URL specifies the database to connect to; the same
database can support many different Jena models. The user and password
are required to (weakly) authenticate the connection. The type is
required so that the correct database drivers can be loaded. Note
the (in-)security implications of the database password being stored
in plain text in the ModelSpec description document - these are
partly bypassed by using the shared
property discussed
later.
[Should contact Chris Bizer and ask him about the connections to databases needed for his RDB-to-graph connection.]
[Leave placeholder for BDB connections?]
_:this jms:maker _:maker . _:this jms:reasonsWith _:reasoner . _:reasoner jms:reasoner <http://jena.hpl.hp.com/2003/RDFSExptRuleReasoner> .
[check that the URI remains correct]
This is the simplest reasoner specification - just giving the URL of the reasoner. Any other properties of the reasoner take on its usual defaults (see [THE REASONER DOCUENTATION]).
Reasoners may be supplied with a schema or schemas as the "initial base" for their reasoning - for example, an RDFS reasoner may be given an RDFS schema and do sub-type reasoning in advance of being applied to a particular model. Schemas can be specified by giving their URLs.
_:reasoner jms:schemaURL <http://some.domain.xyz/RDFS/cunning> .If several schemas are supplied, they are merged into a single schema to feed to the reasoner.
Similarly, a schema can be specified using a ModelSpec. [Discussed later, when we've sorted out the unresolved issue of model specs that identify particular models.]
_:reasoner jms:schema _:modelSpec .If the reasoner is a rule-based reasoner, it may be loaded with additional rules. Those rules may be specified in the ModelSpec description, or be identified by URL.
_:reasoner jms:ruleSetURL <http://some.domain.xyz/RULES/straight> .The URL identifies a resource containing the rules, written in an appropriate notation. Several
ruleSetURL
s may be
given; all the rules are loaded into the reasoner in no particular
order.
[The weasel-wording about "an appropriate notation" is to cover that we only have the one rule-based reasoning engine with the single surface syntax, wheras we ought to conver more options. The reasoner should be in charge of parsing the rules. Also we have only the one internal Rule class, but it's possible we should allow user-definable classes, or else hide Rule as a detail of our implementation.]
Similarly,
_:reasoner jms:ruleSet _:set .specifies a set of rules located elsewhere in this specification, as properties of
_:set
. Multiple such ruleSet
s
can be given, and they my be freely mixed with ruleSetURL
s.
_:set rdf:type jms:RuleSet .which may be useful as a placeholder (or a leftover from pruning away rulesets). Additional rules may be specified inline or by URL:
_:set jms:hasRule "some proper rule text here" . _:set jms:ruleSetURL <http://some.domain/RULES/example> .Both
hasRule
and ruleSetURL
may be
present as often as required. Since both predicates have
domain RuleSet
, the type declaration may be
omitted.
[If ruleSet
is given range RuleSet
,
then the type declaration is always unnecessary. I'm a bit
worried that this makes it easy to forget or mislabel a ruleset.]
[Again, we weasel about the notation in which the rules are
expressed. Possibly a jms:ruleLanguage
property?]
_:this jms:importMaker _:conn . _:this jms:ontLanguage "http://www.w3.org/TR/owl-features/#term_OWLLite" . _:this jms:docManager _:DM . _:this jms:reasonsWith _:R . _:R jms:reasoner http://jena.hpl.hp.com/2003/RDFSExptRuleReasoner .specifies OntModels for the OWL Lite language, using the RDFS rule-based reasoner. The OntModels will take their base models from the database. The document manager has been given no specific properties, so the default document manager will be used.
[More stuff needed for OntModels here]
Any sub-specification can be made shared by giving it the
Shared
type:
_:conn rdf:type jms:Shared .When a component of type
Shared
is requested, if there
is already a Shared
component created from equivalent RDF,
then that component is returned rather than a new component being
created.
The method ModelFactory.share( Resource r, Object o )
declares that the resource r
, which must have RDF type
Shared
, has shared value o
. Any modelspec
component whose description matches r
will resolve to
the value o
.
By "equivalent RDF" we mean that the submodels reachable from
r
are isomorphic.
So, for the database connection example, the resource
_:conn
can be declared shared in the user's application,
without the user's database name and password appearing in the ModelSpec.