How to check if a node exists in CQ extjs? - extjs

Is there a way to check if a node exist and then get the fetch the property value of it?

Use CQ.Util.eval function and pass the node path followed by the .json extension as a single arugment:
var node = CQ.Util.eval('/content/geometrixx/en/jcr:content.json');
If the node doesn't exists you'll get null. Otherwise you can get properties using brackets:
if (node != null) {
console.log(node['jcr:title']);
}

Related

opengl assimp skeletal node transformation

if i have a setup where in order to transform a bone, I have to:
node.transform = scale(node.transform, 2, 2, 2)
then
bone_transform = inverse:offset_matrix *
(node.parent.transform * node.transform) * (inverse:node.parent.transform) * offset_matrix
However this only works properly for bones that doesn't have any children (or the bottom-most in the node hierarchy)..
therefore having trouble when traversing through the bones part..
how would I do this correctly to get the correct bone_transform for all bones..
So if I want to transform any bone anywhere in the hierarchy (using node.transform), it would also adjust all its children bone_transforms correctly..
maybe something like:
mat4 transform = node.transform
while (node.parent != 0) {
if (node.is_bone) {
transform = node.parent.transform * node.transform
}
node = node.parent
}
or something with node.children recursively?
The offset-matrix is already the global transformation for your bone. It contains already all the transformation data from the root down to your current bone.
That is the reason that your code only works for bones without any parent nodes.

Store values that are created in a loop outside of the loop in rust

I am working on a little parser that takes an S-Expression and transforms it into a tree data structure. Since trees are not so easy in Rust to do bidirectional I want to make it only one-directional (each node only knows it's children, not it's parents). To still be able to access nodes that have been created in the past, I want to store all nodes in a Vector and keep an index that tells me which node is where. E.g. a node would have a field parent_index, with the index of it's parent node in the vector, without needing to have a direct reference to it.
So, while I iterate over the String that is my s-expression, I am creating new nodes and want to push them into the vector, as well as assigning child relationships.
for clarifications an S-Expression can be this (w1 (w2 t1) (w3 t2)) or something like this (S (F (FIRSTWORD This) (SECONDWORD is)) (Z (THIRDWORD a) (FOURTHWORD sentence))), or just a terminal like Hello
A lot is still missing but my idea looks like this. My question now is: How can I create all these Trees inside the loop and store them into the vector outside of the loop?
It seems that the borrow checker has some probelems with this...
I am very grateful for any help! Thank you :)
My idea looks like this:
pub struct Tree{
pub root: String,
pub children: Vec<Tree>
}
fn parse_to_tree(mut s_expr: String) -> Tree{
// Vector for all nodes
let mut all_nodes:Vec<&Tree> = Vec::new();
// Index of node we are working on
let mut curr_node_index = 0;
while !s_expr.is_empty(){
// get first char from s expression
let mut c_c = s_expr.remove(0);
//Names: c_c: current_char, c_w: current:word
// only continue if we start with '(', otherwise Leaf
while c_c == '('{
let mut c_w = String::from("");
while c_c != ' '{
c_c = s_expr.remove(0);
c_w.push(c_c);
}
println!("{}", c_w);
let node = Tree{root: c_w, children: Vec::new()};
//Here I want to push the node by reference to the all_nodes_vector
all_nodes.push(&node); // HERE occurs the error: borrowed value does not live long enough...
if !all_nodes.is_empty(){
// Here I want to to push the new node as a child to the old current_node
all_nodes[curr_node_index].children.push(node);
}
curr_node_index += 1;
}
return Tree{root: s_expr, children: Vec::new()};
}
return Tree{root: s_expr, children: Vec::new()};
}
You cannot do that (safely): someone, somewhere, while building this tree, will have to hold both a node and the list of nodes that contains this node. And (at least) the reference to the node will be mutable (because we need to build it), causing a violation of the borrow rules.
The solution is simple: just give up on using references. Store all nodes in a vector, and only keep indices to this vector. This is easy, effective and idiomatic.

Removing unused nodes from JackRabbit versionStorage

I have a scenario where a repository contains several version nodes that don't reference any mix:versionable nodes. This is because those versionable nodes have been removed from repository but not their corresponding versions.
This is causing that the JackRabbit Garbage collector cannot remove some files from datastore, because there are versions that still reference them, and consequently the disk space is not properly freed.
I tried to manually remove those versions with the following algorithm:
Obtain a version by its path, let's say: /jcr:system/jcr:versionStorage/40/05/a9/4005a9b2-51d1-4ed1-8c30-934409e05f86/1.14/jcr:frozenNode
Get the jcr:frozenUuid property from the obtained node
Get the node by identifier, using the frozenUuid from step 2
If no such node exists, remove the version
But in the last step I get the following exception:
javax.jcr.nodetype.ConstraintViolationException: Unable to perform operation. Node is protected.
So, my question is. How can I remove the version nodes that are unused?
I'm using jackrabbit-2.2.13.
This is how I remove my versions...
String nodePath...
String versionName...
Session session...
VersionManager versionManager = session.getWorkspace().getVersionManager()
VersionHistory versionHistory = versionManager.getVersionHistory(nodePath);
versionHistory.removeVersion(versionName);
I think this will help you to traverse all the versions so that you can remove or restore.
Node vs = session.getRootNode().getNode("jcr:system").getNode("jcr:versionStorage");
Version v = traverseVersionStorage(vs, 0);
private static Version traverseVersionStorage(Node n, int level)
throws Exception {
Version v = null;
for (NodeIterator it = n.getNodes(); it.hasNext();) {
Node n2 = it.nextNode();
if (n2 instanceof Version && !n2.getName().startsWith("jcr:")) {
v = (Version) n2;
System.out.println("version " + n2.getName() + " of node "+ n2.getParent().getName() + ":");
Node n3 = n2.getNode("jcr:frozenNode");
VersionManager vman=session.getWorkspace().getVersionManager();
Node parent=n3.getParent();
System.out.println(parent.getName());
vman.restore("/any/path/where/to/restore", v, true);
session.save();
}
Version v2 = traverseVersionStorage(n2, level + 1);
v = v == null ? v2 : v;
}
return v;
}
below code is to traverse all versions of a node and remove by versionName
VersionManager versionManager=jcrsession.getWorkspace().getVersionManager();
VersionHistory vHistory=versionManager.getVersionHistory("/absolute/path/of/node/which/versions/to/be/removed");
for (VersionIterator pt = vHistory.getAllVersions(); pt.hasNext();)
{
Version p = pt.nextVersion();
if(p.getName()!="jcr:rootVersion")
{
vHistory.removeVersion(p.getName());
}
}

