/** * Returns the parent node of the given node. * * @param node the node in question * @return the parent of this node */ ImmutableNode getParent(final ImmutableNode node) { return getCurrentData().getParent(node); }
/** * 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. * * @param node the node in question * @return the level of this node */ private int level(final ImmutableNode node) { ImmutableNode current = getCurrentData().getParent(node); int level = 0; while (current != null) { level++; current = getCurrentData().getParent(current); } return level; }
/** * Removes a node and its children (recursively) from the parent and the * replacement mappings. * * @param root the root of the subtree to be removed */ private void removeNodesFromParentAndReplacementMapping(final ImmutableNode root) { NodeTreeWalker.INSTANCE.walkBFS(root, new ConfigurationNodeVisitorAdapter<ImmutableNode>() { @Override public void visitBeforeChildren(final ImmutableNode node, final NodeHandler<ImmutableNode> handler) { allRemovedNodes.add(node); parentMapping.remove(node); removeNodeFromReplacementMapping(node); } }, getCurrentData()); }
@Override public boolean initTransaction(final ModelTransaction tx) { final List<QueryResult<ImmutableNode>> results = resolver.resolveKey(tx.getQueryRoot(), key, tx.getCurrentData()); return initializeClearTransaction(tx, results); } }, selector, resolver);
/** * Creates a new instance of {@code ModelTransaction} for the current tree * data. * * @param treeData the current {@code TreeData} structure to operate on * @param selector an optional {@code NodeSelector} defining the target root * node for this transaction; this can be used to perform operations * on tracked nodes * @param resolver the {@code NodeKeyResolver} */ public ModelTransaction(final TreeData treeData, final NodeSelector selector, final NodeKeyResolver<ImmutableNode> resolver) { currentData = treeData; this.resolver = resolver; replacementMapping = getCurrentData().copyReplacementMapping(); replacedNodes = new HashMap<>(); parentMapping = getCurrentData().copyParentMapping(); operations = new TreeMap<>(); addedNodes = new LinkedList<>(); removedNodes = new LinkedList<>(); allRemovedNodes = new LinkedList<>(); queryRoot = initQueryRoot(treeData, selector); rootNodeSelector = selector; }
/** * Executes a transaction on the current data of this model. This method is * called if an operation is to be executed on the model's root node or a * tracked node which is not yet detached. * * @param txInit the {@code TransactionInitializer} * @param selector an optional {@code NodeSelector} defining the target node * @param currentData the current data of the model * @param resolver the {@code NodeKeyResolver} * @return a flag whether the operation has been completed successfully */ private boolean executeTransactionOnCurrentStructure( final TransactionInitializer txInit, final NodeSelector selector, final TreeData currentData, final NodeKeyResolver<ImmutableNode> resolver) { boolean done; final ModelTransaction tx = new ModelTransaction(currentData, selector, resolver); if (!txInit.initTransaction(tx)) { done = true; } else { final TreeData newData = tx.execute(); done = structure.compareAndSet(tx.getCurrentData(), newData); } return done; }
tx.getCurrentData()); if (results.size() == 1) tx.getCurrentData()); if (addData.isAttribute())
@Override public boolean initTransaction(final ModelTransaction tx) { boolean added = false; final NodeUpdateData<ImmutableNode> updateData = resolver.resolveUpdateKey(tx.getQueryRoot(), key, value, tx.getCurrentData()); if (!updateData.getNewValues().isEmpty()) { initializeAddTransaction(tx, key, updateData.getNewValues(), resolver); added = true; } final boolean cleared = initializeClearTransaction(tx, updateData.getRemovedNodes()); final boolean updated = initializeUpdateTransaction(tx, updateData.getChangedValues()); return added || cleared || updated; } }, selector, resolver);
/** * Initializes a transaction for an add operation. * * @param tx the transaction to be initialized * @param key the key * @param values the collection with node values * @param resolver the {@code NodeKeyResolver} */ private void initializeAddTransaction(final ModelTransaction tx, final String key, final Iterable<?> values, final NodeKeyResolver<ImmutableNode> resolver) { final NodeAddData<ImmutableNode> addData = resolver.resolveAddKey(tx.getQueryRoot(), key, tx.getCurrentData()); if (addData.isAttribute()) { addAttributeProperty(tx, addData, values); } else { addNodeProperty(tx, addData, values); } }
/** * Executes this transaction resulting in a new {@code TreeData} object. The * object returned by this method serves as the definition of a new node * structure for the calling model. * * @return the updated {@code TreeData} */ public TreeData execute() { executeOperations(); updateParentMapping(); return new TreeData(newRoot, parentMapping, replacementMapping, currentData.getNodeTracker().update(newRoot, rootNodeSelector, getResolver(), getCurrentData()), updateReferenceTracker() ); }
final TreeData currentStructure = tx.getCurrentData(); final List<QueryResult<ImmutableNode>> results = resolver.resolveKey( tx.getQueryRoot(), key, currentStructure);
@Override public boolean initTransaction(final ModelTransaction tx) final TreeData current = tx.getCurrentData(); final String newRootName = determineRootName(current.getRootNode(), node, rootName);