(JCR) Version of a child frozen node - jackrabbit

My question is : how do you read the version of a (child) frozen node?
More details :
- Lets imagine the following situation : node A has two children node B and node C.
- All three nodes are versionable nodes (have the mixin type)
- Let's say node A has 7 versions from 1.0 to 1.6 : at version 1.2 we added node B, at version 1.4 we added node C.
I have a routine that prints the "output" of node A at version 1.5.
//I already obtained the Version object version associated to node A version 1.5
NodeIterator nodeIterator = version.getNodes();
while (nodeIterator.hasNext()) {
Node currentNode = nodeIterator.nextNode();
System.out.println("Node: "+currentNode.getPath());
// I can see that some of the nodes correspond to children (versions) of
//node B and C ..how can I get their version?
}
Thank you.

Each version in the history of the parent will contain a "frozen node" that represents a snapshot of the parent as it existed when the version was created (e.g., when the parent node was checked in). This frozen node contains child nodes that are either snapshots of the child (if the child was not versionable) or a "nt:versionedChild" node (if the child was versionable). This "nt:versionedChild" node contains a single "jcr:childVersionHistory" REFERENCE property that points to the version history of the child.
Section 3.13.10 of the JSR-283 specification contains a pretty good diagram that shows this structure.
Note that the "nt:versionedChild" node does not point to the particular version in the child's version history, which means that you have to determine which version of the child existed at the time the parent was checked in. After all, in this case of a versionable child, the parent and child version histories are independent and the nodes are checked in independently. (The reason might also stem from the fact that the application can change both the parent and child nodes in a single session, and then either check the parent in followed by checking the child in, or checking the child in followed by checking the parent in.)
One way to do this is by looking at the creation date of each version in the child's version history. This isn't ideal, as it will only tell you which child version existed at the time the parent was created. This could be ambiguous, since the comparison of timestamps depends on whether the parent was checked in before or after the versioned child. Within your application, you might have conventions that help you get around these ambiguities.
Perhaps a better option is to use version labels and apply the same label to the parent version and child version. (This is probably easier to do just after checking in the nodes rather than at a later time.) Then once you have a particular version of the parent, obtain its label and use it to find the corresponding version of the child in the child's version history (using VersionHistory.getVersionByLabel(String)).

Related

ReactJS sortable dnd tree setup

React newbie again.
I have and admin page for a forum. It's a tree structure with potentially infinite depth, ordered by order_id field.
I can get it from the api either as a tree (with a children array field holding the children of each node) or as a flat array with an ancestry (a string that holds the whole path to the node, separated by a /) and a parent_id field.
I need to be able to move them around, expand and collapse subtrees and be able to add a node in any place.
Now I have several questions:
Is there a good out-of-the-box UI library to be able to drag-drop them to rearrange? I found this one: https://github.com/frontend-collective/react-sortable-tree but I can't get it to not have a limited height frame, and also customizing those themes looks too complicated.
If I am to do it from scratch using react-dnd, what is the more efficient way of working with this tree - have it as a tree (how do I add/update the nodes?) or store it flat and build the tree on render (easy to manage the collection, but complicates rendering and sorting logic).
This sounds like a complicated and interesting problem. If the library cannot do what you want it to stylistically then you will have to build it from scratch.
I would store all of your node objects in an Array with a children property that holds a reference to all of it's children; you could use their order_id as a reference if it is guaranteed to be unique.
I would also store the parent node's order_id as well, as it will help when you manipulate the tree.
Nodes = [
{order_id: 1, name:"order1", children_ids:[2,3], parent_id: 0},
{order_id: 2, name:"order2", children_ids:[], parent_id: 1},
{order_id: 3, name:"order3", children_ids:[], parent_id: 1},
]
You will have to build the tree on render, it may be a brain twister but it's more than doable with a bit of work.
When you add a new node, you will have to update the parent and children of it's new spot in the tree.
When you rearrange a node, you will have to travel up to the parent and remove it from it's children. You will also have to travel down to it's children and set their parents to the rearranged node's old parent. This removes the node from the tree. Then, add the rearranged node to the tree.
Any manipulation you do will involve manipulating the parent and children of that node - this is why I recommend storing both children's id and the parent's id. It saves you from having to do too many tree traversals which is not computationally efficient.
I don't recommend using an ancestry field as you mentioned. The logic for moving nodes around will be too complicated and you would have to traverse and edit potentially the entire tree if you do it this way.
The first step is to integrate with react-dnd; make each node draggable. When you drop it onto another node to rearrange, you trigger your rearrange handler.
Best of luck.

how to use jump to if I need to evaluate a condition of context variable for two different nodes at same time