Wait until Angular has finished processing a model change before accessing scope

I'm using angular-ui-tree to make a scorecard application that has a hierarchy of scorecard nodes. My scorecard nodes are persisted through a web service layer and have their own ID numbers to identify them.
In order to work with a scorecard node by ID, I implemented the following method:
// get a node scope by a Scorecard Node ID.
function getNodeScopeByNodeID(id, nodesScope) {
nodesScope = nodesScope || getRootNodesScope().$nodesScope;
var nodes = nodesScope.childNodes();
for (var i = 0; i < nodes.length; i++) {
var result;
if (nodes[i].$modelValue.ID == id)
result = nodes[i];
else {
var subScope = nodes[i].$childNodesScope;
if (subScope) {
result = getNodeScopeByNodeID(id, subScope);
}
}
if (result)
return result;
}
return undefined;
}
The details here aren't super important except to say that this method crawls the nested scopes that make up the tree until it finds a scope whose $modelValue (my scorecard node state) has the ID we're looking for. It works great, except when I do something like this:
// add a new objective node to the root of the scorecard.
$scope.newObjective = function () {
var scope = getRootNodesScope();
var rootArray = scope.$nodesScope.$modelValue;
scorecardService.addObjective($scope.selectedScorecard, rootArray)
.then(function (d) {
rootArray.push(d);
$scope.edit(getNodeScopeByNodeID(d.ID));
})
.catch(errorHandler);
}
Note the two lines in the "then" function. I'm asking my service to create a new node, and when I get it I'm pushing it into an array that is part of the model. I want my newly inserted node to immediately flip into "edit" mode (which reveals some form controls inside it.) But the call to getNodeScopeByNodeID immediately following the push fails. If I debug it it looks like the scope hasn't caught up with the model yet. I have one more node in my node array (model) than there are child scopes where I expect them to be.
I think I just have to give angular a chance to react to the model change before I start going through the scope to find what I'm looking for. How do I do that?

Get File Out of JCR File Node

I have the following code to insert "rose.gif" into a roseNode. But how do I retrieve the file from the repository?
Node roseNode = session.getRootNode().getNode("wiki:encyclopedia/wiki:entry[1]/");
File file = new File("rose.gif");
MimeTable mt = MimeTable.getDefaultTable();
String mimeType = mt.getContentTypeFor(file.getName());
if (mimeType == null) mimeType = "application/octet-stream";
Node fileNode = roseNode.addNode(file.getName(), "nt:file");
System.out.println( fileNode.getName() );
Node resNode = fileNode.addNode("jcr:content", "nt:resource");
resNode.setProperty("jcr:mimeType", mimeType);
resNode.setProperty("jcr:encoding", "");
resNode.setProperty("jcr:data", new FileInputStream(file));
Calendar lastModified = Calendar.getInstance();
lastModified.setTimeInMillis(file.lastModified());
resNode.setProperty("jcr:lastModified", lastModified);
//retrieve file and output as rose-out.gif
File outputFile = new File("rose-out.gif");
FileOutputStream out = new FileOutputStream(outputFile);
The only thing you really need to do is get the name of the file from the name of the "nt:file" node, and the content for the file from the "jcr:data" property on the "jcr:content" child node.
JCR 1.0 and 2.0 differ a bit in how you get the stream for the binary "jcr:data" property value. If you're using JCR 1.0, then the code would be like this:
Node fileNode = // find this somehow
Node jcrContent = fileNode.getNode("jcr:content");
String fileName = fileNode.getName();
InputStream content = jcrContent.getProperty("jcr:data").getStream();
If you're using JCR 2.0, the last line is a bit different because you first have to get the Binary object from the property value:
InputStream content = jcrContent.getProperty("jcr:data").getBinary().getStream();
You can then use standard Java stream utility to write the bytes from the 'content' stream into the file.
When you're done with the Binary object, be sure to call the Binary's dispose() method to tell signal that you're done with the Binary and that the implementation can release all resources acquired by the Binary object. You should always do this, even though some JCR implementations try to catch programming errors by returning a stream that, when closed, will automatically call dispose() for you.

Resources