I am trying to create a nested tree view with Custom Pojo Node in Spring MVC, the input that I have from the JSch library after exec command1="find $(pwd) -maxdepth 1 -type f -not -path '*/\\.*' | sort"
will be a list of Strings which contains Absolute Paths for files under the current working directory, as shown in the example below.
`List<String> paths = [
"/Sample Dir/sample.cpp",
"/Sample Dir/New Folder",
"/Sample Dir/New Folder/Sample.txt"];`
I need to create a hierarchical JSON object with the following Model:
public class Node {
private String name;
private String location;
private List<Node> children;
}
I'm trying to figure out the algorithm, how to represent file paths as a Node class which gives the below JSON. Below is the code which I tried, which is having some problems which i'm unable to figure out.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
public class DemoMainClass {
public static void main(String[] args) throws Exception{
Node root = new Node("/");
AddNode("/Sample Dir/sample.cpp", root);
AddNode("/Sample Dir/New Folder", root);
AddNode("/Sample Dir/New Folder/Sample.txt", root);
AddNode("/Sample Dir/New Folder/demo.txt", root);
ObjectMapper Obj = new ObjectMapper();
String jsonStr = Obj.writeValueAsString(root);
System.out.println(jsonStr);
}
public static Node AddNode(String filePath, Node rootNode) {
// convenience method. this creates the queue that we need for recursion from
// the filepath for you
if(filePath.startsWith("/")) {
filePath = filePath.split("/",2)[1];
}
List<String> tokenList = Arrays.asList(filePath.split("/"));
tokenList.remove(" ");
// if you split a folder ending with / it leaves an empty string at the end and
// we want to remove that
if (StringUtils.isBlank(tokenList.get(tokenList.size() - 1))) {
tokenList.remove(tokenList.size() - 1);
}
PriorityQueue<String> queue = new PriorityQueue<String>();
queue.addAll(tokenList);
return AddNode(queue, rootNode);
}
private static Node AddNode(Queue<String> tokens, Node rootNode) {
// base case -> node wasnt found and tokens are gone :(
if (tokens == null || tokens.isEmpty()) {
return null;
}
// get current token, leaving only unsearched ones in the tokens object
String current = tokens.remove();
// create node if not already exists
Node foundNode = rootNode.FindNode(current);
if (foundNode != null) {
// node exists! recurse
return AddNode(tokens, foundNode);
} else {
// node doesnt exist! add it manually and recurse
Node newNode = new Node(current);
rootNode.getChildren().add(newNode);
return AddNode(tokens, newNode);
}
}
}
class Node {
public String name;
public List<Node> children;
public String location;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Node() {
this.children = new ArrayList<Node>();
}
public Node(String fileName) {
this.children = new ArrayList<Node>();
this.name = fileName;
}
public Node FindNode(String data) {
if (this.children == null || this.children.isEmpty()) {
return null;
}
// check Node list to see if there are any that already exist
return this.children.stream().filter(node -> node.getName().equalsIgnoreCase(data)).findFirst().orElse(null);
// .FirstOrDefault(n => n.Data.equalIgnoreCase(data));
}
}
Below is the Output i'm getting:
{"name":"/","children":[{"name":"Sample Dir","children":[{"name":"sample.cpp","children":[],"location":null}],"location":null},{"name":"New Folder","children":[{"name":"Sample Dir","children":[{"name":"Sample.txt","children":[],"location":null},{"name":"demo.txt","children":[],"location":null}],"location":null}],"location":null}],"location":null}
Desired Output is as below,
[
{
"name": "Sample Dir",
"location": "Sample Dir",
"children": [
{
"name": "New Folder",
"location": "Sample Dir/New Folder",
"children": [
{
"name": "Sample.txt",
"location": "Sample Dir/New Folder/Sample.txt",
"children": "null"
}
]
},
{
"name": "sample.cpp",
"location": "Sample Dir/sample.cpp",
"children": "null"
}
]
}
]
Could you help me to where I'm wrong? Any leads are appreciated, thanks in advance.
You're using PriorityQueue which will return the tokens in ascending order as no comparator is provided. In a priority queue the poll/remove method will remove the smallest element (depends on comparator) first. Instead you should use LinkedList which will work on FIFO principle. Update this
PriorityQueue<String> queue = new PriorityQueue<String>();
To this
Queue<String> queue = new LinkedList<>(tokenList);
This should give you the desired output except for the location for which the logic is missing.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.