Package org.sleuthkit.autopsy.directorytree

Source Code of org.sleuthkit.autopsy.directorytree.ViewContextAction

/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.directorytree;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.AbstractAction;
import javax.swing.SwingWorker;
import org.openide.nodes.AbstractNode;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.view.TreeView;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
import org.sleuthkit.autopsy.datamodel.AbstractFsContentNode;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.autopsy.datamodel.DataSourcesNode;
import org.sleuthkit.autopsy.datamodel.RootContentChildren;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentVisitor;
import org.sleuthkit.datamodel.FileSystem;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.VolumeSystem;

/**
* View the directory content associated with the given Artifact in the DataResultViewer.
*
* 1.   Expands the Directory Tree to the location of the parent Node of the
*      associated Content.
* 2.   Selects the parent Node of the associated Content in the Directory Tree,
*      which causes the parent Node's Children to be visible in the DataResultViewer.
* 3.   Waits for all the Children to be contentNode in the DataResultViewer and
*      selects the Node that represents the Content.
*/
public class ViewContextAction extends AbstractAction {

    private Content content;
    private static final Logger logger = Logger.getLogger(ViewContextAction.class.getName());

    public ViewContextAction(String title, BlackboardArtifactNode node) {
        super(title);
        this.content = node.getLookup().lookup(Content.class);

    }

    public ViewContextAction(String title, AbstractFsContentNode<? extends AbstractFile> node) {
        super(title);
        this.content = node.getLookup().lookup(Content.class);
    }

