Class ModelTransaction
An internal helper class for a atomic updates of an InMemoryNodeModel.
This class performs updates on the node structure of a node model consisting of ImmutableNode objects.
Because the nodes themselves cannot be changed updates are achieved by replacing parts of the structure with new
nodes; the new nodes are copies of original nodes with the corresponding manipulations applied. Therefore, each
update of a node in the structure results in a new structure in which the affected node is replaced by a new one, and
this change bubbles up to the root node (because all parent nodes have to be replaced by instances with an updated
child reference).
A single update of a model may consist of multiple changes on nodes. For instance, a remove property operation can include many nodes. There are some reasons why such updates should be handled in a single "transaction" rather than executing them on altered node structures one by one:
- An operation is typically executed on a set of source nodes from the original node hierarchy. While manipulating nodes, nodes of this set may be replaced by new ones. The handling of these replacements complicates things a lot.
- Performing all updates one after the other may cause more updates of nodes than necessary. Nodes near to the root node always have to be replaced when a child of them gets manipulated. If all these updates are deferred and handled in a single transaction, the resulting operation is more efficient.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final classA specialized operation class for adding an attribute to a target node.private static final classA specialized operation class for adding multiple attributes to a target node.private static final classA specialized operation class which changes the name of a node.private static final classA specialized operation class which changes the value of a node.private final classA specializedOperationimplementation for replacing the children of a target node.private static classAn abstract base class representing an operation to be performed on a node.private final classA helper class which collects multiple update operations to be executed on a single node.private static final classA specialized operation class for removing an attribute from a target node. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final Collection<ImmutableNode> A collection with nodes which have been added.private final Collection<ImmutableNode> Stores all nodes which have been removed in this transaction (not only the root nodes of removed trees).private final TreeDataStores the current tree data of the calling node model.private static final intConstant for an unknown level.private static final intConstant for the maximum number of entries in the replacement mapping.private Map<ImmutableNode, Object> A map with reference objects to be added during this transaction.private ImmutableNodeThe new root node.private final SortedMap<Integer, Map<ImmutableNode, ModelTransaction.Operations>> Stores the operations to be executed during this transaction.private final Map<ImmutableNode, ImmutableNode> A new parent mapping.private final ImmutableNodeThe root node for query operations.private final Collection<ImmutableNode> A collection with nodes which have been removed.private final Map<ImmutableNode, ImmutableNode> The nodes replaced in this transaction.private final Map<ImmutableNode, ImmutableNode> A new replacement mapping.private final NodeKeyResolver<ImmutableNode> TheNodeKeyResolverto be used for this transaction.private final NodeSelectorThe selector to the root node of this transaction. -
Constructor Summary
ConstructorsConstructorDescriptionModelTransaction(TreeData treeData, NodeSelector selector, NodeKeyResolver<ImmutableNode> resolver) Creates a new instance ofModelTransactionfor the current tree data. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddAddNodeOperation(ImmutableNode parent, ImmutableNode newChild) Adds an operation for adding a new child to a given parent node.voidaddAddNodesOperation(ImmutableNode parent, Collection<? extends ImmutableNode> newNodes) Adds an operation for adding a number of new children to a given parent node.voidaddAttributeOperation(ImmutableNode target, String name, Object value) Adds an operation for adding an attribute to a target node.voidaddAttributesOperation(ImmutableNode target, Map<String, Object> attributes) Adds an operation for adding multiple attributes to a target node.voidaddChangeNodeNameOperation(ImmutableNode target, String newName) Adds an operation for changing the name of a target node.voidaddChangeNodeValueOperation(ImmutableNode target, Object newValue) Adds an operation for changing the value of a target node.voidAdds an operation for clearing the value of a target node.voidaddNewReference(ImmutableNode node, Object ref) Adds a new reference object for the given node.voidaddNewReferences(Map<ImmutableNode, ?> refs) Adds a map with new reference objects.voidaddRemoveAttributeOperation(ImmutableNode target, String name) Adds an operation for removing an attribute from a target node.voidaddRemoveNodeOperation(ImmutableNode parent, ImmutableNode node) Adds an operation for removing a child node of a given node.private static <E> Collection<E> append(Collection<E> col, E node) Appends a single element to a collection.private static <K,V> Map <K, V> Adds a single key-value pair to a map.private static <E> Set<E> Appends a single element to a set.private static <E> Collection<E> concatenate(Collection<E> col1, Collection<? extends E> col2) Constructs the concatenation of two collections.private static <K,V> Map <K, V> concatenate(Map<K, V> map1, Map<? extends K, ? extends V> map2) Constructs the concatenation of two maps.private static <E> Set<E> concatenate(Set<E> set1, Set<? extends E> set2) Constructs the concatenation of two sets.execute()Executes this transaction resulting in a newTreeDataobject.private voidExecutes all operations in this transaction.(package private) ModelTransaction.OperationsfetchOperations(ImmutableNode target, int level) Obtains theOperationsobject for manipulating the specified node.private Map<ImmutableNode, Object> Returns the map with new reference objects.Gets the currentTreeDataobject this transaction operates on.(package private) ImmutableNodegetParent(ImmutableNode node) Gets the parent node of the given node.Gets the root node to be used within queries.Gets theNodeKeyResolverused by this transaction.private ImmutableNodeinitQueryRoot(TreeData treeData, NodeSelector selector) Initializes the root node to be used within queries.private intlevel(ImmutableNode node) Determines the level of the specified node in the current hierarchy.private voidRebuilds the parent mapping from scratch.private voidRemoves the specified node completely from the replacement mapping.private voidRemoves a node and its children (recursively) from the parent and the replacement mappings.private voidUpdates the parent mapping for the resultingTreeDatainstance.private voidAdds newly added nodes and their children to the parent mapping.private voidRemoves nodes that have been removed during this transaction from the parent and replacement mappings.private ReferenceTrackerReturns an updatedReferenceTrackerinstance.
-
Field Details
-
MAX_REPLACEMENTS
private static final int MAX_REPLACEMENTSConstant for the maximum number of entries in the replacement mapping. If this number is exceeded, the parent mapping is reconstructed. The number is a bit arbitrary. If it is too low, updates - especially on large node structures - are expensive because the parent mapping is often rebuild. If it is too big, read access to the model is slowed down because looking up the parent of a node is more complicated.- See Also:
-
LEVEL_UNKNOWN
private static final int LEVEL_UNKNOWNConstant for an unknown level.- See Also:
-
currentData
Stores the current tree data of the calling node model. -
queryRoot
The root node for query operations. -
rootNodeSelector
The selector to the root node of this transaction. -
resolver
TheNodeKeyResolverto be used for this transaction. -
replacementMapping
A new replacement mapping. -
replacedNodes
The nodes replaced in this transaction. -
parentMapping
A new parent mapping. -
addedNodes
A collection with nodes which have been added. -
removedNodes
A collection with nodes which have been removed. -
allRemovedNodes
Stores all nodes which have been removed in this transaction (not only the root nodes of removed trees). -
operations
Stores the operations to be executed during this transaction. The map is sorted by the levels of the nodes to be manipulated: Operations on nodes down in the hierarchy are executed first because they affect the nodes closer to the root. -
newReferences
A map with reference objects to be added during this transaction. -
newRoot
The new root node.
-
-
Constructor Details
-
ModelTransaction
public ModelTransaction(TreeData treeData, NodeSelector selector, NodeKeyResolver<ImmutableNode> resolver) Creates a new instance ofModelTransactionfor the current tree data.- Parameters:
treeData- the currentTreeDatastructure to operate onselector- an optionalNodeSelectordefining the target root node for this transaction; this can be used to perform operations on tracked nodesresolver- theNodeKeyResolver
-
-
Method Details
-
append
Appends a single element to a collection. The collection may be null, then it is created.- Type Parameters:
E- the type of elements involved- Parameters:
col- the collectionnode- the element to be added- Returns:
- the resulting collection
-
append
Adds a single key-value pair to a map. The map may be null, then it is created.- Type Parameters:
K- the type of the keyV- the type of the value- Parameters:
map- the mapkey- the keyvalue- the value- Returns:
- the resulting map
-
append
Appends a single element to a set. The set may be null then it is created.- Type Parameters:
E- the type of the elements involved- Parameters:
col- the setelem- the element to be added- Returns:
- the resulting set
-
concatenate
Constructs the concatenation of two collections. Both can be null.- Type Parameters:
E- the type of the elements involved- Parameters:
col1- the first collectioncol2- the second collection- Returns:
- the resulting collection
-
concatenate
Constructs the concatenation of two maps. Both can be null.- Type Parameters:
K- the type of the keysV- the type of the values- Parameters:
map1- the first mapmap2- the second map- Returns:
- the resulting map
-
concatenate
Constructs the concatenation of two sets. Both can be null.- Type Parameters:
E- the type of the elements involved- Parameters:
set1- the first setset2- the second set- Returns:
- the resulting set
-
addAddNodeOperation
Adds an operation for adding a new child to a given parent node.- Parameters:
parent- the parent nodenewChild- the new child to be added
-
addAddNodesOperation
public void addAddNodesOperation(ImmutableNode parent, Collection<? extends ImmutableNode> newNodes) Adds an operation for adding a number of new children to a given parent node.- Parameters:
parent- the parent nodenewNodes- the collection of new child nodes
-
addAttributeOperation
Adds an operation for adding an attribute to a target node.- Parameters:
target- the target nodename- the name of the attributevalue- the value of the attribute
-
addAttributesOperation
Adds an operation for adding multiple attributes to a target node.- Parameters:
target- the target nodeattributes- the map with attributes to be set
-
addChangeNodeNameOperation
Adds an operation for changing the name of a target node.- Parameters:
target- the target nodenewName- the new name for this node
-
addChangeNodeValueOperation
Adds an operation for changing the value of a target node.- Parameters:
target- the target nodenewValue- the new value for this node
-
addClearNodeValueOperation
Adds an operation for clearing the value of a target node.- Parameters:
target- the target node
-
addNewReference
Adds a new reference object for the given node.- Parameters:
node- the affected noderef- the reference object for this node
-
addNewReferences
Adds a map with new reference objects. The entries in this map are passed to theReferenceTrackerduring execution of this transaction.- Parameters:
refs- the map with new reference objects
-
addRemoveAttributeOperation
Adds an operation for removing an attribute from a target node.- Parameters:
target- the target nodename- the name of the attribute
-
addRemoveNodeOperation
Adds an operation for removing a child node of a given node.- Parameters:
parent- the parent nodenode- the child node to be removed
-
execute
Executes this transaction resulting in a newTreeDataobject. The object returned by this method serves as the definition of a new node structure for the calling model.- Returns:
- the updated
TreeData
-
executeOperations
private void executeOperations()Executes all operations in this transaction. -
fetchOperations
Obtains theOperationsobject for manipulating the specified node. If no such object exists yet, it is created. The level can be undefined, then it is determined based on the target node.- Parameters:
target- the target nodelevel- the level of the target node (may be undefined)- Returns:
- the
Operationsobject for this node
-
fetchReferenceMap
Returns the map with new reference objects. It is created if necessary.- Returns:
- the map with reference objects
-
getCurrentData
Gets the currentTreeDataobject this transaction operates on.- Returns:
- the associated
TreeDataobject
-
getParent
Gets the parent node of the given node.- Parameters:
node- the node in question- Returns:
- the parent of this node
-
getQueryRoot
Gets the root node to be used within queries. This is not necessarily the current root node of the model. If the operation is executed on a tracked node, this node has to be passed as root nodes to the expression engine.- Returns:
- the root node for queries and calls to the expression engine
-
getResolver
Gets theNodeKeyResolverused by this transaction.- Returns:
- the
NodeKeyResolver
-
initQueryRoot
Initializes the root node to be used within queries. If a tracked node selector is provided, this node becomes the root node. Otherwise, the actual root node is used.- Parameters:
treeData- the current data of the modelselector- an optionalNodeSelectordefining the target root- Returns:
- the query root node for this transaction
-
level
Determines the level of the specified node in the current hierarchy. The level of the root node is 0, the children of the root have level 1 and so on.- Parameters:
node- the node in question- Returns:
- the level of this node
-
rebuildParentMapping
private void rebuildParentMapping()Rebuilds the parent mapping from scratch. This method is called if the replacement mapping exceeds its maximum size. In this case, it is cleared, and a new parent mapping is constructed for the new root node. -
removeNodeFromReplacementMapping
Removes the specified node completely from the replacement mapping. This also includes the nodes that replace the given one.- Parameters:
node- the node to be removed
-
removeNodesFromParentAndReplacementMapping
Removes a node and its children (recursively) from the parent and the replacement mappings.- Parameters:
root- the root of the subtree to be removed
-
updateParentMapping
private void updateParentMapping()Updates the parent mapping for the resultingTreeDatainstance. This method is called after all update operations have been executed. It ensures that the parent mapping is updated for the changes on the nodes structure. -
updateParentMappingForAddedNodes
private void updateParentMappingForAddedNodes()Adds newly added nodes and their children to the parent mapping. -
updateParentMappingForRemovedNodes
private void updateParentMappingForRemovedNodes()Removes nodes that have been removed during this transaction from the parent and replacement mappings. -
updateReferenceTracker
Returns an updatedReferenceTrackerinstance. The changes performed during this transaction are applied to the tracker.- Returns:
- the updated tracker instance
-