In Java how do I create a structured tree using FileVisitor - java

Given a starting path I want to create a tree like object representing the filesystem using Java, showing all the folders down to level x but not ordinary files. . So using FileVisitor I know that every time just before Im going to browse a new subfolder that the preVisitDirectory() method will be called and once it had completed parsing all its children the postVisitDirectory() will be called, but my problem is knowing how to attach this directory to its parent.
i.e in my case I want to create data for jstree using ul/li/ul/li elements, and Im doing this with j2html lib. So create root using ul(), then when I go into preVisitDirectory() I would create a li() element and in postVisitDirectory() would want to attach to ul() using ul().with(li) but I cant see how to keep track of where I am in building my tree.
e.g static hard coded example not actually browsing tree
public Tag createBrowseTreeAsHtml()
{
Tag ulTag = ul(
li("ChildNode 2").withId("child_node_1"),
li("ChildNode")
);
Tag divTag= div(
ul(
li("Root Node 1").with(ulTag),
li("Root Node 2")
)
)
.withId("jstree");
return div().with(divTag);
}
I see Guava has support for Graphs, should I be utilising this somehow ?

Related

How to force Jena API's findShortestPath method to do BFS on <owl#onProperty> instead of <owl#someValuesFrom>?

I am trying to find the shortest path or a path between two nodes in an ontology using Jena's above mentioned method.
Given any two nodes of the ontology, my eventual goal is to create a SPARQL query with this path to query the data at the two nodes and a path is required as SPARQL needs a path as follows (if the 2 nodes are not directly connected)
SELECT ?var1 ?var3
WHERE {
?var1 <someProperty> ?var2.
?var2 <someProperty> ?var3.
}
Currently I am getting a path for most of the nodes using Jena, that are connected but the relationship between them is
[[http://myontology/Node1, http://www.w3.org/2000/01/rdf-schema#subClassOf, cbc3c5-d026-49-94d9-e3ba],
[cf3c5-d026-49-94d9-e3ba, http://www.w3.org/2002/07/owl#someValuesFrom, http://myontology/Node2]]
and so on till Node3.
I would like the path to be as
[[http://myontology/Node1, http://myontology/myPropertyABC , http://myontology/Node2,]
[http://myontology/Node2, http://myontology/myPropertyXYZ , http://myontology/Node3]]
I am currently building the query as
SELECT ?var1 ?var3
WHERE {
?var1 ?x ?var2.
?var2 ?y ?var3.
}
This gets me the answer but is a very unoptimized query so I'd prefer to generate the property based query. I tried to walkthrough the shortest path method by priniting it's entire BFS trace and noticed it does search on owl#onProperty. So while supplying the method the onPath argument, how to construct the object to force to only look at onProperty? (PS- Any other way of achieving the goal is welcomed)
The method signature is,
public static Path findShortestPath( Model m, Resource start, RDFNode end, Predicate<Statement> onPath )
Also, Jena fails to find the path at all in a lot of cases when the end node is related to a path in the inverse fashion, for example
Node1 -> Node2 -> Node3 -> Node4 <- Node5.
Will reach Node4, but can't get to Node5. This is restricting the ability to address the entire graph and only forward relationships are being addressed.
Any other RDF API's that achieve this, python or java based are also welcome.
(Looked at rdf4j and protege but seems like jena only has this traversal feature)
Would really appreciate any help on this!
Please let me know if additional details are required.

Programmatically arranging contents in aem 6.4

everyone. I'm new in working with aem. I'm using aem 6.4. My task is to programmatically sort the order of the contents of a cq:project in aem depending on the content of a JSON file.
The content of the JSON file should be set as the initial child instead of the children sorted by their creation date.
This is the current structure of my cq:page. If the child2 is the one indicated in the JSON file, it should be the first one to be displayed. The content of the JSON file is just the name of one child so even though there are 10 children, the content of the JSON file should always be the first one in the list.
I've spent hours researching on how I can implement this although I still can't find any solution. Any insights on how should I create this? Thanks!
As I understand it, you want a way to order a named child of a cq:Page to be first in the list.
This is possible because cq:Page is an orderable node. This would not be possible otherwise. you chan check any nodetype in CRX Explorer.
I think adding the bit about JSON complicates the question. You just need a simple method such as the following:
private void orderAsFirstChild(String childName, Node parentNode) throws RepositoryException {
if (parentNode.hasNode(childName)) {
// find current first child name
String firstChildName = Optional.ofNullable(parentNode.getNodes())
.map(NodeIterator::nextNode)
.map(node -> {
try {
node.getName();
} catch (RepositoryException e) {
e.printStackTrace();
}
return (String) null;
}) //
.orElse(null);
parentNode.orderBefore(childName, firstChildName);
}
}
You should probably clean this up a little, but this is the general idea using Node#orderBefore
This may helps -
Get the children from the parent node.(you will get 'iterator' convert it to list here-Convert Iterator to ArrayList)
Delete all child nodes now. And keep the back up of above list.
iterate through the list , identify the node which you want place first(by title or some other property) add that to a separate set(LinkedHashSet- to maintain order).
Now add the remaining items/nodes in the same order after your specific node in the above set.(you may need to iterate through again)
Now this Set has nodes/Resources in the order which you want, iterate , create nodes and save your changes.

AEM asset Is there any way to move a file by creating a folder in a workflow in java

I want to move few assets by creating a new folder using only the workflow in java.I dont want to create the folders manually and then move the assets as there are 10000s of assets that are to be moved to different folders.
If you are looking at creating folder using workflow - A folder in AEM is nothing but a node of jcr:primaryType either sling:Folder or sling:OrderedFolder. If you have com.day.cq.commons.jcr in your classpath, createPath method will help you create a node if it does not exist.
You could also use addNode method followed by setProperty method from javax.jcr.Node api to create this folder of appropriate primary type.
Moving assets to this newly created node(folder), can proceed after this. You could use the clone method from javax.jcr.WorkSpace which has an option to remove the existing node.
There is another straight forward way to move assets.
I would recommend you to use built-in com.adobe.granite.asset.api.AssetManager api to perform CRUD operations on DAM assets.
session = resourceResolver.adaptTo(Session.class);
String assetPath = "/content/dam/folderA/asset1.jpg";
String movePath = "/content/dam/folderB/asset1.jpg";
assetManager.moveAsset(assetPath, copyPath);
session.save()
session.logout()
Further references for AssetManager API.
HelpX Article
API Details
Moving large number of assets might cause the move operation to fail if there no appropriate indexes in place. Monitor logs for warning messages like The query read or traversed more than X nodes.. You might have to add oak based properties to the out-of-the-box /oak:index/ntBaseLucene index to fix this.
More details here.

XWiki extension : detect event space creation

Based on the documentation here we can see that in a xwiki java extension, we can intercept the event UserCreation like that :
https://extensions.xwiki.org/xwiki/bin/view/Extension/Observation%20Module%20Local#HWritinganEventListenerinVelocityinaWikipage
public void onEvent(Event event, Object source, Object data)
{
XWikiDocument document = (XWikiDocument) source;
String wikiName = document.getDocumentReference().getWikiReference().getName();
DocumentReference userClass = new DocumentReference(wikiName, "XWiki", "XWikiUsers");
if (document.getXObject(userClass) != null) {
}
I want the same thing, but I want to detect the event space creation ( so basically when you add a space( basically a space is the main root page of an article ) in your wiki. But I didn't found any class like XWikiUsers for the space or the page.
It don't want to do it with velocity or groovy but in pure java extension and I have no clue, the doc is very huge but it's hard to found what I' looking for.
Technically, a "space" gets created whenever a page is created under it (either terminal page or WebHome).
So you could either:
do a query each time a page is being created (DocumentCreatingEvent, so not yet DocumentCreatedEvent) and then do a query (see https://extensions.xwiki.org/xwiki/bin/view/Extension/Query%20Module) to see if the space (matching the new document's space reference) matches an existing one or a deeper nested one inside the database... or
check if the newly created document (DocumentCreatedEvent) has the name WebHome which would be much better in terms of performance, but it will not work if you are working with terminal documents (i.e. other documents than 'WebHome' ones, see https://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide/Features/ContentOrganization/#HTerminology

How to read a file system using Spring

What I need: I need a method that, given a specific directory name on my app, will return his content.
/root
/folder1
/folder11
/folder12
/folder2
/folder21
/file21.txt
/folder3
/file31.txt
/file32.txt
For example, if I call myMethod("/root"); it will return to me a certain object list containing {'folder1', 'folder2', 'folder3'}. Calling myMethod("/root/folder2"); will return {'folder21', 'file21.txt'}
Question: how can I implement this kind of function using Spring?
You can use java.io.File if it is a directory you list childs with docx.list() and then recursively you can do that for all childs that are directories

Categories

Resources