I have one parent node ,based on the user input Iam setting a context variable at my application level eligibility:yes or no and passing back.And for my parent node I have two child nodes for conditions $eligibility=="yes" and $eligibility=="no".So once users input from parent node validation is done and context variable is passed back ,then I need to jump and look for condition of eligibility.If yes I need to go one node ,if no then to other.How can I do?
I tried putting true to node and added these two nodes to this and jump to true..But didnt worked..How can we achieve this?
what #data_henrik has mentioned is a good way to set context value and then switch to different flows depending upon the set value. But when you need to perform some logic before setting that value in the context from your application, it won't be a suitable way.
I had a requirement like this, so we used to send a dummy text from our application after we were done with setting the value in context after the parent node execution. Check out the images and explanation after that.
We didn't use Jump because we had to do some validation in the Conversation service after parent node before moving forward. Using jumps would've allowed the Conversation to move to next node before we could set value in context.
Use case flow - once user enters text for the parent node intent, for my case "#send-mail" intent, I show the parent response and do some functional validation in my app after that and add a value to the context. Now we send a dummy text "valid" which satisfies the intent "#Valid" and hence move to the next node in flow. In this node we check for the value in context (which is already set by now) and show appropriate response to user.
You can set within your first two test nodes, $testMe==true and $testMe==false a temp output variable within the output json packet, i.e. output{"temp":"true"} or "false". Then you can jump to a new set of nodes and test for the output.temp value, i.e. output.temp == 'true' then do something, or output.temp == 'false' then do something.
The nice side effect of this action is that the output.temp variable only has a life of that current conversation input. Unlike context variables which need to be removed / deleted.

level order queue implemmentation in C

I understand the logic of using a queue to visit the nodes in a binary search tree level by level.
However i tried to implemment in C but i'am stuck because i don't know how to enqueue them properly. Starting with the root i can create a Queue but after that if i add the children of the root to the queue i will lose the children of those new nodes since iam modifying the connections in the Queue every time a add a new node.
I could create a new data type that has one more link to use in the linked list Queue, that should work. What is the best approach here?
visit[ing] the nodes in a binary search tree level by level
has a name: it is called a "breadth-first" traversal of the tree. Starting with an empty queue, you enqueue the root node and then repeatedly dequeue the first node in the queue, process it somehow, and enqueue all that node's children, until there are no more nodes enqueued. When exactly you should enqueue a node's children relative to other processing of that node may depend on exactly what processing you intend to perform, especially if it involves structurally modifying the tree.
As long as the per-node processing can affect only the subtree rooted at the then-current node, this is all fine. If you need to be able to affect other parts of the overall tree, however, then a breadth-first traversal probably is not appropriate for your task.
You said
[I] don't know how to enqueue them properly. Starting with the root [I] can create a Queue but after that if [I] add the children of the root to the queue [I] will lose the children of those new nodes since [I] am modifying the connections in the Queue every time a add a new node.
The key concept here is that membership and position in the queue are separate and independent from membership and position in the tree. You could manage that by adding additional links to the node structures themselves, or by creating a new structure for the queue elements that contains a pointer to the enqueued BST node. The latter decouples the tree from the queue, which many, including me, would consider preferable for most purposes.

What do you call a parent with no children?

I have some code where the user can delete one child record of a parent record one at a time. I'm detecting when there are no children left. At that point, I'm deleting the parent record as well. When coming up with a name for the variable, I realized I don't know what you call a parent with no children.
Is there a single, accepted name that I haven't heard of (or can't remember)?
Leaf: (no children)
Terminal: (never children)
Vacant: (had children)
Orphan: (no parent)
Leaf seems pretty standard according to wikipedia. "Terminal Node" on wikipedia will re-direct you to leaf node.
Vacant node in more detail:
Your orphanage had a child. The child got adopted and left. Your orpahage is now vacant.
Terminal node in more detail:
Example in OpenGL:
An EBO references a VAO.
A VAO references a VBO.
A VBO is raw data and references nothing else.
( EBO --> VAO --> VBO )
Thinking of the VBO as a "terminal node" would make more sense than thinking of it
as a leaf. Because it will not and cannot have children.
There are two common computer science notions of parent: relative/transitive and absolute/non-transitive. One node can be the parent of another (a child). (Hence, object of a transitive "is" or "parents"). A node with no children is a leaf node; a node with children is a parent node. (Hence, object of a non-transitive "is"). Neither of these involve the non-instantaneous notion of ever once having had children, eg as in the real world.
Each node of the type you are describing is during processing (before and after pruning) both a parent and not a parent. So you are using something like the non-instantaneous/real-world third meaning, something like "was a parent but isn't any more". (Think about what you're saying: it's a parent in the sense that it used to be a parent node even though it's not a parent node. So it's a parent ...because... it's not a parent.)
Once it's going to be deleted, how about NoLongerParent? But if you're just using a name for that node for all the processing, and it starts as a non-leaf, why not just Parent?

ExtJS Find Node within Tree Branch

I'm trying to check whether a certain node exists beneath a branch of an ExtJS tree. Knowing the ID of the parent node, is there a library function to check whether a node exists beneath the parent (by its ID)?
I've checked the API numerous times over, and can only seem to accomplish this by iterating through the entire branch of the tree.
Is there a library function which allows me to check if a child exists (by its ID) if the parent node ID is known?
Thanks!
PS, to find the parent ID, I'm using the following:
tree.getNodeById('myID');
Ext.tree.TreeNode "contains" function does exactly what you want:
var parent = tree.getNodeById('myID');
parent.contains(tree.getNodeById('childId'));
Have you looked at DomQuery? The API defines the method jsSelect: selects a group of elements.
jsSelect( String selector, [Node/String root] ) : Array
Parameters:
selector : String
The selector/xpath query (can be a comma separated list of selectors)
root : Node/String
(optional) The start of the query (defaults to document).
Returns an Array of DOM elements which match the selector. If there are no matches, and empty Array is returned.

Resources