Switch to side-by-side view

--- a/tool/run/plugins/basic/TreeNodeDetails.java
+++ b/tool/run/plugins/basic/TreeNodeDetails.java
@@ -17,13 +17,19 @@
 import GUI.TreeNodeSPDX;
 import GUI.swingUtils;
 import definitions.Messages;
+import definitions.definition;
 import definitions.is;
+import java.awt.Cursor;
 import java.io.File;
+import java.util.Collection;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
 import main.core;
 import main.param;
 import script.Plugin;
 import script.log;
+import spdxlib.FileInfo;
 import spdxlib.Person;
 import spdxlib.SPDXfile;
 
@@ -81,8 +87,238 @@
         
         // basic parts were done, now add up the needed details
         addPeople(spdx, node);
-        
-        
+        addFiles(spdx, node);
+        
+        
+        // all done, time to refresh things up
+        swingUtils.setSelectedNode(node.getUID());
+        // refresh things up
+        core.studio.getTree().repaint();
+        
+    }
+    
+    
+    /**
+     * Add the files inside this SPDX document
+     */
+    private void addFiles(SPDXfile spdx, TreeNodeSPDX spdxNode){
+        // title of the node that we want to create
+        String title = "Files";
+        
+        // do we have more than one reviewer?
+        if(spdx.fileSection.files.size() > 1){
+            title = "Files " 
+                    + " ("
+                    + spdx.fileSection.files.size()
+                    + ")";
+        }
+        
+        // let's add the main node for files
+        TreeNodeSPDX node = swingUtils.nodeCreate(
+                title, 
+                NodeType.sectionFile, spdxNode);
+        node.nodeType = NodeType.sectionFile;
+        node.id = "./";
+        node.setUserObject(spdx.fileSection);
+
+        
+        
+        core.studio.getTree().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        // create the tree structure
+        doTreeStructure(node, spdx);
+        // if an exception occurs, this next line doesn't happen..
+        core.studio.getTree().setCursor(Cursor.getDefaultCursor());
+       
+        
+    }
+    
+    
+    /**
+     * Creates a tree of folders and respective files
+     * @param root
+     * @param spdx 
+     */
+    private void doTreeStructure(TreeNodeSPDX root, SPDXfile spdx){
+        // go through all the files inside the SPDX 
+        for(FileInfo fileInfo : spdx.fileSection.files){
+            // get the path for this file bit
+            String path = getFilePath(fileInfo);
+            //String parentFolder = getParentFolder(path);
+            // add it up to our list
+            TreeNodeSPDX pathNode = addNodeFolder(root, path);
+        }
+        
+        
+         for(FileInfo fileInfo : spdx.fileSection.files){
+            // get the path for this file bit
+            String path = getFilePath(fileInfo);
+            //String parentFolder = getParentFolder(path);
+            // add it up to our list
+            TreeNodeSPDX pathNode = addNodeFolder(root, path);
+            
+            TreeNodeSPDX nodeFile = new TreeNodeSPDX(getSimpleName(fileInfo));
+            nodeFile.id = fileInfo.getName();
+            nodeFile.nodeType = NodeType.file;
+            nodeFile.setUserObject(fileInfo);
+            // add this file to the parent path
+            pathNode.add(nodeFile);
+        }
+       
+        
+    }
+     
+    
+    /**
+     * Provides a pretty name to place on the tree view
+     * @param fileInfo
+     * @return 
+     */
+    private String getSimpleName(FileInfo fileInfo){
+        String result = fileInfo.tagFileName.getValue();
+        if(result.contains("/")){
+            return result.substring(result.lastIndexOf("/")+1);
+        }
+        return result;
+    }
+    
+    
+    /**
+     * Adds a given folder as child from a specific folder
+     */
+    private TreeNodeSPDX addNodeFolder(TreeNodeSPDX root, String newFolder){
+        // don't accept requests for the root node
+        if(newFolder.equals("./")){
+            return root;
+        }
+        
+        // try to locate this parent
+        TreeNodeSPDX TheOne = findTheOne(root, newFolder);
+        // if no folder/node was found, create it
+        if(TheOne == null){
+            TheOne = createTheOne(root, newFolder);
+        }
+         
+        return TheOne;
+    }
+    
+    
+    /**
+     * Create the node inside a given node as father
+     */
+    private TreeNodeSPDX createTheOne(TreeNodeSPDX root, String what){
+        // we want to break apart all the folder components
+        String path = what;
+        // we don't need the root part
+        if(path.startsWith("./")){
+            // remove it
+            path = path.substring(2);
+        }
+        
+        // break everything into little pieces
+        String[] pathPortions = path.split("/");
+        // go through each little piece
+        TreeNodeSPDX lastNode = root;
+        String lastPortion = ".";
+        for(String portion : pathPortions){
+            String thisPath = lastPortion + "/" + portion;
+            // get the node if it exists, return null if not existing
+            TreeNodeSPDX node = getNode(lastNode, thisPath);
+            // doesn't exist? Create one
+            if(node == null){
+                node = new TreeNodeSPDX(portion);
+                node.nodeType = NodeType.folder;
+                node.id = thisPath;
+                // add up this node as child
+                lastNode.add(node);
+                //System.err.println("TND23s - " + thisPath);
+            }
+            // increment our data
+            lastNode = node;
+            lastPortion = thisPath;
+        }
+        // give back the last node that was created
+        return lastNode;
+    }
+    
+    /**
+     * Does a given node contain a child with a specific ID?
+     * @return 
+     */
+    private TreeNodeSPDX getNode(TreeNodeSPDX where, String what){
+        // list all the children folders
+        Enumeration list = where.children();
+        while(list.hasMoreElements()){
+            TreeNodeSPDX child = (TreeNodeSPDX) list.nextElement();
+            // first question: Are you the one?
+            if(child.id.equals(what)){
+                // no need to continue, he is the one
+                return child;
+            }
+        }
+       return null; 
+    }
+    
+    /**
+     * Tries to find a node with a given ID from a given 
+     * node as root location
+     * @param what
+     * @return 
+     */
+    private TreeNodeSPDX findTheOne(TreeNodeSPDX where, String what){
+    // list all the children folders
+        Enumeration list = where.children();
+        while(list.hasMoreElements()){
+            TreeNodeSPDX child = (TreeNodeSPDX) list.nextElement();
+            // first question: Are you the one?
+            if(child.id.equals(what)){
+                // no need to continue, he is the one
+                return child;
+            }
+            // Is any of your children, the one?
+            TreeNodeSPDX result = findTheOne(child, what);
+            if(result != null){
+                // he is the one
+                return result;
+            }
+        }
+        return null;
+    }
+    
+    
+    /**
+     * Returns the parent path (if available)
+     */
+    private String getParentFolder(String path){
+        // we need to count the number of slashes
+        int lengthOriginal = path.length();
+        String temp = path.replace("/", "");
+        // do we have at least two slashes?
+        if(lengthOriginal > (temp.length() + 1)){
+            // get everything up to last slash
+            return path.substring(0, path.lastIndexOf("/"));
+        }
+        // we have nothing, return the root folder
+        return "./";
+    }
+    
+    
+    /**
+     * Returns the path portion from a given FileInfo object
+     * @return 
+     */
+    private String getFilePath(FileInfo fileInfo){
+        // if we have a FilePath tag available, use it as default
+        if(fileInfo.tagFilePath != null){
+            return fileInfo.tagFilePath.getValue();
+        }
+        // or else, the path is found inside the FileName tag
+        String fileName = fileInfo.tagFileName.getValue();
+        // if no path is available, just mention it as root
+        if(fileName.contains("/")==false){
+            return "./";
+        }
+        // there is a path available, let's get it
+        return fileName.substring(0, fileName.lastIndexOf("/"));
     }
     
     