    public ViewContextAction(String title, Content content) {
        super(title);
        this.content = content;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                // create a list of Content objects starting with content's
                // Image and ends with content
                ReverseHierarchyVisitor vtor = new ReverseHierarchyVisitor();
                List<Content> hierarchy = content.accept(vtor);
                Collections.reverse(hierarchy);

                Node generated = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(hierarchy)), true);
                Children genChilds = generated.getChildren();

                final DirectoryTreeTopComponent dirTree = DirectoryTreeTopComponent.findInstance();
                TreeView dirTreeView = dirTree.getTree();
                ExplorerManager dirTreeExplorerManager = dirTree.getExplorerManager();
                Node dirTreeRootNode = dirTreeExplorerManager.getRootContext();
                Children dirChilds = dirTreeRootNode.getChildren();
                Children currentChildren = dirChilds.findChild(DataSourcesNode.NAME).getChildren();

                Node dirExplored = null;

                // Find the parent node of the content in the directory tree
                for (int i = 0; i < genChilds.getNodesCount() - 1; i++) {
                    Node currentGeneratedNode = genChilds.getNodeAt(i);
                    for (int j = 0; j < currentChildren.getNodesCount(); j++) {
                        Node currentDirectoryTreeNode = currentChildren.getNodeAt(j);
                        if (currentGeneratedNode.getDisplayName().equals(currentDirectoryTreeNode.getDisplayName())) {
                            dirExplored = currentDirectoryTreeNode;
                            dirTreeView.expandNode(dirExplored);
                            currentChildren = currentDirectoryTreeNode.getChildren();
                            break;
                        }
                    }
                }

                // Set the parent node of the content as the selection in the
                // directory tree
                try {
                    if (dirExplored != null) {
                        dirTreeView.expandNode(dirExplored);
                        dirTreeExplorerManager.setExploredContextAndSelection(dirExplored, new Node[]{dirExplored});
                    }
                } catch (PropertyVetoException ex) {
                    logger.log(Level.WARNING, "Couldn't set selected node", ex); //NON-NLS
                }

               
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        DataResultTopComponent dataResultTC = dirTree.getDirectoryListing();
                        Node currentRootNodeOfDataResultTC = dataResultTC.getRootNode();
                        Node contentNode = content.accept(new RootContentChildren.CreateSleuthkitNodeVisitor());
                        new SelectionWorker(dataResultTC, contentNode.getName(), currentRootNodeOfDataResultTC).execute();
                    }
                });
            }
        });
    }
   
    /**
     * Waits for a Node's children to be generated, regardless of whether they
     * are lazily loaded, then sets the correct selection in a specified
     * DataResultTopComponent.
     */
    private class SelectionWorker extends SwingWorker<Node[], Integer> {

        DataResultTopComponent dataResultTC;
        String nameOfNodeToSelect;
        Node originalRootNodeOfDataResultTC;
       
        SelectionWorker(DataResultTopComponent dataResult, String nameToSelect, Node originalRoot) {
            this.dataResultTC = dataResult;
            this.nameOfNodeToSelect = nameToSelect;
            this.originalRootNodeOfDataResultTC = originalRoot;
        }
       
        @Override
        protected Node[] doInBackground() throws Exception {
            // Calls to Children::getNodes(true) block until all child Nodes have
            // been created, regardless of whether they are created lazily.
            // This means that this call will return the actual child Nodes
            // and will *NEVER* return a proxy wait Node. This is done on the
            // background thread to ensure we are not hanging the ui as it could
            // be a lengthy operation.
            return originalRootNodeOfDataResultTC.getChildren().getNodes(true);
        }
       
        @Override
        protected void done() {
            Node[] nodesDisplayedInDataResultViewer;
            try {
                nodesDisplayedInDataResultViewer = get();
            } catch (InterruptedException | ExecutionException ex) {
                logger.log(Level.WARNING, "Failed to get nodes in selection worker.", ex); //NON-NLS
                return;
            }
            // catch and ignore if we were cancelled
            catch (java.util.concurrent.CancellationException ex ) {
                return;
            }
           
            // It is possible the user selected a different Node to be displayed
            // in the DataResultViewer while the child Nodes were being generated.
            // In that case, we don't want to set the selection because it the
            // nodes returned from get() won't be in the DataResultTopComponent's
            // ExplorerManager. If we did call setSelectedNodes, it would clear
            // the current selection, which is not good.
            if (dataResultTC.getRootNode().equals(originalRootNodeOfDataResultTC) == false) {
                return;
            }
           
            // Find the correct node to select from the nodes that are displayed
            // in the data result viewer and set it as the selection of the
            // DataResultTopComponent.
            for (Node node : nodesDisplayedInDataResultViewer) {
                if (nameOfNodeToSelect.equals(node.getName())) {
                    dataResultTC.requestActive();
                    dataResultTC.setSelectedNodes(new Node[]{node});
                    DirectoryTreeTopComponent.getDefault().fireViewerComplete();
                    break;
                }
            }
        }
       
    }

    /**
     * The ReverseHierarchyVisitor class is designed to return a list of Content
     * objects starting with the one the user calls 'accept' with and ending at
     * the Image object. Please NOTE that Content objects in this hierarchy of
     * type VolumeSystem and FileSystem are skipped. This seems to be necessary
     * because
     * org.sleuthkit.autopsy.datamodel.AbstractContentChildren.CreateSleuthkitNodeVisitor
     * does not support these types.
     */
    private class ReverseHierarchyVisitor extends ContentVisitor.Default<List<Content>> {

        List<Content> ret = new ArrayList<Content>();

        private List<Content> visitParentButDontAddMe(Content content) {
            Content parent = null;
            try {
                parent = content.getParent();
            } catch (TskCoreException ex) {
                logger.log(Level.WARNING, "Couldn't get parent of Content object: " + content); //NON-NLS
            }
            return parent == null ? ret : parent.accept(this);
        }

        @Override
        protected List<Content> defaultVisit(Content content) {
            ret.add(content);
            Content parent = null;
            try {
                parent = content.getParent();
            } catch (TskCoreException ex) {
                logger.log(Level.WARNING, "Couldn't get parent of Content object: " + content); //NON-NLS
            }
            return parent == null ? ret : parent.accept(this);
        }

        @Override
        public List<Content> visit(FileSystem fs) {
            return visitParentButDontAddMe(fs);
        }

        @Override
        public List<Content> visit(VolumeSystem vs) {
            return visitParentButDontAddMe(vs);
        }
    }
}
TOP

Related Classes of org.sleuthkit.autopsy.directorytree.ViewContextAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.