# introduction

This document summarises API changes in Jena2. Many of these changes are additions, but there are some removals and incompatible changes.

# Statement.set

The Statement.set(X) methods have been removed. In its place we have the Statement.changeObject(X) methods. These methods update the model in the same way, but they do not alter the Statement object - they construct a new one and return it. This avoids certain technical difficulties which arose from having mutable Statement objects.

# the DAML interface

[To Be Done]

# namespace prefixes

Models now have associated prefix-namespace mappings. The readers notice any mappings in their input streams and add them to the model; the writers use those namespace prefixes (if appropriate) in their output.

The user may read and write the prefix mappings, either one at a time or from other PrefixMappings and Maps. Operations are provided that convert a URI to a QName (if possible) using the prefixes, and back the other way.

Model extends the interface PrefixMapping for the namespace methods; see the Javadoc for more details.

There is a "standard" set of prefix mappings (covering, in particular, rdf:, rdfs:, owl:, and daml:) in PrefixMapping.Standard.

# bulk update

The model API has been extended with "bulk update" operations which implementations of Model are expected to implement efficiently.

- add(Statement []) adds all of the statements in the array to the model.
- add(List) adds all of the statements in the List to the model. It is an error if any of the elements are not Statements.
- remove(Statement []) removes all of the statements in the array to the model.
- remove(List) removes all of the statements in the List to the model. It is an error if any of the elements are not Statements.

In addition, the existing add(Model) and remove(Model) implementations have been modified to use the bulk update interface if possible.

# Exceptions

The root of the Jena exception hierarchy is now com.hp.hpl.jena.shared.JenaException. RDFException still exists but will be deprecated and the error-code functionality it provided has been replaced by specific sub-classes of JenaException (so that they may be specifically caught). Look in .shared for most of these subclasses.

# inference support

[To Be Done]

# listStatements(S, P, O)

An extra version of listStatements taking separate subject, predicate, and object arguments is available. This avoids the user having to create a SimpleSelector in many cases.

# rdfNode.inModel(Model)

The RDFNode method inModel(Model m) constructs a version of the RDFNode that is "in" the model m and returns that node. If the RDFNode is a Literal, or already in m, then it is returned unchanged.

# Model::isEmpty()

Model's method isEmpty returns true if and only if the model is empty, that is, if size() would return 0 or listStatements() would return an empty iterator. Implementations of Model may be significantly more efficient than either of these alternatives.

# rdfNode.as(Class)

This method converts an RDFNode of one kind to another, if possible, throwing an exception if it cannot. The Class argument is the class of the interface that is being converted to. The boolean method canAs(Class) returns true iff it's possible to convert this resource to one of the given class.

# aModel.executeTransactionIn(Command cmd)

This new method executes the Command [defined in com.hp.hpl.jena.shared] within a new transaction. If the command fails (ie, throws an exception), then the transaction is aborted; otherwise it is committed. This operation is built on the transaction primitives.

# Resource.visitWith(RDFVisitor rv)

An RDFVisitor defines visitURI, visitBlank, and visitLiteral; the appropriate one of these is called when visitWith is run. Allows type-dependant decisions to be made about what to do to a Node without needing to dance around instanceof, and the "essential information" about the node (URI, AnonId, or Literal) to be obtained without casting.

# aModel.containsResource(RDFNode r)

This boolean method returns true iff r appears somewhere in aModel as the subject, predicate, or object of some statement.

# createResource(AnonId)

An extra createResource method is availble that creates a blank (anonymous) node with a specified AnonId.

# Resource.removeAll( Property p )

This method removes from the resource all the statements using the predicate `p`, and returns the resource.

# ModelFactory

ModelMem is obsolete. For a few-frills memory-based model, use ModelFactory.createDefaultModel() instead. [To Be Continued]

# reification

Statements are no longer Resources. Instead Statements can be converted into Resources using the asResource() method. These new Resources are ReifiedStatement objects. See the API proposal document for the moment.

# typed literals

[To Be Done]

# query

# [To Be Done - Chris is going to add a API for some of the fast-track query]

# iterators

Iterators now implement java.util.iterator, which means the .next() method returns an Object rather than a typed object. You need to either cast the return from the .next() method to the appropriate type or use the .nextType() (where Type is Resource, Literal, Ns, RDFNode or Statement depending on the iterator) to avoid casting.

# event handling

It is now possible to attach listeners to a Model. Each listener must implement ModelChangedListener and is informed of all statement-oriented updates to the model, ie add/remove of Statement, Statement[], List (of Statement), StmtIterator, or Model.

Convenience classes implementing ModelChangedListener are in .model's sibling package .listeners, including listeners that simply record that a change has occurred and listeners that convert all updates into single-statement adds and removes.

# I/O

See the IO mini HowTo.