@@ -100,11 +336,23 @@
             }
         }
         
+        // title of the node that we want to create
+        String title = definition.nodeReviewerSPDX;
+        
+        // do we have more than one reviewer?
+        if(spdx.creatorSection.people.size() > 1){
+            title = definition.nodeReviewersSPDX 
+                    + " ("
+                    + spdx.creatorSection.people.size()
+                    + ")";
+        }
+        
         // let's add people, this is our main node
-        TreeNodeSPDX node = swingUtils.nodeCreate("SPDX author", 
+        TreeNodeSPDX node = swingUtils.nodeCreate(
+                title, 
                 NodeType.sectionCreator, spdxNode);
         node.nodeType = NodeType.sectionCreator;
-        node.id = "SPDX author";
+        node.id = definition.nodeReviewerSPDX;
         node.setUserObject(spdx.creatorSection);
         
         // create now a node for each author
@@ -112,22 +360,19 @@
             TreeNodeSPDX nodePerson = swingUtils.addNodePerson(node, person);
             // add here the action we want to happen when clicked
             File scriptFile = new File(core.getPluginsFolder(), "/people/show.java");
-              nodePerson.scriptFile = scriptFile;
-              nodePerson.scriptFolder = scriptFile.getParentFile();
-              nodePerson.scriptMethod = "details";
-              // create the correct parameters
-              String relativePath = 
-                      spdx.file.getAbsolutePath().replace(core.getProductsFolder().getAbsolutePath(), "");
-              // add the SPDX that we want to edit/show
-              nodePerson.scriptParameters.add(new String[]{param.spdx, relativePath});
-              // add the user name that we want to edit
-              nodePerson.scriptParameters.add(new String[]{param.filter, person.getTitle()});
-        }
-        
-        // all done, time to refresh things up
-        swingUtils.setSelectedNode(spdxNode.getUID());
-        // refresh things up
-        core.studio.getTree().repaint();
+            nodePerson.scriptFile = scriptFile;
+            nodePerson.scriptFolder = scriptFile.getParentFile();
+            nodePerson.scriptMethod = "details";
+            // create the correct parameters
+            String relativePath = 
+                    spdx.file.getAbsolutePath().replace(core.getProductsFolder().getAbsolutePath(), "");
+            // add the SPDX that we want to edit/show
+            nodePerson.scriptParameters.add(new String[]{param.spdx, relativePath});
+            // add the user name that we want to edit
+            nodePerson.scriptParameters.add(new String[]{param.filter, person.getTitle()});
+        }
+        
+       
     }