/*
* Copyright 2006 Day Management AG, Switzerland. All rights reserved.
*/
package javax.jcr;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import javax.jcr.lock.LockException;
import javax.jcr.lock.Lock;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.version.VersionException;
import javax.jcr.security.AccessControlManager;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* The <code>Session</code> object provides read and (in level 2) write access to the content of a
* particular workspace in the repository.
* <p/>
* The <code>Session</code> object is returned by {@link Repository#login(Credentials, String) Repository.login()}.
* It encapsulates both the authorization settings of a particular user (as specified by the
* passed <code>Credentials</code>) and a binding to the workspace specified by the
* <code>workspaceName</code> passed on <code>login</code>.
* <p/>
* Each <code>Session</code> object is associated one-to-one with a <code>Workspace</code> object.
* The <code>Workspace</code> object represents a "view" of an actual repository workspace entity
* as seen through the authorization settings of its associated <code>Session</code>.
*/
public interface Session {
/**
* Returns the <code>Repository</code> object through which this session was
* acquired.
*
* @return a <code>{@link Repository}</code> object.
*/
public Repository getRepository();
/**
* Gets the user ID associated with this <code>Session</code>. How the
* user ID is set is up to the implementation, it may be a string passed in
* as part of the credentials or it may be a string acquired in some other
* way. This method is free to return an "anonymous user ID" or
* <code>null</code>.
*
* @return the user ID associated with this <code>Session</code>.
*/
public String getUserID();
/**
* Returns the names of the attributes set in this session as a result of the
* <code>Credentials</code> that were used to acquire it. Not all
* <code>Credentials</code> implementations will contain attributes (though,
* for example, <code>SimpleCredentials</code> does allow for them). This
* method returns an empty array if the <code>Credentials</code> instance did
* not provide attributes.
*
* @return A string array containing the names of all attributes passed in
* the credentials used to acquire this session.
*/
public String[] getAttributeNames();
/**
* Returns the value of the named attribute as an <code>Object</code>, or
* <code>null</code> if no attribute of the given name exists.
* See {@link Session#getAttributeNames}.
*
* @param name the name of an attribute passed in the credentials used to
* acquire this session.
*
* @return the value of the attribute or <code>null</code> if no attribute
* of the given name exists.
*/
public Object getAttribute(String name);
/**
* Returns the <code>Workspace</code> attached to this <code>Session</code>.
*
* @return a <code>{@link Workspace}</code> object.
*/
public Workspace getWorkspace();
/**
* Returns the root node of the workspace, "/". This node is the main
* access point to the content of the workspace.
* <p/>
* A <code>RepositoryException</code> is thrown if an error occurs.
*
* @return The root node of the workspace: a <code>{@link Node}</code> object.
*
* @throws RepositoryException if an error occurs.
*/
public Node getRootNode() throws RepositoryException;
/**
* Returns a new session in accordance with the specified (new) Credentials.
* Allows the current user to "impersonate" another using incomplete or
* relaxed credentials requirements (perhaps including a user name but no
* password, for example), assuming that this <code>Session</code> gives
* them that permission.
* <p/>
* The new <code>Session</code> is tied to a new <code>Workspace</code> instance.
* In other words, <code>Workspace</code> instances are not re-used. However,
* the <code>Workspace</code> instance returned represents the same actual
* persistent workspace entity in the repository as is represented by the
* <code>Workspace</code> object tied to this <code>Session</code>.
* <p/>
* A <code>LoginException</code> is thrown if this session does not have
* sufficient permissions to perform the operation.
* <p/>
* A <code>RepositoryException</code> is thrown if another error occurs.
*
* @param credentials A <code>Credentials</code> object
* @return a <code>Session</code> object
* @throws LoginException if the current session does not have sufficient
* permissions to perform the operation.
* @throws RepositoryException if another error occurs.
*/
public Session impersonate(Credentials credentials) throws LoginException, RepositoryException;
/**
* Returns the node specifed by the given UUID. Only applies to nodes that
* expose a UUID, in other words, those of mixin node type
* <code>mix:referenceable</code>
*
* @deprecated As of JCR 2.0, {@link #getNodeByIdentifier(String)} should
* be used instead.
*
* @param uuid A universally unique identifier.
* @return A <code>Node</code>.
* @throws ItemNotFoundException if the specified UUID is not found.
* @throws RepositoryException if another error occurs.
*/
public Node getNodeByUUID(String uuid) throws ItemNotFoundException, RepositoryException;
/**
* Returns the node specified by the given identifier. Applies to both
* referenceable and non-referenceable nodes.
* <p/>
* An <code>ItemNotFoundException</code> is thrown if no node with the
* specified identifier exists. This exception is also thrown if this
* <code>Session<code> does not have read access to the node with the
* specified identifier.
* <p/>
* A <code>RepositoryException</code> is thrown if another error occurs.
*
* @param id An identifier.
* @return A <code>Node</code>.
* @throws ItemNotFoundException if the specified identifier is not found.
* @throws RepositoryException if another error occurs.
* @since JCR 2.0
*/
public Node getNodeByIdentifier(String id) throws ItemNotFoundException, RepositoryException;
/**
* Returns the node at the specified absolute path in the workspace.
* If no such node exists, then it returns the property at the specified path.
* If no such property exists a <code>PathNotFoundException</code> is thrown.
* <p/>
* This method should only be used if the application does not know whether
* the item at the indicated path is property or node. In cases where the
* application has this information, either {@link #getNode} or
* {@link #getProperty} should be used, as appropriate. In many repository
* implementations the node and property-specific methods are likely to be
* more efficient than <code>getItem</code>.
* <p/>
* A <code>RepositoryException</code> is thrown if another error occurs.
*
* @param absPath An absolute path.
* @return the specified <code>Item</code>.
* @throws PathNotFoundException if the specified path cannot be found.
* @throws RepositoryException if another error occurs.
*/
public Item getItem(String absPath) throws PathNotFoundException, RepositoryException;
/**
* Returns the node at the specified absolute path in the workspace.
* If no node exists, then a <code>PathNotFoundException</code> is thrown.
*
* @param absPath An absolute path.
* @return the specified <code>Node</code>.
* @throws PathNotFoundException If no node exists.
* @throws RepositoryException If another error occurs.
* @since JCR 2.0
*/
public Node getNode(String absPath) throws PathNotFoundException, RepositoryException;
/**
* Returns the property at the specified absolute path in the workspace.
* If no property exists, then a <code>PathNotFoundException</code> is thrown.
*
* @param absPath An absolute path.
* @return the specified <code>Property</code>.
* @throws PathNotFoundException If no property exists.
* @throws RepositoryException if another error occurs.
* @since JCR 2.0
*/
public Property getProperty(String absPath) throws PathNotFoundException, RepositoryException;
/**
* Returns <code>true</code> if an item exists at <code>absPath</code>
* and this <code>Session</code> has read access to it; otherwise returns
* <code>false</code>.
* <p/>
* Throws a <code>RepositoryException</code> if <code>absPath</code> is not
* a well-formed absolute path.
*
* @param absPath An absolute path.
* @return a <code>boolean</code>
* @throws RepositoryException if <code>absPath</code> is not a well-formed
* absolute path.
*/
public boolean itemExists(String absPath) throws RepositoryException;
/**
* Returns <code>true</code> if a node exists at <code>absPath</code>
* and this <code>Session</code> has read access to it; otherwise returns
* <code>false</code>.
* <p/>
* Throws a <code>RepositoryException</code> if <code>absPath</code>
* is not a well-formed absolute path.
*
* @param absPath An absolute path.
* @return a <code>boolean</code>
* @throws RepositoryException if <code>absPath</code> is not a well-formed
* absolute path.
* @since JCR 2.0
*/
public boolean nodeExists(String absPath) throws RepositoryException;
/**
* Returns <code>true</code> if a property exists at <code>absPath</code>
* and this <code>Session</code> has read access to it; otherwise returns
* <code>false</code>.
* <p/>
* Throws a <code>RepositoryException</code> if <code>absPath</code>
* is not a well-formed absolute path.
*
* @param absPath An absolute path.
* @return a <code>boolean</code>
* @throws RepositoryException if <code>absPath</code> is not a well-formed
* absolute path.
* @since JCR 2.0
*/
boolean propertyExists(String absPath) throws RepositoryException;
/**
* Moves the node at <code>srcAbsPath</code> (and its entire subtree) to the
* new location at <code>destAbsPath</code>. Returns the path of the node at
* its new position. Note that the returned path will indicate the resulting
* same-name sibling index of the destination (if necessary), unlike the
* supplied <code>destAbsPath</code> parameter (see below).
* <p>
* In order to persist the change, a <code>save</code>
* must be called on either the session or a common ancestor to both the source and destination locations.
* <p/>
* The identifiers of referenceable nodes must not be changed by a
* <code>move</code>. The identifiers of non-referenceable nodes <i>may</i> change.
* <p/>
* A <code>ConstraintViolationException</code> is thrown either immediately or on <code>save</code>
* if performing this operation would violate a node type or implementation-specific constraint.
* Implementations may differ on when this validation is performed.
* <p>
* As well, a <code>ConstraintViolationException</code> will be thrown on
* <code>save</code> if an attempt is made to seperately <code>save</code>
* either the source or destination node.
* <p>
* Note that this behaviour differs from that of
* {@link Workspace#move}, which operates directly in the persistent
* workspace and does not require a <code>save</code>.
* <p/>
* The <code>destAbsPath</code> provided must not have an index on its final
* element. If it does then a <code>RepositoryException</code> is thrown.
* Strictly speaking, the <code>destAbsPath</code> parameter is actually an
* <i>absolute path</i> to the parent node of the new location, appended
* with the new <i>name</i> desired for the moved node. It does not specify
* a position within the child node ordering (if such ordering is
* supported). If ordering is supported by the node type of the parent node
* of the new location, then the newly moved node is appended to the end of
* the child node list. The resulting position within a same-name sibling set
* can, however, be determined from the path returned by this method, which
* will include an index if one is required.
* <p/>
* This method cannot be used to move just an individual property by itself.
* It moves an entire node and its subtree (including, of course, any properties
* contained therein).
* <p/>
* If no node exists at <code>srcAbsPath</code> or no node exists one level above <code>destAbsPath</code>
* (in other words, there is no node that will serve as the parent of the moved item) then a
* <code>PathNotFoundException</code> is thrown either immediately or on <code>save</code>.
* Implementations may differ on when this validation is performed.
* <p/>
* An <code>ItemExistsException</code> is thrown either immediately or on <code>save</code>
* if a node already exists at <code>destAbsPath</code> and same-name siblings are not allowed.
* Implementations may differ on when this validation is performed.
* <p/>
* Note that if a property already exists at <code>destAbsPath</code>, the
* operation succeeds, since a node may have a child node and property with
* the same name.
* <p/>
* A <code>VersionException</code> is thrown either immediately or on <code>save</code>
* if the parent node of <code>destAbsPath</code> or the parent node of <code>srcAbsPath] is versionable and
* checked-in, or is non-versionable and its nearest versionable ancestor is checked-in.
* Implementations may differ on when this validation is performed.
* <p/>
* A <code>LockException</code> is thrown either immediately or on <code>save</code>
* if a lock prevents the <code>move</code>. Implementations may differ on when this validation is performed.
*
* @param srcAbsPath the root of the subtree to be moved.
* @param destAbsPath the location to which the subtree is to be moved.
* @return the path of the node at its new position.
* @throws ItemExistsException if a node already exists at <code>destAbsPath</code>
* and same-name siblings are not allowed.
* @throws PathNotFoundException if either <code>srcAbsPath</code> or <code>destAbsPath</code> cannot be found and this
* implementation performs this validation immediately instead of waiting until <code>save</code>.
* @throws VersionException if the parent node of <code>destAbsPath</code> or the parent node of <code>srcAbsPath</code>
* is versionable and checked-in, or or is non-verionable and its nearest versionable ancestor is checked-in and this
* implementation performs this validation immediately instead of waiting until <code>save</code>.
* @throws ConstraintViolationException if a node-type or other constraint violation is detected immediately and this
* implementation performs this validation immediately instead of waiting until <code>save</code>.
* @throws LockException if the move operation would violate a lock and this
* implementation performs this validation immediately instead of waiting until <code>save</code>.
* @throws RepositoryException if the last element of <code>destAbsPath</code> has an index or if another error occurs.
*/
public String move(String srcAbsPath, String destAbsPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException;
/**
* Validates all pending changes currently recorded in this <code>Session</code>. If validation of <i>all</i>
* pending changes succeeds, then this change information is cleared from the <code>Session</code>.
* If the <code>save</code> occurs outside a transaction, the changes are persisted and thus
* made visible to other <code>Sessions</code>. If the <code>save</code> occurs within a transaction,
* the changes are not persisted until the transaction is committed.
* <p/>
* If validation fails, then no pending changes are saved and they remain recorded on the <code>Session</code>.
* There is no best-effort or partial <code>save</code>.
* <p/>
* The item in persistent storage to which a transient item is saved is
* determined by matching identifiers and paths.
* <p/>
* An <code>AccessDeniedException</code> will be thrown if any of the changes
* to be persisted would violate the access privileges of this
* <code>Session</code>.
* <p/>
* If any of the changes to be persisted would cause the removal of a node
* that is currently the target of a <code>REFERENCE</code> property then a
* <code>ReferentialIntegrityException</code> is thrown, provided that this <code>Session</code> has
* read access to that <code>REFERENCE</code> property. If, on the other hand, this
* <code>Session</code> does not have read access to the <code>REFERENCE</code> property in question,
* then an <code>AccessDeniedException</code> is thrown instead.
* <p/>
* An <code>ItemExistsException</code> will be thrown if any of the changes
* to be persisted would be prevented by the presence of an already existing
* item in the workspace.
* <p/>
* A <code>ConstraintViolationException</code> will be thrown if any of the
* changes to be persisted would violate a node type restriction.
* Additionally, a repository may use this exception to enforce
* implementation- or configuration-dependant restrictions.
* <p/>
* An <code>InvalidItemStateException</code> is thrown if any of the
* changes to be persisted conflicts with a change already persisted
* through another session and the implementation is such that this
* conflict can only be detected at <code>save</code>-time and therefore was not
* detected earlier, at change-time.
* <p/>
* A <code>VersionException</code> is thrown if the <code>save</code> would make a result in
* a change to persistent storage that would violate the read-only status of a
* checked-in node.
* <p/>
* A <code>LockException</code> is thrown if the <code>save</code> would result
* in a change to persistent storage that would violate a lock.
* <p/>
* A <code>NoSuchNodeTypeException</code> is thrown if the <code>save</code> would result in the
* addition of a node with an unrecognized node type.
* <p/>
* A <code>RepositoryException</code> will be thrown if another error
* occurs.
*
* @throws AccessDeniedException if any of the changes to be persisted would violate
* the access privileges of the this <code>Session</code>. Also thrown if any of the
* changes to be persisted would cause the removal of a node that is currently
* referenced by a <code>REFERENCE</code> property that this Session
* <i>does not</i> have read access to.
* @throws ItemExistsException if any of the changes
* to be persisted would be prevented by the presence of an already existing
* item in the workspace.
* @throws ConstraintViolationException if any of the changes to be persisted would
* violate a node type or restriction. Additionally, a repository may use this
* exception to enforce implementation- or configuration-dependent restrictions.
* @throws InvalidItemStateException if any of the
* changes to be persisted conflicts with a change already persisted
* through another session and the implementation is such that this
* conflict can only be detected at <code>save</code>-time and therefore was not
* detected earlier, at change-time.
* @throws ReferentialIntegrityException if any of the
* changes to be persisted would cause the removal of a node that is currently
* referenced by a <code>REFERENCE</code> property that this <code>Session</code>
* has read access to.
* @throws VersionException if the <code>save</code> would make a result in
* a change to persistent storage that would violate the read-only status of a
* checked-in node.
* @throws LockException if the <code>save</code> would result in a
* change to persistent storage that would violate a lock.
* @throws NoSuchNodeTypeException if the <code>save</code> would result in the
* addition of a node with an unrecognized node type.
* @throws RepositoryException if another error occurs.
*/
public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException;
/**
* If <code>keepChanges</code> is <code>false</code>, this method discards all pending changes
* currently recorded in this <code>Session</code> and returns all items to reflect the current
* saved state. Outside a transaction this state is simply the current state of persistent storage.
* Within a transaction, this state will reflect persistent storage as modified by changes that have
* been saved but not yet committed.
* <p>
* If <code>keepChanges</code> is true then pending change are not discarded but items that do not
* have changes pending have their state refreshed to reflect the current saved state, thus revealing
* changes made by other sessions.
*
* @param keepChanges a boolean
* @throws RepositoryException if an error occurs.
*/
public void refresh(boolean keepChanges) throws RepositoryException;
/**
* Returns <code>true</code> if this session holds pending (that is, unsaved) changes;
* otherwise returns <code>false</code>.
*
* @return a boolean
* @throws RepositoryException if an error occurs
*/
public boolean hasPendingChanges() throws RepositoryException;
/**
* This method returns a <code>ValueFactory</code> that is used to create <code>Value</code> objects
* for use when setting repository properties.
* <p/>
* If writing to the repository is not supported (because this is a level 1-only
* implementation, for example) an <code>UnsupportedRepositoryOperationException</code>
* will be thrown.
*
* @return a <code>ValueFactory</code>
* @throws UnsupportedRepositoryOperationException if writing to the repository is not supported.
* @throws RepositoryException if another error occurs.
*/
public ValueFactory getValueFactory() throws UnsupportedRepositoryOperationException, RepositoryException;
/**
* Determines whether this <code>Session</code> has permission to perform the specified actions
* at the specified <code>absPath</code>. This method quietly returns if the access request is
* permitted, or throws a suitable <code>java.security.AccessControlException</code> otherwise.
* <p/>
* The <code>actions</code> parameter is a comma separated list of action strings. The following
* action strings are defined:
* <ul>
* <li>
* <code>add_node</code>: If <code>checkPermission(path, "add_node")</code> returns quietly, then
* this <code>Session</code> has permission to add a node at <code>path</code>, otherwise permission
* is denied.
* </li>
* <li>
* <code>set_property</code>: If <code>checkPermission(path, "set_property")</code> returns quietly,
* then this <code>Session</code> has permission to set (add or change) a property at <code>path</code>,
* otherwise permission is denied.
* </li>
* <li>
* <code>remove</code>: If <code>checkPermission(path, "remove")</code> returns quietly, then this
* <code>Session</code> has permission to remove an item at <code>path</code>, otherwise permission is denied.
* </li>
* <li>
* <code>read</code>: If <code>checkPermission(path, "read")</code> returns quietly, then this
* <code>Session</code> has permission to retrieve (and read the value of, in the case of a property)
* an item at <code>path</code>, otherwise permission is denied.
* </li>
* </ul>
* When more than one action is specified in the <code>actions</code> parameter, this method will only
* return quietly if this <code>Session</code> has permission to perform <i>all</i> of the listed
* actions at the specified path.
* <p/>
* The information returned through this method will only reflect access control policies
* and not other restrictions that may exist. For example, even though <code>checkPermission</code>
* may indicate that a particular <code>Session</code> may add a property at <code>/A/B/C</code>,
* the node type of the node at <code>/A/B</code> may prevent the addition of a property called
* <code>C</code>.
*
* @param absPath an absolute path.
* @param actions a comma separated list of action strings.
* @throws java.security.AccessControlException If permission is denied.
* @throws RepositoryException if another error occurs.
*/
public void checkPermission(String absPath, String actions) throws java.security.AccessControlException, RepositoryException;
/**
* Returns an <code>org.xml.sax.ContentHandler</code> 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 JCR <i>system view</i> XML
* document then it is interpreted as a JCR <i>document view</i> XML
* document.
* <p/>
* The incoming XML is deserialized into a subtree of items immediately
* below the node at <code>parentAbsPath</code>.
* <p/>
* This method simply returns the <code>ContentHandler</code> without
* altering the state of the session; the actual deserialization to the
* session transient space is done through the methods of the
* <code>ContentHandler</code>. Invalid XML data
* will cause the <code>ContentHandler</code> to throw a
* <code>SAXException</code>.
* <p/>
* As SAX events are fed into the <code>ContentHandler</code>, the tree of
* new items is built in the transient storage of the session. In order to
* persist the new content, <code>save</code> must be called. The advantage
* of this through-the-session method is that (depending on which constraint
* checks the implementation leaves until <code>save</code>) structures that
* violate node type constraints can be imported, fixed and then saved. The
* disadvantage is that a large import will result in a large cache of
* pending nodes in the session. See
* {@link Workspace#getImportContentHandler} for a version of this
* method that does not go through the session.
* <p/>
* The flag <code>uuidBehavior</code> governs how the identifiers of incoming
* (deserialized) nodes are handled. There are four options:
* <ul>
* <li>
* {@link ImportUUIDBehavior#IMPORT_UUID_CREATE_NEW}: Incoming identifiers
* nodes are added in the same way that new node is added with
* <code>Node.addNode</code>. That is, they are either assigned newly
* created identifiers upon addition or upon <code>save</code> (depending on the
* implementation). In either case, identifier collisions will not occur.
* </li>
* <li>
* {@link ImportUUIDBehavior#IMPORT_UUID_COLLISION_REMOVE_EXISTING}: If an
* incoming node has the same identifier 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. Both the removal and the new addition
* will be persisted on <code>save</code>.
* </li>
* <li>
* {@link ImportUUIDBehavior#IMPORT_UUID_COLLISION_REPLACE_EXISTING}: If an
* incoming node has the same identifier 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
* <code>parentAbsPath</code>. This will occur if the topmost element of the
* incoming XML has the same identifier as an existing node elsewhere in the
* workspace. The change will be persisted on <code>save</code>.
* </li>
* <li>
* {@link ImportUUIDBehavior#IMPORT_UUID_COLLISION_THROW}: If an incoming
* node has the same identifier as a node already existing in the
* workspace then a <code>SAXException</code> is thrown by the
* <code>ContentHandler</code> during deserialization.
* </li>
* </ul>
* Unlike <code>Workspace.getImportContentHandler</code>, this method does not necessarily
* enforce all node type constraints during deserialization. Those that
* would be immediately enforced in a normal write method (<code>Node.addNode</code>,
* <code>Node.setProperty</code> etc.) of this implementation cause the returned
* <code>ContentHandler</code> to throw an immediate <code>SAXException</code> during deserialization.
* All other constraints are checked on save, just as they are in normal
* write operations. 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.
* <p/>
* A <code>SAXException</code> will also be thrown by the returned
* <code>ContentHandler</code> during deserialization if <code>uuidBehavior</code> is set to
* <code>IMPORT_UUID_COLLISION_REMOVE_EXISTING</code> and an incoming node has the same
* identifier as the node at <code>parentAbsPath</code> or one of its ancestors.
* <p/>
* A <code>PathNotFoundException</code> is thrown either immediately or on <code>save</code>
* if no node exists at <code>parentAbsPath</code>. Implementations may differ on when this
* validation is performed
* <p/>
* A <code>ConstraintViolationException</code> is thrown either immediately or on <code>save</code>
* 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.
* Implementations may differ on when this validation is performed.
* <p/>
* A <code>VersionException</code> is thrown either immediately or on <code>save</code> if the node at
* <code>parentAbsPath</code> is versionable and checked-in, or is non-versionable but
* its nearest versionable ancestor is checked-in. Implementations may differ on when this validation is performed.
* <p/>
* A <code>LockException</code> is thrown either immediately or on <code>save</code>
* if a lock prevents the addition of the subtree. Implementations may differ on when this validation is performed.
*
* @param parentAbsPath the absolute path of a node under which (as child) the imported subtree will be
* built.
* @param uuidBehavior a four-value flag that governs how incoming identifiers are handled.
* @return an org.xml.sax.ContentHandler whose methods may be called to feed SAX events
* into the deserializer.
* @throws PathNotFoundException if no node exists at <code>parentAbsPath</code> and this
* implementation performs this validation immediately instead of waiting until <code>save</code>.
* @throws ConstraintViolationException if the new subtree cannot be added to the node at
* <code>parentAbsPath</code> due to node-type or other implementation-specific constraints,
* and this implementation performs this validation immediately instead of waiting until <code>save</code>.
* @throws VersionException if the node at <code>parentAbsPath</code> is versionable
* and checked-in, or is non-versionable but its nearest versionable ancestor is checked-in and this
* implementation performs this validation immediately instead of waiting until <code>save</code>..
* @throws LockException if a lock prevents the addition of the subtree and this
* implementation performs this validation immediately instead of waiting until <code>save</code>..
* @throws RepositoryException if another error occurs.
*/
public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, RepositoryException;
/**
* Deserializes an XML document and adds the resulting item subtree as a
* child of the node at <code>parentAbsPath</code>.
* <p/>
* If the incoming XML stream does not appear to be a JCR <i>system view</i>
* XML document then it is interpreted as a <i>document view</i> XML
* document.
* <p/>
* The passed <code>InputStream</code> is closed before this method returns
* either normally or because of an exception.
* <p/>
* The tree of new items is built in the transient storage of the <code>Session</code>.
* In order to persist the new content, <code>save</code> must be called.
* The advantage of this through-the-session method is that (depending on
* what constraint checks the implementation leaves until <code>save</code>)
* structures that violate node type constraints can be imported, fixed and
* then saved. The disadvantage is that a large import will result in a
* large cache of pending nodes in the session. See {@link
* Workspace#importXML} for a version of this method that does not go
* through the <code>Session</code>.
* <p/>
* The flag <code>uuidBehavior</code> governs how the identifiers of incoming
* (deserialized) nodes are handled. There are four options:
* <ul>
* <li>
* {@link ImportUUIDBehavior#IMPORT_UUID_CREATE_NEW}: Incoming nodes
* are added in the same way that new node is added with
* <code>Node.addNode</code>. That is, they are either assigned newly
* created identifiers upon addition or upon <code>save</code> (depending on
* the implementation, see <i>4.9.1.1 When Identifiers are Assigned</i> in
* the specification). In either case, identifier collisions will not occur.
* </li>
* <li>
* {@link ImportUUIDBehavior#IMPORT_UUID_COLLISION_REMOVE_EXISTING}: If an incoming
* node has the same identifier 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. Both the removal and the new addition will be
* persisted on <code>save</code>.
* </li>
* <li>
* {@link ImportUUIDBehavior#IMPORT_UUID_COLLISION_REPLACE_EXISTING}: If an incoming
* node has the same identifier 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
* <code>parentAbsPath</code>. This will occur if the topmost element of the
* incoming XML has the same identifier as an existing node elsewhere in the
* workspace. The change will only be persisted on <code>save</code>.
* </li>
* <li>
* {@link ImportUUIDBehavior#IMPORT_UUID_COLLISION_THROW}: If an incoming
* node has the same identifier as a node already existing in the
* workspace then an <code>ItemExistsException</code> is thrown.
* </li>
* </ul>
* Unlike {@link Workspace#importXML}, this method does not necessarily
* enforce all node type constraints during deserialization. Those that
* would be immediately enforced in a normal write method
* (<code>Node.addNode</code>, <code>Node.setProperty</code> etc.) of this
* implementation cause an immediate
* <code>ConstraintViolationException</code> during deserialization. All
* other constraints are checked on <code>save</code>, just as they are in
* normal write operations. 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
* <i>5.4.3 Respecting Property Semantics</i> in the specification).
* <p/>
* A <code>ConstraintViolationException</code> will also be thrown
* immediately if <code>uuidBehavior</code> is set to
* <code>IMPORT_UUID_COLLISION_REMOVE_EXISTING</code> and an incoming node
* has the same identifier as the node at <code>parentAbsPath</code> or one of its
* ancestors.
* <p/>
* A <code>PathNotFoundException</code> is thrown either immediately or on <code>save</code>
* if no node exists at <code>parentAbsPath</code>. Implementations may differ on when this
* validation is performed
* <p/>
* A <code>ConstraintViolationException</code> is thrown either immediately or on <code>save</code>
* 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.
* Implementations may differ on when this validation is performed.
* <p/>
* A <code>VersionException</code> is thrown either immediately or on <code>save</code> if the node at
* <code>parentAbsPath</code> is versionable and checked-in, or is non-versionable but
* its nearest versionable ancestor is checked-in. Implementations may differ on when this validation is performed.
* <p/>
* A <code>LockException</code> is thrown either immediately or on <code>save</code>
* if a lock prevents the addition of the subtree. Implementations may differ on when this validation is performed.
*
* @param parentAbsPath the absolute path of the node below which the deserialized subtree is added.
* @param in The <code>Inputstream</code> from which the XML to be deserilaized is read.
* @param uuidBehavior a four-value flag that governs how incoming identifiers are handled.
*
* @throws java.io.IOException if an error during an I/O operation occurs.
* @throws PathNotFoundException if no node exists at <code>parentAbsPath</code> and this
* implementation performs this validation immediately instead of waiting until <code>save</code>..
* @throws ItemExistsException if deserialization would overwrite an existing item and this
* implementation performs this validation immediately instead of waiting until <code>save</code>..
* @throws ConstraintViolationException if a node type or other implementation-specific
* constraint is violated that would be checked on a normal write method or if
* <code>uuidBehavior</code> is set to <code>IMPORT_UUID_COLLISION_REMOVE_EXISTING</code>
* and an incoming node has the same UUID as the node at <code>parentAbsPath</code> or one
* of its ancestors.
* @throws VersionException if the node at <code>parentAbsPath</code> is versionable
* and checked-in, or its nearest versionable ancestor is checked-in and this
* implementation performs this validation immediately instead of waiting until <code>save</code>..
* @throws InvalidSerializedDataException if incoming stream is not a valid XML document.
* @throws LockException if a lock prevents the addition of the subtree and this
* implementation performs this validation immediately instead of waiting until <code>save</code>..
* @throws RepositoryException is another error occurs.
*/
public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException, VersionException, InvalidSerializedDataException, LockException, RepositoryException;
/**
* Serializes the node (and if <code>noRecurse</code> is <code>false</code>,
* the whole subtree) at <code>absPath</code> into a series of SAX events by
* calling the methods of the supplied <code>org.xml.sax.ContentHandler</code>.
* The resulting XML is in the system view form. Note that <code>absPath</code>
* must be the path of a node, not a property.
* <p>
* If <code>skipBinary</code> is true then any properties of <code>PropertyType.BINARY</code> will be
* serialized as if they are empty. That is, the existence of the property
* will be serialized, but its content will not appear in the serialized
* output (the <code><sv:value></code> element will have no content). Note that in the
* case of multi-value <code>BINARY</code> properties, the number of values in the
* property will be reflected in the serialized output, though they will all
* be empty. If <code>skipBinary</code> is false then the actual value(s) of each <code>BINARY</code>
* property is recorded using Base64 encoding.
* <p>
* If <code>noRecurse</code> is true then only the node at
* <code>absPath</code> and its properties, but not its child nodes, are
* serialized. If <code>noRecurse</code> is <code>false</code> then the entire subtree
* rooted at <code>absPath</code> is serialized.
* <p>
* If the user lacks read access to some subsection of the specified tree,
* that section simply does not get serialized, since, from the user's
* point of view, it is not there.
* <p>
* The serialized output will reflect the state of the current workspace as
* modified by the state of this <code>Session</code>. This means that
* pending changes (regardless of whether they are valid according to
* node type constraints) and all namespace mappings in the namespace registry,
* as modified by the current session-mappings, are reflected in the output.
* <p>
* The output XML will be encoded in UTF-8.
* <p>
* A <code>PathNotFoundException</code> is thrown if no node exists at <code>absPath</code>.
* <p>
* A <code>SAXException</code> is thrown if an error occurs while feeding events to the
* <code>ContentHandler</code>.
*
* @param absPath The path of the root of the subtree to be serialized.
* This must be the path to a node, not a property
* @param contentHandler The <code>org.xml.sax.ContentHandler</code> to
* which the SAX events representing the XML serialization of the subtree
* will be output.
* @param skipBinary A <code>boolean</code> governing whether binary
* properties are to be serialized.
* @param noRecurse A <code>boolean</code> governing whether the subtree at
* absPath is to be recursed.
*
* @throws PathNotFoundException if no node exists at <code>absPath</code>.
* @throws org.xml.sax.SAXException if an error occurs while feeding events to the
* <code>org.xml.sax.ContentHandler</code>.
* @throws RepositoryException if another error occurs.
*/
public void exportSystemView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws PathNotFoundException, SAXException, RepositoryException;
/**
* Serializes the node (and if <code>noRecurse</code> is <code>false</code>,
* the whole subtree) at <code>absPath</code> as an XML stream and outputs it to
* the supplied <code>OutputStream</code>. The resulting XML is in the system
* view form. Note that <code>absPath</code> must be the path of a node, not a property.
* <p>
* If <code>skipBinary</code> is true then any properties of <code>PropertyType.BINARY</code> will be
* serialized as if they are empty. That is, the existence of the property
* will be serialized, but its content will not appear in the serialized
* output (the <code><sv:value></code> element will have no content). Note that in the
* case of multi-value <code>BINARY</code> properties, the number of values in the
* property will be reflected in the serialized output, though they will all
* be empty. If <code>skipBinary</code> is false then the actual value(s) of each <code>BINARY</code>
* property is recorded using Base64 encoding.
* <p>
* If <code>noRecurse</code> is true then only the node at
* <code>absPath</code> and its properties, but not its child nodes, are
* serialized. If <code>noRecurse</code> is <code>false</code> then the entire subtree
* rooted at <code>absPath</code> is serialized.
* <p>
* If the user lacks read access to some subsection of the specified tree,
* that section simply does not get serialized, since, from the user's
* point of view, it is not there.
* <p>
* The serialized output will reflect the state of the current workspace as
* modified by the state of this <code>Session</code>. This means that
* pending changes (regardless of whether they are valid according to
* node type constraints) and all namespace mappings in the namespace
* registry, as modified by the current session-mappings, are reflected in the output.
* <p>
* The output XML will be encoded in UTF-8.
* <p>
* It is the responsibility of the caller to close the passed <code>OutputStream</code>.
* <p/>
* An <code>IOException</code> is thrown if an I/O error occurs.
* <p/>
* A <code>PathNotFoundException</code> is thrown if no node exists at <code>absPath</code>.
*
* @param absPath The path of the root of the subtree to be serialized.
* This must be the path to a node, not a property
* @param out The <code>OutputStream</code> to which the XML
* serialization of the subtree will be output.
* @param skipBinary A <code>boolean</code> governing whether binary
* properties are to be serialized.
* @param noRecurse A <code>boolean</code> governing whether the subtree at
* absPath is to be recursed.
*
* @throws PathNotFoundException if no node exists at <code>absPath</code>.
* @throws IOException if an error during an I/O operation occurs.
* @throws RepositoryException if another error occurs.
*/
public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException, PathNotFoundException, RepositoryException;
/**
* Serializes the node (and if <code>noRecurse</code> is <code>false</code>,
* the whole subtree) at <code>absPath</code> into a series of SAX events by
* calling the methods of the supplied <code>org.xml.sax.ContentHandler</code>.
* The resulting XML is in the document view form. Note that <code>absPath</code>
* must be the path of a node, not a property.
* <p>
* If <code>skipBinary</code> is true then any properties of <code>PropertyType.BINARY</code> will be
* serialized as if they are empty. That is, the existence of the property
* will be serialized, but its content will not appear in the serialized
* output (the value of the attribute will be empty). If <code>skipBinary</code> is false
* then the actual value(s) of each <code>BINARY</code> property is recorded using Base64
* encoding.
* <p>
* If <code>noRecurse</code> is true then only the node at
* <code>absPath</code> and its properties, but not its child nodes, are
* serialized. If <code>noRecurse</code> is <code>false</code> then the entire subtree
* rooted at <code>absPath</code> is serialized.
* <p>
* If the user lacks read access to some subsection of the specified tree,
* that section simply does not get serialized, since, from the user's
* point of view, it is not there.
* <p>
* The serialized output will reflect the state of the current workspace as
* modified by the state of this <code>Session</code>. This means that
* pending changes (regardless of whether they are valid according to
* node type constraints) and all namespace mappings in the namespace registry,
* as modified by the current session-mappings, are reflected in the output.
* <p>
* The output XML will be encoded in UTF-8.
* <p>
* A <code>PathNotFoundException</code> is thrown if no node exists at <code>absPath</code>.
* <p>
* A <code>SAXException</code> is thrown if an error occurs while feeding events to the
* <code>ContentHandler</code>.
*
* @param absPath The path of the root of the subtree to be serialized.
* This must be the path to a node, not a property
* @param contentHandler The <code>org.xml.sax.ContentHandler</code> to
* which the SAX events representing the XML serialization of the subtree
* will be output.
* @param skipBinary A <code>boolean</code> governing whether binary
* properties are to be serialized.
* @param noRecurse A <code>boolean</code> governing whether the subtree at
* absPath is to be recursed.
*
* @throws PathNotFoundException if no node exists at <code>absPath</code>.
* @throws org.xml.sax.SAXException if an error occurs while feeding events to the
* <code>org.xml.sax.ContentHandler</code>.
* @throws RepositoryException if another error occurs.
*/
public void exportDocumentView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws PathNotFoundException, SAXException, RepositoryException;
/**
* Serializes the node (and if <code>noRecurse</code> is <code>false</code>,
* the whole subtree) at <code>absPath</code> as an XML stream and outputs it to
* the supplied <code>OutputStream</code>. The resulting XML is in the document
* view form. Note that <code>absPath</code> must be the path of a node, not a property.
* <p>
* If <code>skipBinary</code> is true then any properties of <code>PropertyType.BINARY</code> will be
* serialized as if they are empty. That is, the existence of the property
* will be serialized, but its content will not appear in the serialized
* output (the value of the attribute will be empty). If <code>skipBinary</code> is false
* then the actual value(s) of each <code>BINARY</code> property is recorded using Base64
* encoding.
* <p>
* If <code>noRecurse</code> is true then only the node at
* <code>absPath</code> and its properties, but not its child nodes, are
* serialized. If <code>noRecurse</code> is <code>false</code> then the entire subtree
* rooted at <code>absPath</code> is serialized.
* <p>
* If the user lacks read access to some subsection of the specified tree,
* that section simply does not get serialized, since, from the user's
* point of view, it is not there.
* <p>
* The serialized output will reflect the state of the current workspace as
* modified by the state of this <code>Session</code>. This means that
* pending changes (regardless of whether they are valid according to
* node type constraints) and all namespace mappings in the namespace registry,
* as modified by the current session-mappings, are reflected in the output.
* <p>
* The output XML will be encoded in UTF-8.
* <p/>
* It is the responsibility of the caller to close the passed <code>OutputStream</code>.
* <p/>
* An IOException is thrown if an I/O error occurs.
* <p>
* A <code>PathNotFoundException</code> is thrown if no node exists at <code>absPath</code>.
*
* @param absPath The path of the root of the subtree to be serialized.
* This must be the path to a node, not a property
* @param out The <code>OutputStream</code> to which the XML
* serialization of the subtree will be output.
* @param skipBinary A <code>boolean</code> governing whether binary
* properties are to be serialized.
* @param noRecurse A <code>boolean</code> governing whether the subtree at
* absPath is to be recursed.
*
* @throws PathNotFoundException if no node exists at <code>absPath</code>.
* @throws IOException if an error during an I/O operation occurs.
* @throws RepositoryException if another error occurs.
*/
public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException, PathNotFoundException, RepositoryException;
/**
* Within the scope of this <code>Session</code>, this method maps
* <code>uri</code> to <code>prefix</code>. The remapping only affects
* operations done through this <code>Session</code>. To clear all
* remappings, the client must acquire a new <code>Session</code>.
* <p/>
* All local mappings already present in the <code>Session</code> that
* include either the specified <code>prefix</code> or the specified
* <code>uri</code> are removed and the new mapping is added.
* <p/>
* A <code>NamespaceException</code> will be thrown if an attempt is made to
* map a namespace URI to a prefix beginning with the characters
* "<code>xml</code>" (in any combination of case).
* <p/>
* A <code>NamespaceException</code> will be thrown if an attempt is made to
* map either the empty prefix or the empty namespace (i.e., if either
* <code>prefix</code> or <code>uri</code> are the empty string).
*
* @param prefix a string
* @param uri a string
* @throws NamespaceException if the local mapping cannot be done.
* @throws RepositoryException if another error occurs.
*/
public void setNamespacePrefix(String prefix, String uri) throws NamespaceException, RepositoryException;
/**
* Returns all prefixes currently mapped to URIs in this <code>Session</code>.
*
* @return a string array
* @throws RepositoryException if an error occurs
*/
public String[] getNamespacePrefixes() throws RepositoryException;
/**
* Returns the URI to which the given <code>prefix</code> is mapped
* as currently set in this <code>Session</code>.
*
* @param prefix a string
* @return a string
* @throws NamespaceException if the specified <code>prefix</code> is unknown.
* @throws RepositoryException if another error occurs
*/
public String getNamespaceURI(String prefix) throws NamespaceException, RepositoryException;
/**
* Returns the prefix to which the given <code>uri</code> is mapped as currently
* set in this <code>Session</code>.
*
* @param uri a string
* @return a string
* @throws NamespaceException if the specified <code>uri</code> is unknown.
* @throws RepositoryException if another error occurs
*/
public String getNamespacePrefix(String uri) throws NamespaceException, RepositoryException;
/**
* Releases all resources associated with this <code>Session</code>. This method should be called when a
* <code>Session</code> is no longer needed.
*/
public void logout();
/**
* Returns <code>true</code> if this <code>Session</code> object is usable
* by the client. Otherwise, returns <code>false</code>. A usable
* <code>Session</code> is one that is neither logged-out, timed-out nor in
* any other way disconnected from the repository.
*
* @return <code>true</code> if this <code>Session</code> is usable,
* <code>false</code> otherwise.
*/
public boolean isLive();
/**
* Adds the specified lock token to this <code>Session</code>. Holding a
* lock token makes this <code>Session</code> the owner of the lock
* specified by that particular lock token.
* <p/>
* A <code>LockException</code> is thrown if the specified lock token is
* already held by another <code>Session</code> and the implementation does
* not support simultaneous ownership of open-scoped locks..
* <p/>
* A <code>RepositoryException</code> is thrown if another error occurs.
*
* @param lt a lock token (a string)
* @throws LockException if the specified lock token is already held by
* another <code>Session</code> and the implementation
* does not support simultaneous ownership of open-scoped
* locks.
* @throws RepositoryException if another error occurs.
*/
public void addLockToken(String lt) throws LockException, RepositoryException;
/**
* Returns an array containing all lock tokens currently held by this
* <code>Session</code>. Note that any such tokens will represent open-scoped
* locks, since session-scoped locks do not have tokens.
*
* @return an array of lock tokens (strings)
*/
public String[] getLockTokens();
/**
* Returns all locks owned by this session.
*
* @return an array of <code>Lock</code>s
* @since JCR 2.0
*/
public Lock[] getLocks();
/**
* Removes the specified lock token from this <code>Session</code>.
* <p/>
* A <code>LockException</code> is thrown if this <code>Session</code> does
* not hold the specified lock token.
* <p/>
* A <code>RepositoryException</code> is thrown if another error occurs.
*
* @param lt a lock token (a string)
* @throws LockException if this <code>Session</code> does not hold the
* specified lock token.
* @throws RepositoryException if another error occurs.
*/
public void removeLockToken(String lt) throws LockException, RepositoryException;
/**
* This method is called by the client to set the current activity on the
* session. Changing the current activity is done by calling <code>setActivity</code>
* again. Cancelling the current activity (so that the session has no
* current activity) is done by calling <code>setActivity(null)</code>.
* The activity <code>Node</code> is returned.
* <p/>
* An <code>UnsupportedRepositoryOperationException</code> is thrown if the
* repsoitory does not support activities or if <code>activity</code> is not
* a <code>nt:activity</code> node.
*
* @param activity an activity node
* @return the activity node
* @throws UnsupportedRepositoryOperationException if the repository does
* not support activities or if <code>activity</code> is not a
* <code>nt:activity</code> node.
* @throws RepositoryException if another error occurs.
* @since JCR 2.0
*/
public Node setActivity(Node activity)
throws UnsupportedRepositoryOperationException, RepositoryException;
/**
* Returns the access control manager for this <code>Session</code>.
* <p/>
* An <code>UnsupportedRepositoryOperationException</code> is thrown if
* access control discovery is not supported.
* <p/>
* A <code>RepositoryException</code> is thrown if another error occurs.
*
* @return the access control manager for this <code>Session</code>
* @throws UnsupportedRepositoryOperationException if access control discovery
* is not supported.
* @throws RepositoryException if another error occurs.
* @since JCR 2.0
*/
public AccessControlManager getAccessControlManager()
throws UnsupportedRepositoryOperationException, RepositoryException;
}
|