org.modeshape.graph.session
Class GraphSession<Payload,PropertyPayload>

java.lang.Object
  extended by org.modeshape.graph.session.GraphSession<Payload,PropertyPayload>
Type Parameters:
Payload - the type of the payload object for each node, used to allow the nodes to hold additional cached information
PropertyPayload - the type of payload object for each property, used to allow the nodes to hold additional cached information

@NotThreadSafe
public class GraphSession<Payload,PropertyPayload>
extends Object

This class represents an interactive session for working with the content within a graph. This session maintains a cache of content read from the repository, as well as transient changes that have been made to the nodes within this session that are then pushed to the graph when the session is saved.

Like the other Graph APIs, the mutable objects in this session should not be held onto for very long periods of time. When the session is saved or {refreshed (or when a node is saved or refreshed), the session may unload and discard some of its nodes. Using nodes after they are discarded may result in assertion errors (assuming Java assertions are enabled).


Nested Class Summary
static interface GraphSession.Authorizer
           
protected static class GraphSession.Dependencies
           
protected  class GraphSession.LoadAllChildrenVisitor
          A visitor that ensures that all children of a node are loaded, and provides a hook to post-process the parent.
protected  class GraphSession.LoadNodesVisitor
          An abstract base class for visitors that need to load nodes using a single batch for all read operations.
static class GraphSession.Node<Payload,PropertyPayload>
           
static class GraphSession.NodeId
          An immutable identifier for a node, used within the GraphSession.
static interface GraphSession.NodeIdFactory
           
static class GraphSession.NodeOperations<Payload,PropertyPayload>
          A default implementation of GraphSession.Operations that provides all the basic functionality required by a graph session.
static class GraphSession.NodeVisitor<NodePayload,PropertyPayloadType>
          The node visitor.
protected static class GraphSession.NoOpAuthorizer
          GraphSession.Authorizer implementation that does nothing.
static interface GraphSession.Operations<NodePayload,PropertyPayload>
           
static class GraphSession.PropertyInfo<PropertyPayload>
           
protected static class GraphSession.RefreshState<Payload,PropertyPayload>
           
protected static class GraphSession.Snapshot<PropertyPayload>
           
static class GraphSession.Status
           
static class GraphSession.StructureSnapshot<PropertyPayload>
          A read-only visitor that walks the cache to obtain a snapshot of the cache structure.
 
Field Summary
protected  GraphSession.Authorizer authorizer
           
protected  Map<GraphSession.NodeId,GraphSession.Dependencies> changeDependencies
          A map that records how the changes to a node are dependent upon other nodes.
protected  ExecutionContext context
           
protected  GraphSession.NodeIdFactory idFactory
           
protected  int loadDepth
           
protected  com.google.common.collect.ListMultimap<Name,GraphSession.Node<Payload,PropertyPayload>> NO_CHILDREN
           
protected  Map<Name,GraphSession.PropertyInfo<PropertyPayload>> NO_PROPERTIES
           
protected  GraphSession.Operations<Payload,PropertyPayload> nodeOperations
           
protected  Map<GraphSession.NodeId,GraphSession.Node<Payload,PropertyPayload>> nodes
          A map of the nodes keyed by their identifier.
protected  Graph.Batch operations
           
protected  PathFactory pathFactory
           
protected  GraphSession.Node<Payload,PropertyPayload> root
           
protected  Graph store
           
protected  String workspaceName
           
 
Constructor Summary
GraphSession(Graph graph, String workspaceName, GraphSession.Operations<Payload,PropertyPayload> nodeOperations)
          Create a session that uses the supplied graph and the supplied node operations.
GraphSession(Graph graph, String workspaceName, GraphSession.Operations<Payload,PropertyPayload> nodeOperations, GraphSession.Authorizer authorizer)
          Create a session that uses the supplied graph and the supplied node operations.
 
Method Summary
 void clearAllChangedNodes()
          Remove any cached information that has been marked as a transient change.
protected  GraphSession.Node<Payload,PropertyPayload> createNode(GraphSession.Node<Payload,PropertyPayload> parent, GraphSession.NodeId nodeId, Location location)
           
 GraphSession.Node<Payload,PropertyPayload> findNodeRelativeTo(GraphSession.Node<Payload,PropertyPayload> startingPoint, Path relativePath)
          Find the node with the supplied path relative to another node.
protected  GraphSession.Node<Payload,PropertyPayload> findNodeRelativeTo(GraphSession.Node<Payload,PropertyPayload> startingPoint, Path relativePath, boolean loadIfRequired)
          Find the node with the supplied path relative to another node.
 GraphSession.Node<Payload,PropertyPayload> findNodeWith(GraphSession.NodeId id)
          Find in the session the node with the supplied identifier.
 GraphSession.Node<Payload,PropertyPayload> findNodeWith(GraphSession.NodeId id, Path path)
          Find the node with the supplied identifier or, if no such node is found, the node at the supplied path.
 GraphSession.Node<Payload,PropertyPayload> findNodeWith(Location location)
          Find in the session the node with the supplied location.
 GraphSession.Node<Payload,PropertyPayload> findNodeWith(Path path)
          Find the node with the supplied path.
protected  GraphSession.Node<Payload,PropertyPayload> findNodeWith(Path path, boolean loadIfRequired)
          Find the node with the supplied path.
protected  long getCurrentTime()
           
 int getDepthForLoadingNodes()
          Get the subgraph depth that is read when a node is loaded from the persistence store.
 PathFactory getPathFactory()
          Get the path factory that should be used to adjust the path objects.
 GraphSession.Node<Payload,PropertyPayload> getRoot()
          Get the root node.
 boolean hasPendingChanges()
          Returns whether the session cache has any pending changes that need to be executed.
 void immediateClone(Path source, String sourceWorkspace, Path destination, boolean removeExisting, boolean destPathIncludesSegment)
          Clone the supplied source branch and place into the destination location, optionally removing any existing copy that already exists in the destination location, doing so immediately without enqueuing the operation within the session's operations.
 void immediateCopy(Path source, Path destination)
          Copy the node at the supplied source path in the named workspace, and place the copy at the supplied location within the current workspace, doing so immediately without enqueuing the operation within the session's operations.
 void immediateCopy(Path source, String sourceWorkspace, Path destination)
          Copy the node at the supplied source path in the named workspace, and place the copy at the supplied location within the current workspace, doing so immediately without enqueuing the operation within the session's operations.
 void immediateMove(Path nodeToMove, Path destination)
          Move this node from its current location so that is is a child of the supplied parent, doing so immediately without enqueuing the operation within the session's operations.
protected  void recordDelete(GraphSession.Node<Payload,PropertyPayload> node)
          Record the fact that the supplied node is in the process of being deleted, so any cached information (outside of the node object itself) should be cleaned up.
protected  void recordMove(GraphSession.Node<Payload,PropertyPayload> nodeBeingMoved, GraphSession.Node<Payload,PropertyPayload> oldParent, GraphSession.Node<Payload,PropertyPayload> newParent)
           
protected  void recordUnloaded(GraphSession.Node<Payload,PropertyPayload> node)
          Record the fact that the supplied node is in the process of being unloaded, so any cached information (outside of the node object itself) should be cleaned up.
 void refresh(boolean keepChanges)
          Refreshes (removes the cached state) for all cached nodes.
 void refresh(GraphSession.Node<Payload,PropertyPayload> node, boolean keepChanges)
          Refreshes (removes the cached state) for the given node and its descendants.
 void save()
          Save any changes that have been accumulated by this session.
 void save(GraphSession.Node<Payload,PropertyPayload> node)
          Save any changes to the identified node or its descendants.
 void setDepthForLoadingNodes(int depth)
          Set the loading depth parameter, which controls how deep a subgraph should be read when a node is loaded from the persistence store.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

NO_CHILDREN

protected final com.google.common.collect.ListMultimap<Name,GraphSession.Node<Payload,PropertyPayload>> NO_CHILDREN

NO_PROPERTIES

protected final Map<Name,GraphSession.PropertyInfo<PropertyPayload>> NO_PROPERTIES

authorizer

protected final GraphSession.Authorizer authorizer

context

protected final ExecutionContext context

store

protected final Graph store

root

protected final GraphSession.Node<Payload,PropertyPayload> root

nodeOperations

protected final GraphSession.Operations<Payload,PropertyPayload> nodeOperations

pathFactory

protected final PathFactory pathFactory

idFactory

protected final GraphSession.NodeIdFactory idFactory

workspaceName

protected final String workspaceName

loadDepth

protected int loadDepth

nodes

protected final Map<GraphSession.NodeId,GraphSession.Node<Payload,PropertyPayload>> nodes
A map of the nodes keyed by their identifier.


changeDependencies

protected final Map<GraphSession.NodeId,GraphSession.Dependencies> changeDependencies
A map that records how the changes to a node are dependent upon other nodes.


operations

protected Graph.Batch operations
Constructor Detail

GraphSession

public GraphSession(Graph graph,
                    String workspaceName,
                    GraphSession.Operations<Payload,PropertyPayload> nodeOperations)
Create a session that uses the supplied graph and the supplied node operations.

Parameters:
graph - the graph that this session is to use
workspaceName - the name of the workspace that is to be used, or null if the current workspace should be used
nodeOperations - the operations that are to be performed during various stages in the lifecycle of a node, or null if there are no special operations that should be performed

GraphSession

public GraphSession(Graph graph,
                    String workspaceName,
                    GraphSession.Operations<Payload,PropertyPayload> nodeOperations,
                    GraphSession.Authorizer authorizer)
Create a session that uses the supplied graph and the supplied node operations.

Parameters:
graph - the graph that this session is to use
workspaceName - the name of the workspace that is to be used, or null if the current workspace should be used
nodeOperations - the operations that are to be performed during various stages in the lifecycle of a node, or null if there are no special operations that should be performed
authorizer - the authorizing component, or null if no special authorization is to be performed
Throws:
IllegalArgumentException - if the graph reference is null
IllegalArgumentException - if the depth is not positive
Method Detail

getDepthForLoadingNodes

public int getDepthForLoadingNodes()
Get the subgraph depth that is read when a node is loaded from the persistence store. By default, this value is 1.

Returns:
the loading depth; always positive

setDepthForLoadingNodes

public void setDepthForLoadingNodes(int depth)
Set the loading depth parameter, which controls how deep a subgraph should be read when a node is loaded from the persistence store. By default, this value is 1.

Parameters:
depth - the depth that should be read whenever a single node is loaded
Throws:
IllegalArgumentException - if the depth is not positive

getRoot

public GraphSession.Node<Payload,PropertyPayload> getRoot()
Get the root node.

Returns:
the root node; never null

getPathFactory

public PathFactory getPathFactory()
Get the path factory that should be used to adjust the path objects.

Returns:
the path factory; never null

findNodeWith

public GraphSession.Node<Payload,PropertyPayload> findNodeWith(Location location)
                                                        throws PathNotFoundException,
                                                               AccessControlException
Find in the session the node with the supplied location. If the location does not have a path, this method must first query the actual persistent store, even if the session already has loaded the node. Thus, this method may not be the most efficient technique to find a node.

Parameters:
location - the location of the node
Returns:
the cached node at the supplied location
Throws:
PathNotFoundException - if the node at the supplied location does not exist
AccessControlException - if the user does not have permission to read the node given by the supplied location
IllegalArgumentException - if the location is null

findNodeWith

public GraphSession.Node<Payload,PropertyPayload> findNodeWith(GraphSession.NodeId id)
Find in the session the node with the supplied identifier.

Parameters:
id - the identifier of the node
Returns:
the identified node, or null if the session has no node with the supplied identifier
Throws:
IllegalArgumentException - if the identifier is null

findNodeWith

public GraphSession.Node<Payload,PropertyPayload> findNodeWith(GraphSession.NodeId id,
                                                               Path path)
                                                        throws PathNotFoundException,
                                                               AccessControlException
Find the node with the supplied identifier or, if no such node is found, the node at the supplied path. Note that if a node was found by the identifier, the resulting may not have the same path as that supplied as a parameter.

Parameters:
id - the identifier to the node; may be null if the node is to be found by path
path - the path that should be used to find the node only when the cache doesn't contain a node with the identifier
Returns:
the node with the supplied id and/or path
Throws:
IllegalArgumentException - if the identifier and path are both node
PathNotFoundException - if the node at the supplied path does not exist
AccessControlException - if the user does not have permission to read the nodes given by the supplied path

findNodeWith

public GraphSession.Node<Payload,PropertyPayload> findNodeWith(Path path)
                                                        throws PathNotFoundException,
                                                               AccessControlException
Find the node with the supplied path. This node quickly finds the node if it exists in the cache, or if it is not in the cache, it loads the nodes down the supplied path.

Parameters:
path - the path to the node
Returns:
the node information
Throws:
PathNotFoundException - if the node at the supplied path does not exist
AccessControlException - if the user does not have permission to read the nodes given by the supplied path

findNodeWith

protected GraphSession.Node<Payload,PropertyPayload> findNodeWith(Path path,
                                                                  boolean loadIfRequired)
                                                           throws PathNotFoundException,
                                                                  AccessControlException
Find the node with the supplied path. This node quickly finds the node if it exists in the cache, or if it is not in the cache, it loads the nodes down the supplied path. However, if loadIfRequired is false, then any node along the path that is not loaded will result in this method returning null.

Parameters:
path - the path to the node
loadIfRequired - true if any missing nodes should be loaded, or false if null should be returned if any nodes along the path are not loaded
Returns:
the node information
Throws:
PathNotFoundException - if the node at the supplied path does not exist
AccessControlException - if the user does not have permission to read the nodes given by the supplied path

findNodeRelativeTo

public GraphSession.Node<Payload,PropertyPayload> findNodeRelativeTo(GraphSession.Node<Payload,PropertyPayload> startingPoint,
                                                                     Path relativePath)
                                                              throws PathNotFoundException,
                                                                     AccessControlException
Find the node with the supplied path relative to another node. This node quickly finds the node by walking the supplied relative path starting at the supplied node. As soon as a cached node is found to not be fully loaded, the persistent information for that node and all remaining nodes along the relative path are read from the persistent store and inserted into the cache.

Parameters:
startingPoint - the node from which the path is relative
relativePath - the relative path from the designated starting point to the desired node; may not be null and may not be an absolute path
Returns:
the node information
Throws:
PathNotFoundException - if the node at the supplied path does not exist
AccessControlException - if the user does not have permission to read the nodes given by the supplied path

findNodeRelativeTo

protected GraphSession.Node<Payload,PropertyPayload> findNodeRelativeTo(GraphSession.Node<Payload,PropertyPayload> startingPoint,
                                                                        Path relativePath,
                                                                        boolean loadIfRequired)
                                                                 throws PathNotFoundException,
                                                                        AccessControlException
Find the node with the supplied path relative to another node. This node quickly finds the node by walking the supplied relative path starting at the supplied node. As soon as a cached node is found to not be fully loaded, the persistent information for that node and all remaining nodes along the relative path are read from the persistent store and inserted into the cache.

Parameters:
startingPoint - the node from which the path is relative
relativePath - the relative path from the designated starting point to the desired node; may not be null and may not be an absolute path
loadIfRequired - true if any missing nodes should be loaded, or false if null should be returned if any nodes along the path are not loaded
Returns:
the node information, or null if the node was not yet loaded (and loadRequired was false)
Throws:
PathNotFoundException - if the node at the supplied path does not exist
AccessControlException - if the user does not have permission to read the nodes given by the supplied path

hasPendingChanges

public boolean hasPendingChanges()
Returns whether the session cache has any pending changes that need to be executed.

Returns:
true if there are pending changes, or false if there is currently no changes

clearAllChangedNodes

public void clearAllChangedNodes()
Remove any cached information that has been marked as a transient change.


immediateMove

public void immediateMove(Path nodeToMove,
                          Path destination)
                   throws AccessControlException,
                          RepositorySourceException
Move this node from its current location so that is is a child of the supplied parent, doing so immediately without enqueuing the operation within the session's operations. The current session is modified immediately to reflect the move result.

Parameters:
nodeToMove - the path to the node that is to be moved; may not be null
destination - the desired new path; may not be null
Throws:
IllegalArgumentException - if the node being moved is the root node
AccessControlException - if the caller does not have the permission to perform the operation
RepositorySourceException - if any error resulting while performing the operation

immediateCopy

public void immediateCopy(Path source,
                          Path destination)
                   throws AccessControlException,
                          RepositorySourceException
Copy the node at the supplied source path in the named workspace, and place the copy at the supplied location within the current workspace, doing so immediately without enqueuing the operation within the session's operations. The current session is modified immediately to reflect the copy result.

Note that the destination path should not include a same-name-sibling index, since this will be ignored and will always be recomputed (as the copy will be appended to any children already in the destination's parent).

Parameters:
source - the path to the node that is to be copied; may not be null
destination - the path where the copy is to be placed; may not be null
Throws:
IllegalArgumentException - either path is null or invalid
AccessControlException - if the caller does not have the permission to perform the operation
RepositorySourceException - if any error resulting while performing the operation

immediateCopy

public void immediateCopy(Path source,
                          String sourceWorkspace,
                          Path destination)
                   throws InvalidWorkspaceException,
                          AccessControlException,
                          PathNotFoundException,
                          RepositorySourceException
Copy the node at the supplied source path in the named workspace, and place the copy at the supplied location within the current workspace, doing so immediately without enqueuing the operation within the session's operations. The current session is modified immediately to reflect the copy result.

Note that the destination path should not include a same-name-sibling index, since this will be ignored and will always be recomputed (as the copy will be appended to any children already in the destination's parent).

Parameters:
source - the path to the node that is to be copied; may not be null
sourceWorkspace - the name of the workspace where the source node is to be found, or null if the current workspace should be used
destination - the path where the copy is to be placed; may not be null
Throws:
IllegalArgumentException - either path is null or invalid
PathNotFoundException - if the node being copied or the parent of the destination path do not exist
InvalidWorkspaceException - if the source workspace name is invalid or does not exist
AccessControlException - if the caller does not have the permission to perform the operation
RepositorySourceException - if any error resulting while performing the operation

immediateClone

public void immediateClone(Path source,
                           String sourceWorkspace,
                           Path destination,
                           boolean removeExisting,
                           boolean destPathIncludesSegment)
                    throws InvalidWorkspaceException,
                           AccessControlException,
                           UuidAlreadyExistsException,
                           PathNotFoundException,
                           RepositorySourceException
Clone the supplied source branch and place into the destination location, optionally removing any existing copy that already exists in the destination location, doing so immediately without enqueuing the operation within the session's operations. The current session is modified immediately to reflect the clone result.

Parameters:
source - the path to the node that is to be cloned; may not be null
sourceWorkspace - the name of the workspace where the source node is to be found, or null if the current workspace should be used
destination - the path for the new cloned copy; may not be null index
removeExisting - true if the original should be removed, or false if the original should be left
destPathIncludesSegment - true if the destination path includes the segment that should be used
Throws:
IllegalArgumentException - either path is null or invalid
InvalidWorkspaceException - if the source workspace name is invalid or does not exist
UuidAlreadyExistsException - if copy could not be completed because the current workspace already includes at least one of the nodes at or below the source branch in the source workspace
PathNotFoundException - if the node being clone or the destination node do not exist
AccessControlException - if the caller does not have the permission to perform the operation
RepositorySourceException - if any error resulting while performing the operation

refresh

public void refresh(boolean keepChanges)
             throws InvalidStateException,
                    RepositorySourceException
Refreshes (removes the cached state) for all cached nodes.

If keepChanges == true, modified nodes will not have their state refreshed, while all others will either be unloaded or changed to reflect the current state of the persistent store.

Parameters:
keepChanges - indicates whether changed nodes should be kept or refreshed from the repository.
Throws:
InvalidStateException - if any error resulting while reading information from the repository
RepositorySourceException - if any error resulting while reading information from the repository

refresh

public void refresh(GraphSession.Node<Payload,PropertyPayload> node,
                    boolean keepChanges)
             throws InvalidStateException,
                    RepositorySourceException
Refreshes (removes the cached state) for the given node and its descendants.

If keepChanges == true, modified nodes will not have their state refreshed, while all others will either be unloaded or changed to reflect the current state of the persistent store.

Parameters:
node - the node that is to be refreshed; may not be null
keepChanges - indicates whether changed nodes should be kept or refreshed from the repository.
Throws:
InvalidStateException - if any error resulting while reading information from the repository
RepositorySourceException - if any error resulting while reading information from the repository

save

public void save()
          throws PathNotFoundException,
                 ValidationException,
                 InvalidStateException
Save any changes that have been accumulated by this session.

Throws:
PathNotFoundException - if the state of this session is invalid and is attempting to change a node that doesn't exist
ValidationException - if any of the changes being made result in an invalid node state
InvalidStateException - if the supplied node is no longer a node within this cache (because it was unloaded)

save

public void save(GraphSession.Node<Payload,PropertyPayload> node)
          throws PathNotFoundException,
                 ValidationException,
                 InvalidStateException
Save any changes to the identified node or its descendants. The supplied node may not have been deleted or created in this session since the last save operation.

Parameters:
node - the node being saved; may not be null
Throws:
PathNotFoundException - if the state of this session is invalid and is attempting to change a node that doesn't exist
ValidationException - if any of the changes being made result in an invalid node state
InvalidStateException - if the supplied node is no longer a node within this cache (because it was unloaded)

createNode

protected GraphSession.Node<Payload,PropertyPayload> createNode(GraphSession.Node<Payload,PropertyPayload> parent,
                                                                GraphSession.NodeId nodeId,
                                                                Location location)

getCurrentTime

protected long getCurrentTime()

recordMove

protected void recordMove(GraphSession.Node<Payload,PropertyPayload> nodeBeingMoved,
                          GraphSession.Node<Payload,PropertyPayload> oldParent,
                          GraphSession.Node<Payload,PropertyPayload> newParent)

recordDelete

protected void recordDelete(GraphSession.Node<Payload,PropertyPayload> node)
Record the fact that the supplied node is in the process of being deleted, so any cached information (outside of the node object itself) should be cleaned up.

Parameters:
node - the node being deleted; never null

recordUnloaded

protected void recordUnloaded(GraphSession.Node<Payload,PropertyPayload> node)
Record the fact that the supplied node is in the process of being unloaded, so any cached information (outside of the node object itself) should be cleaned up.

Parameters:
node - the node being unloaded; never null


Copyright © 2008-2010 JBoss, a division of Red Hat. All Rights Reserved.