7.3.6 Workspace Import Methods

The Workspace interface provides the following methods for importing content into the repository:

javax.jcr.
Workspace

ContentHandler

getImportContentHandler(
String parentAbsPath,
int uuidBehavior)

Returns an org.xml.sax.ContentHandler which can be used to push SAX events into the repository. If the incoming XML stream (in the form of SAX events) does not appear to be a system view XML document then it is interpreted as a document view XML document.

The incoming XML is deserialized into a subtree of items immediately below the node at parentAbsPath.

This method simply returns the ContentHandler without altering the state of the repository; the actual deserialization is done through the methods of the ContentHandler. Invalid XML data will cause the ContentHandler to throw a SAXException.

As SAX events are fed into the ContentHandler, changes are made directly at the workspace level, without going through the Session. As a result, there is not need to call save. The advantage of this direct-to-workspace method is that a large import will not result in a large cache of pending nodes in the Session. The disadvantage is that structures that violate node type constraints cannot be imported, fixed and then saved. Instead, a constraint violation will cause the ContentHandler to throw a SAXException. See Session.getImportContentHandler for a version of this method that does go through the Session.

The flag uuidBehavior governs how the UUIDs of incoming (deserialized) nodes are handled. There are four options (defined as constants in the interface javax.jcr.ImportUUIDBehavior):

  • IMPORT_UUID_CREATE_NEW: Incoming referenceable nodes are assigned newly created UUIDs upon addition to the workspace. As a result UUID collisions never occur.

  • IMPORT_UUID_COLLISION_REMOVE_EXISTING: If an incoming referenceable node has the same UUID as a node already existing in the workspace then the already existing node (and its subtree) is removed from wherever it may be in the workspace before the incoming node is added. Note that this can result in nodes “disappearing” from locations in the workspace that are remote from the location to which the incoming subtree is being written.

  • IMPORT_UUID_COLLISION_REPLACE_EXISTING: If an incoming referenceable node has the same UUID as a node already existing in the workspace, then the already existing node is replaced by the incoming node in the same position as the existing node. Note that this may result in the incoming subtree being disaggregated and “spread around” to different locations in the workspace. In the most extreme case this behavior may result in no node at all being added as child of parentAbsPath. This will occur if the topmost element of the incoming XML has the same UUID as an existing node elsewhere in the workspace.

  • IMPORT_UUID_COLLISION_THROW: If an incoming referenceable node has the same UUID as a node already existing in the workspace then a SAXException is thrown by the ContentHandler during deserialization.

A SAXException will be thrown by the returned ContentHandler during deserialization if the top-most element of the incoming XML would deserialize to a node with the same name as an existing child of parentAbsPath and that child does not allow same-name siblings.

A SAXException will also be thrown by the returned ContentHandler during deserialization if uuidBehavior is set to IMPORT_UUID_COLLISION_REMOVE_EXISTING and an incoming node has the same UUID as the node at parentAbsPath or one of its ancestors.

A PathNotFoundException is thrown if no node exists at parentAbsPath.

A ConstraintViolationException is thrown if the new subtree cannot be added to the node at parentAbsPath due to node-type or other implementation-specific constraints, and this can be determined before the first SAX event is sent.

Unlike Session.getImportContentHandler, this method will also enforce node type constraints by having the returned ContentHandler throw a SAXException during deserialization. However, which node type constraints are enforced depends upon whether node type information in the imported data is respected, and this is an implementation-specific issue (see 7.3.3 Respecting Property Semantics).

A VersionException is thrown if the node at parentAbsPath is versionable and checked-in, or is non-versionable but its nearest versionable ancestor is checked-in.

A LockException is thrown if a lock prevents the addition of the subtree.

An AccessDeniedException is thrown if the session associated with this Workspace object does not have sufficient permissions to perform the import.

A RepositoryException is thrown if another error occurs.

void

importXML(String parentAbsPath,
InputStream in,
int uuidBehavior)

Deserializes an XML document and adds the resulting item subtree as a child of the node at parentAbsPath.

If the incoming XML stream does not appear to be a system view XML document then it is interpreted as a document view XML document.

Changes are made directly at the workspace level, without going through the Session. As a result, there is not need to call save. The advantage of this direct-to-workspace method is that a large import will not result in a large cache of pending nodes in the Session. The disadvantage is that invalid data cannot be imported, fixed and then saved. Instead, invalid data will cause this method to throw an InvalidSerializedDataException. See Session.importXML for a version of this method that does go through the Session.

The flag uuidBehavior governs how the UUIDs of incoming (deserialized) nodes are handled. There are four options (defined as constants in the interface javax.jcr.ImportUUIDBehavior):

  • IMPORT_UUID_CREATE_NEW: Incoming referenceable nodes are assigned newly created UUIDs upon addition to the workspace. As a result UUID collisions never occur.

  • IMPORT_UUID_COLLISION_REMOVE_EXISTING: If an incoming referenceable node has the same UUID as a node already existing in the workspace then the already existing node (and its subtree) is removed from wherever it may be in the workspace before the incoming node is added. Note that this can result in nodes “disappearing” from locations in the workspace that are remote from the location to which the incoming subtree is being written.

  • IMPORT_UUID_COLLISION_REPLACE_EXISTING: If an incoming referenceable node has the same UUID as a node already existing in the workspace then the already existing node is replaced by the incoming node in the same position as the existing node. Note that this may result in the incoming subtree being disaggregated and “spread around” to different locations in the workspace. In the most extreme edge case this behavior may result in no node at all being added as child of parentAbsPath. This will occur if the topmost element of the incoming XML has the same UUID as an existing node elsewhere in the workspace.

  • IMPORT_UUID_COLLISION_THROW: If an incoming referenceable node has the same UUID as a node already existing in the workspace then an ItemExistsException is thrown.

An ItemExistsException will be thrown if the top-most element of the incoming XML would deserialize to a node with the same name as an existing child of parentAbsPath and that child does not allow same-name siblings.

An IOException is thrown if an I/O error occurs.

If no node exists at parentAbsPath, a PathNotFoundException is thrown.

If node-type or other implementation-specific constraints prevent the addition of the subtree, a ConstraintViolationException is thrown.

A ConstraintViolationException will also be thrown if uuidBehavior is set to IMPORT_UUID_COLLISION_REMOVE_EXISTING and an incoming node has the same UUID as the node at parentAbsPath or one of its ancestors.

A VersionException is thrown if the node at parentAbsPath is versionable and checked-in, or is non-versionable but its nearest versionable ancestor is checked-in.

A LockException is thrown if a lock prevents the addition of the subtree.

An AccessDeniedException is thrown if the session associated with this Workspace object does not have sufficient permissions to perform the import.

If another error occurs, a RepositoryException is thrown.