mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge branch 'contentnode-cleanup'
This commit is contained in:
commit
ed32b62a7f
9
.gitignore
vendored
9
.gitignore
vendored
@ -1,13 +1,6 @@
|
|||||||
/Case/build/
|
|
||||||
/CoreComponentInterfaces/build/
|
|
||||||
/DirectoryTree/build/
|
|
||||||
/CoreComponents/build/
|
|
||||||
/dist/
|
/dist/
|
||||||
/build/
|
/build/
|
||||||
/DataModel/build/
|
/*/build/
|
||||||
/MenuActions/build/
|
|
||||||
/Logging/build/
|
|
||||||
/FileSearch/build/
|
|
||||||
*/nbproject/private/*
|
*/nbproject/private/*
|
||||||
/nbproject/private/*
|
/nbproject/private/*
|
||||||
/DataModel/release/modules/lib/libewf.dll
|
/DataModel/release/modules/lib/libewf.dll
|
||||||
|
@ -60,7 +60,6 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
|
|||||||
if (c instanceof JComponent) { // assume Swing components
|
if (c instanceof JComponent) { // assume Swing components
|
||||||
JComponent jc = (JComponent) c;
|
JComponent jc = (JComponent) c;
|
||||||
// Sets step number of a component
|
// Sets step number of a component
|
||||||
// TODO if using org.openide.dialogs >= 7.8, can use WizardDescriptor.PROP_*:
|
|
||||||
jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
|
jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
|
||||||
// Sets steps names for a panel
|
// Sets steps names for a panel
|
||||||
jc.putClientProperty("WizardPanel_contentData", steps);
|
jc.putClientProperty("WizardPanel_contentData", steps);
|
||||||
|
@ -54,7 +54,7 @@ import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
|
|||||||
*/
|
*/
|
||||||
public class Case {
|
public class Case {
|
||||||
// change the CTL_MainWindow_Title in Bundle.properties as well if you change this value
|
// change the CTL_MainWindow_Title in Bundle.properties as well if you change this value
|
||||||
private static final String autopsyVer = "3.0.0b2"; // current version of autopsy. Changed it when the version is changed
|
private static final String autopsyVer = "3.0.0b2"; // current version of autopsy. Change it when the version is changed
|
||||||
private static final String appName = "Autopsy " + autopsyVer;
|
private static final String appName = "Autopsy " + autopsyVer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,8 +150,7 @@ public class Case {
|
|||||||
currentCase = newCase;
|
currentCase = newCase;
|
||||||
|
|
||||||
pcs.firePropertyChange(CASE_CURRENT_CASE, null, currentCase);
|
pcs.firePropertyChange(CASE_CURRENT_CASE, null, currentCase);
|
||||||
//TODO: This will fire off a bunch of stuff in CaseListener.propertyChange()
|
// TODO: This will fire off a bunch of stuff in CaseListener.propertyChange() that should probably be migrated into here
|
||||||
// that should probably be migrated into here
|
|
||||||
|
|
||||||
pcs.firePropertyChange(CASE_NAME, "", currentCase.name);
|
pcs.firePropertyChange(CASE_NAME, "", currentCase.name);
|
||||||
RecentCases.getInstance().addRecentCase(currentCase.name, currentCase.configFilePath); // update the recent cases
|
RecentCases.getInstance().addRecentCase(currentCase.name, currentCase.configFilePath); // update the recent cases
|
||||||
|
@ -37,6 +37,7 @@ import org.sleuthkit.autopsy.logging.Log;
|
|||||||
*/
|
*/
|
||||||
@ServiceProvider(service = CaseOpenAction.class)
|
@ServiceProvider(service = CaseOpenAction.class)
|
||||||
public final class CaseOpenAction implements ActionListener {
|
public final class CaseOpenAction implements ActionListener {
|
||||||
|
private static final Logger logger = Logger.getLogger(CaseOpenAction.class.getName());
|
||||||
|
|
||||||
JFileChooser fc = new JFileChooser();
|
JFileChooser fc = new JFileChooser();
|
||||||
GeneralFilter autFilter = new GeneralFilter(new String[]{".aut"}, "AUTOPSY File (*.aut)", false);
|
GeneralFilter autFilter = new GeneralFilter(new String[]{".aut"}, "AUTOPSY File (*.aut)", false);
|
||||||
@ -73,7 +74,7 @@ public final class CaseOpenAction implements ActionListener {
|
|||||||
StartupWindow.getInstance().close();
|
StartupWindow.getInstance().close();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
// no need to show the error message to the user.
|
// no need to show the error message to the user.
|
||||||
// TODO: But maybe put the error message in the log in the future.
|
logger.log(Level.INFO, "Error closing startup window.", ex);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Case.open(path); // open the case
|
Case.open(path); // open the case
|
||||||
|
@ -119,7 +119,6 @@ public final class NewCaseWizardAction extends CallableSystemAction {
|
|||||||
if (c instanceof JComponent) { // assume Swing components
|
if (c instanceof JComponent) { // assume Swing components
|
||||||
JComponent jc = (JComponent) c;
|
JComponent jc = (JComponent) c;
|
||||||
// Sets step number of a component
|
// Sets step number of a component
|
||||||
// TODO if using org.openide.dialogs >= 7.8, can use WizardDescriptor.PROP_*:
|
|
||||||
jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
|
jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
|
||||||
// Sets steps names for a panel
|
// Sets steps names for a panel
|
||||||
jc.putClientProperty("WizardPanel_contentData", steps);
|
jc.putClientProperty("WizardPanel_contentData", steps);
|
||||||
|
@ -191,7 +191,6 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||||
// TODO add your handling code here:
|
|
||||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
import org.openide.windows.TopComponent;
|
import org.openide.windows.TopComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +34,7 @@ public interface DataContent extends PropertyChangeListener {
|
|||||||
* Sets the "selected" node in this class
|
* Sets the "selected" node in this class
|
||||||
* @param selectedNode node to use
|
* @param selectedNode node to use
|
||||||
*/
|
*/
|
||||||
public void setNode(ContentNode selectedNode);
|
public void setNode(Node selectedNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the TopComponent that is used when displaying this DataContent
|
* Get the TopComponent that is used when displaying this DataContent
|
||||||
|
@ -19,19 +19,19 @@
|
|||||||
|
|
||||||
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for a tab in the {@link DataContent} component. Displays the
|
* Responsible for a tab in the {@link DataContent} component. Displays the
|
||||||
* contents of the node passed to {@link setNode(ContentNode)}.
|
* contents of the node passed to {@link setNode(Node)}.
|
||||||
*/
|
*/
|
||||||
public interface DataContentViewer {
|
public interface DataContentViewer {
|
||||||
/**
|
/**
|
||||||
* Sets the node to display in the viewer. When called with null, must
|
* Sets the node to display in the viewer. When called with null, must
|
||||||
* clear all references to previous nodes.
|
* clear all references to previous nodes.
|
||||||
*/
|
*/
|
||||||
public void setNode(ContentNode selectedNode);
|
public void setNode(Node selectedNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the title of this viewer.
|
* Returns the title of this viewer.
|
||||||
@ -43,8 +43,7 @@ public interface DataContentViewer {
|
|||||||
* instance returned by the Lookup as a factory for the instances that
|
* instance returned by the Lookup as a factory for the instances that
|
||||||
* are actually used.)
|
* are actually used.)
|
||||||
*/
|
*/
|
||||||
// TODO: extract the factory method out into a seperate interface that
|
// TODO: extract the factory method out into a seperate interface that is used for the Lookup.
|
||||||
// is used for the Lookup.
|
|
||||||
public DataContentViewer getInstance();
|
public DataContentViewer getInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,6 +61,6 @@ public interface DataContentViewer {
|
|||||||
* @param node Node to check for support
|
* @param node Node to check for support
|
||||||
* @return True if supported, else false
|
* @return True if supported, else false
|
||||||
*/
|
*/
|
||||||
public boolean isSupported(ContentNode node);
|
public boolean isSupported(Node node);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
import org.openide.nodes.Node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface for the "top right component" window.
|
* The interface for the "top right component" window.
|
||||||
@ -30,7 +30,7 @@ public interface DataResult {
|
|||||||
/**
|
/**
|
||||||
* Sets the "selected" node in this class.
|
* Sets the "selected" node in this class.
|
||||||
*/
|
*/
|
||||||
public void setNode(ContentNode selectedNode);
|
public void setNode(Node selectedNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the unique TopComponent ID of this class.
|
* Gets the unique TopComponent ID of this class.
|
||||||
@ -46,6 +46,13 @@ public interface DataResult {
|
|||||||
*/
|
*/
|
||||||
public void setTitle(String title);
|
public void setTitle(String title);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the descriptive context text at the top of the pane.
|
||||||
|
* @param pathText Descriptive text giving context for the current results
|
||||||
|
*/
|
||||||
|
public void setPath(String pathText);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this is the main (uncloseable) instance of DataResult
|
* Checks if this is the main (uncloseable) instance of DataResult
|
||||||
*
|
*
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
package org.sleuthkit.autopsy.corecomponentinterfaces;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for the different viewers that show a set of nodes in the DataResult area.
|
* Interface for the different viewers that show a set of nodes in the DataResult area.
|
||||||
@ -34,7 +34,7 @@ public interface DataResultViewer {
|
|||||||
* Set the root node to display in this viewer. When called with null, must
|
* Set the root node to display in this viewer. When called with null, must
|
||||||
* clear all references to previous nodes.
|
* clear all references to previous nodes.
|
||||||
*/
|
*/
|
||||||
public void setNode(ContentNode selectedNode);
|
public void setNode(Node selectedNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the title of this viewer
|
* Gets the title of this viewer
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obt ain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
@ -28,15 +28,16 @@ import org.openide.nodes.Node;
|
|||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds commonalities between all DataResultViewers
|
* Holds commonalities between all DataResultViewers
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractDataResultViewer extends JPanel implements DataResultViewer, Provider, PropertyChangeListener {
|
public abstract class AbstractDataResultViewer extends JPanel implements
|
||||||
|
DataResultViewer, Provider, PropertyChangeListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Propagates changes in the current select node from the DataResultViewer to the DataContentTopComponent
|
* Propagates changes in the current select node from the DataResultViewer
|
||||||
|
* to the DataContentTopComponent
|
||||||
*
|
*
|
||||||
* @param evt
|
* @param evt
|
||||||
*/
|
*/
|
||||||
@ -53,14 +54,14 @@ public abstract class AbstractDataResultViewer extends JPanel implements DataRes
|
|||||||
// change the cursor to "waiting cursor" for this operation
|
// change the cursor to "waiting cursor" for this operation
|
||||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
try {
|
try {
|
||||||
Node originalSelectedNode = this.getOriginalSelectedNode();
|
Node selectedNode = this.getSelectedNode();
|
||||||
|
|
||||||
// DataContent is designed to return only the default viewer
|
// DataContent is designed to return only the default viewer
|
||||||
DataContent dataContent = Lookup.getDefault().lookup(DataContent.class);
|
DataContent dataContent = Lookup.getDefault().lookup(DataContent.class);
|
||||||
|
|
||||||
if (originalSelectedNode != null && originalSelectedNode instanceof ContentNode) {
|
if (selectedNode != null) {
|
||||||
// there's a new/changed node to display
|
// there's a new/changed node to display
|
||||||
ContentNode newSelectedNode = (ContentNode) originalSelectedNode; // get the selected Node on the table
|
Node newSelectedNode = selectedNode; // get the selected Node on the table
|
||||||
// push the node to default "DataContent"
|
// push the node to default "DataContent"
|
||||||
dataContent.setNode(newSelectedNode);
|
dataContent.setNode(newSelectedNode);
|
||||||
} else {
|
} else {
|
||||||
@ -74,9 +75,8 @@ public abstract class AbstractDataResultViewer extends JPanel implements DataRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current node, stripping off any FilterNode that this class might
|
* Gets the current node selected node
|
||||||
* have wrapped it in.
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public abstract Node getOriginalSelectedNode();
|
public abstract Node getSelectedNode();
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,17 @@ import java.util.logging.Logger;
|
|||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.windows.TopComponent;
|
import org.openide.windows.TopComponent;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top component that organizes all of the data content viewers. Doing a lookup on this class will
|
* Top component that organizes all of the data content viewers. Doing a lookup on this class will
|
||||||
@ -45,7 +47,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
|
|||||||
|
|
||||||
// reference to the "default" TC that always stays open
|
// reference to the "default" TC that always stays open
|
||||||
private static DataContentTopComponent defaultInstance;
|
private static DataContentTopComponent defaultInstance;
|
||||||
private ContentNode currentNode;
|
private Node currentNode;
|
||||||
// set to true if this is the TC that always stays open and is the default place to display content
|
// set to true if this is the TC that always stays open and is the default place to display content
|
||||||
private boolean isDefault;
|
private boolean isDefault;
|
||||||
// Different DataContentViewers
|
// Different DataContentViewers
|
||||||
@ -78,7 +80,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
|
|||||||
this.outdated = true;
|
this.outdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNode(ContentNode selectedNode) {
|
void setNode(Node selectedNode) {
|
||||||
this.wrapped.setNode(selectedNode);
|
this.wrapped.setNode(selectedNode);
|
||||||
this.outdated = false;
|
this.outdated = false;
|
||||||
}
|
}
|
||||||
@ -92,7 +94,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
|
|||||||
return this.outdated;
|
return this.outdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isSupported(ContentNode node) {
|
boolean isSupported(Node node) {
|
||||||
return this.wrapped.isSupported(node);
|
return this.wrapped.isSupported(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,7 +106,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
|
|||||||
* @param givenNode node to view content of
|
* @param givenNode node to view content of
|
||||||
* @return newly undocked instance
|
* @return newly undocked instance
|
||||||
*/
|
*/
|
||||||
public static DataContentTopComponent createUndocked(String filePath, ContentNode givenNode) {
|
public static DataContentTopComponent createUndocked(String filePath, Node givenNode) {
|
||||||
|
|
||||||
DataContentTopComponent dctc = new DataContentTopComponent(false, filePath);
|
DataContentTopComponent dctc = new DataContentTopComponent(false, filePath);
|
||||||
dctc.componentOpened();
|
dctc.componentOpened();
|
||||||
@ -219,16 +221,24 @@ public final class DataContentTopComponent extends TopComponent implements DataC
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNode(ContentNode selectedNode) {
|
public void setNode(Node selectedNode) {
|
||||||
// change the cursor to "waiting cursor" for this operation
|
// change the cursor to "waiting cursor" for this operation
|
||||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
String defaultName = NbBundle.getMessage(DataContentTopComponent.class, "CTL_DataContentTopComponent");
|
||||||
// set the file path
|
// set the file path
|
||||||
if (selectedNode == null) {
|
if (selectedNode == null) {
|
||||||
setName(NbBundle.getMessage(DataContentTopComponent.class, "CTL_DataContentTopComponent"));
|
setName(defaultName);
|
||||||
} else {
|
} else {
|
||||||
String path = DataConversion.getformattedPath(selectedNode.getDisplayPath(), 0);
|
Content content = selectedNode.getLookup().lookup(Content.class);
|
||||||
|
if (content != null) {
|
||||||
|
String path = DataConversion.getformattedPath(ContentUtils.getDisplayPath(selectedNode.getLookup().lookup(Content.class)), 0);
|
||||||
setName(path);
|
setName(path);
|
||||||
|
} else {
|
||||||
|
setName(defaultName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentNode = selectedNode;
|
currentNode = selectedNode;
|
||||||
@ -281,7 +291,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
|
|||||||
*
|
*
|
||||||
* @param selectedNode the selected content Node
|
* @param selectedNode the selected content Node
|
||||||
*/
|
*/
|
||||||
public void resetTabs(ContentNode selectedNode) {
|
public void resetTabs(Node selectedNode) {
|
||||||
|
|
||||||
int totalTabs = dataContentTabbedPane.getTabCount();
|
int totalTabs = dataContentTabbedPane.getTabCount();
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ import java.awt.Cursor;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.swing.JTextPane;
|
import javax.swing.JTextPane;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
@ -272,14 +272,18 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNode(ContentNode selectedNode) {
|
public void setNode(Node selectedNode) {
|
||||||
if (selectedNode != null) {
|
if (selectedNode != null) {
|
||||||
this.setDataView(selectedNode.getContent(), 0, false);
|
Content content = (selectedNode).getLookup().lookup(Content.class);
|
||||||
} else {
|
if (content != null) {
|
||||||
this.setDataView(null, 0, true);
|
this.setDataView(content, 0, false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setDataView(null, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return "Hex View";
|
return "Hex View";
|
||||||
@ -317,7 +321,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(ContentNode node) {
|
public boolean isSupported(Node node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ import javax.imageio.ImageIO;
|
|||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.TskException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,14 +83,16 @@ public class DataContentViewerPicture extends javax.swing.JPanel implements Data
|
|||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNode(ContentNode selectedNode) {
|
public void setNode(Node selectedNode) {
|
||||||
// change the cursor to "waiting cursor" for this operation
|
// change the cursor to "waiting cursor" for this operation
|
||||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
try {
|
try {
|
||||||
if (selectedNode != null) {
|
if (selectedNode != null) {
|
||||||
try {
|
try {
|
||||||
// read the byte of the image file
|
// read the byte of the image file
|
||||||
byte[] dataSource = selectedNode.getContent().read(0, selectedNode.getContent().getSize());
|
|
||||||
|
Content content = selectedNode.getLookup().lookup(Content.class);
|
||||||
|
byte[] dataSource = content.read(0, content.getSize());
|
||||||
|
|
||||||
// create the input stream for the content
|
// create the input stream for the content
|
||||||
InputStream is = new ByteArrayInputStream(dataSource);
|
InputStream is = new ByteArrayInputStream(dataSource);
|
||||||
@ -129,9 +131,7 @@ public class DataContentViewerPicture extends javax.swing.JPanel implements Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(ContentNode cNode) {
|
public boolean isSupported(Node node) {
|
||||||
Node node = (Node) cNode;
|
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
// Note: only supports JPG, GIF, and PNG for now
|
// Note: only supports JPG, GIF, and PNG for now
|
||||||
return node.getDisplayName().toLowerCase().endsWith(".jpg")
|
return node.getDisplayName().toLowerCase().endsWith(".jpg")
|
||||||
|
@ -22,8 +22,8 @@ import java.awt.Component;
|
|||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
@ -266,14 +266,18 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNode(ContentNode selectedNode) {
|
public void setNode(Node selectedNode) {
|
||||||
if (selectedNode != null) {
|
if (selectedNode != null) {
|
||||||
this.setDataView(selectedNode.getContent(), 0, false);
|
Content content = selectedNode.getLookup().lookup(Content.class);
|
||||||
} else {
|
if (content != null) {
|
||||||
this.setDataView(null, 0, true);
|
this.setDataView(content, 0, false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setDataView(null, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return "String View";
|
return "String View";
|
||||||
@ -296,7 +300,7 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(ContentNode node) {
|
public boolean isSupported(Node node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,21 +32,19 @@ import org.openide.windows.TopComponent;
|
|||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||||
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top component which displays something.
|
* Top component which displays something.
|
||||||
*/
|
*/
|
||||||
public final class DataResultTopComponent extends TopComponent implements DataResult, ChangeListener {
|
public final class DataResultTopComponent extends TopComponent implements DataResult, ChangeListener {
|
||||||
|
|
||||||
private ContentNode rootNode;
|
private Node rootNode;
|
||||||
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||||
private boolean isMain;
|
private boolean isMain;
|
||||||
/** path to the icon used by the component and its open action */
|
|
||||||
// static final String ICON_PATH = "SET/PATH/TO/ICON/HERE";
|
|
||||||
private static String PREFERRED_ID = "NodeTableTopComponent";
|
private static String PREFERRED_ID = "NodeTableTopComponent";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of property change fired when a file search result is closed
|
* Name of property change fired when a file search result is closed
|
||||||
*/
|
*/
|
||||||
@ -75,7 +73,7 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
|
|||||||
this.outdated = true;
|
this.outdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNode(ContentNode selectedNode) {
|
void setNode(Node selectedNode) {
|
||||||
this.wrapped.setNode(selectedNode);
|
this.wrapped.setNode(selectedNode);
|
||||||
this.outdated = false;
|
this.outdated = false;
|
||||||
}
|
}
|
||||||
@ -112,8 +110,8 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
|
|||||||
newDataResult.open(); // open it first so the component can be initialized
|
newDataResult.open(); // open it first so the component can be initialized
|
||||||
|
|
||||||
// set the tree table view
|
// set the tree table view
|
||||||
newDataResult.setNode((ContentNode) givenNode);
|
newDataResult.setNode(givenNode);
|
||||||
newDataResult.directoryTablePath.setText(pathText);
|
newDataResult.setPath(pathText);
|
||||||
|
|
||||||
return newDataResult;
|
return newDataResult;
|
||||||
}
|
}
|
||||||
@ -283,21 +281,16 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNode(ContentNode selectedNode) {
|
public void setNode(Node selectedNode) {
|
||||||
this.rootNode = selectedNode;
|
this.rootNode = selectedNode;
|
||||||
String path = "";
|
|
||||||
if (selectedNode != null) {
|
if (selectedNode != null) {
|
||||||
path = DataConversion.getformattedPath(selectedNode.getDisplayPath(), 0);
|
int childrenCount = selectedNode.getChildren().getNodesCount(true);
|
||||||
|
|
||||||
int childrenCount = ((Node) selectedNode).getChildren().getNodesCount(true);
|
|
||||||
this.numberMatchLabel.setText(Integer.toString(childrenCount));
|
this.numberMatchLabel.setText(Integer.toString(childrenCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.numberMatchLabel.setVisible(true);
|
this.numberMatchLabel.setVisible(true);
|
||||||
this.matchLabel.setVisible(true);
|
this.matchLabel.setVisible(true);
|
||||||
|
|
||||||
this.directoryTablePath.setText(path); // set the node path
|
|
||||||
|
|
||||||
resetTabs(selectedNode);
|
resetTabs(selectedNode);
|
||||||
|
|
||||||
// set the display on the current active tab
|
// set the display on the current active tab
|
||||||
@ -313,6 +306,11 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
|
|||||||
setName(title);
|
setName(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPath(String pathText) {
|
||||||
|
this.directoryTablePath.setText(pathText);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMain() {
|
public boolean isMain() {
|
||||||
return this.isMain;
|
return this.isMain;
|
||||||
@ -349,7 +347,7 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
|
|||||||
*
|
*
|
||||||
* @param selectedNode the selected content Node
|
* @param selectedNode the selected content Node
|
||||||
*/
|
*/
|
||||||
public void resetTabs(ContentNode selectedNode) {
|
public void resetTabs(Node selectedNode) {
|
||||||
|
|
||||||
for (UpdateWrapper drv : this.viewers) {
|
for (UpdateWrapper drv : this.viewers) {
|
||||||
drv.resetComponent();
|
drv.resetComponent();
|
||||||
|
@ -22,7 +22,7 @@ import java.awt.Component;
|
|||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -33,13 +33,11 @@ import org.openide.explorer.view.OutlineView;
|
|||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.nodes.Node.Property;
|
||||||
import org.openide.nodes.Node.PropertySet;
|
import org.openide.nodes.Node.PropertySet;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||||
// TODO We should not have anything specific to Image in here...
|
|
||||||
import org.sleuthkit.datamodel.Image;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DataResult sortable table viewer
|
* DataResult sortable table viewer
|
||||||
@ -49,7 +47,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
|
|
||||||
private transient ExplorerManager em = new ExplorerManager();
|
private transient ExplorerManager em = new ExplorerManager();
|
||||||
private String firstColumnLabel = "Name";
|
private String firstColumnLabel = "Name";
|
||||||
private boolean isImageNode;
|
|
||||||
|
|
||||||
/** Creates new form DataResultViewerTable */
|
/** Creates new form DataResultViewerTable */
|
||||||
public DataResultViewerTable() {
|
public DataResultViewerTable() {
|
||||||
@ -63,7 +60,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
// don't show the root node
|
// don't show the root node
|
||||||
ov.getOutline().setRootVisible(false);
|
ov.getOutline().setRootVisible(false);
|
||||||
|
|
||||||
this.isImageNode = false;
|
|
||||||
this.em.addPropertyChangeListener(this);
|
this.em.addPropertyChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,13 +94,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
private void tableScrollPanelComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_tableScrollPanelComponentResized
|
private void tableScrollPanelComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_tableScrollPanelComponentResized
|
||||||
if (this.tableScrollPanel.getWidth() < 700 && isImageNode) {
|
|
||||||
((OutlineView) this.tableScrollPanel).getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
|
||||||
} else {
|
|
||||||
if (isImageNode) {
|
|
||||||
((OutlineView) this.tableScrollPanel).getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}//GEN-LAST:event_tableScrollPanelComponentResized
|
}//GEN-LAST:event_tableScrollPanelComponentResized
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JScrollPane tableScrollPanel;
|
private javax.swing.JScrollPane tableScrollPanel;
|
||||||
@ -116,14 +105,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node getOriginalSelectedNode() {
|
public Node getSelectedNode() {
|
||||||
Node result = null;
|
Node result = null;
|
||||||
Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
|
Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
|
||||||
if (selectedNodes.length > 0) {
|
if (selectedNodes.length > 0) {
|
||||||
result = selectedNodes[0];
|
result = selectedNodes[0];
|
||||||
if (result != null && result instanceof TableFilterNode) {
|
|
||||||
result = ((TableFilterNode) result).getOriginal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -150,7 +136,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNode(ContentNode selectedNode) {
|
public void setNode(Node selectedNode) {
|
||||||
// change the cursor to "waiting cursor" for this operation
|
// change the cursor to "waiting cursor" for this operation
|
||||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
try {
|
try {
|
||||||
@ -158,17 +144,15 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
|
|
||||||
|
|
||||||
if (selectedNode != null) {
|
if (selectedNode != null) {
|
||||||
hasChildren = ((Node) selectedNode).getChildren().getNodesCount() > 0;
|
hasChildren = selectedNode.getChildren().getNodesCount() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if there's no selection node, do nothing
|
// if there's no selection node, do nothing
|
||||||
if (hasChildren) {
|
if (hasChildren) {
|
||||||
Node root = (Node) selectedNode;
|
Node root = selectedNode;
|
||||||
|
|
||||||
if (root instanceof TableFilterNode) {
|
if (!(root instanceof TableFilterNode)) {
|
||||||
root = ((TableFilterNode) root).getOriginal();
|
|
||||||
} else {
|
|
||||||
root = new TableFilterNode(root, true);
|
root = new TableFilterNode(root, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +160,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
|
|
||||||
OutlineView ov = ((OutlineView) this.tableScrollPanel);
|
OutlineView ov = ((OutlineView) this.tableScrollPanel);
|
||||||
|
|
||||||
List<Node.Property> tempProps = new ArrayList<Node.Property>(Arrays.asList(getChildPropertyHeaders((Node) selectedNode)));
|
List<Node.Property> tempProps = new ArrayList<Node.Property>(Arrays.asList(getChildPropertyHeaders(selectedNode)));
|
||||||
|
|
||||||
tempProps.remove(0);
|
tempProps.remove(0);
|
||||||
|
|
||||||
@ -211,8 +195,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
|
|
||||||
|
|
||||||
// show the horizontal scroll panel and show all the content & header
|
// show the horizontal scroll panel and show all the content & header
|
||||||
if (!(selectedNode.getContent() instanceof Image)) {
|
|
||||||
this.isImageNode = false;
|
|
||||||
int totalColumns = props.length;
|
int totalColumns = props.length;
|
||||||
|
|
||||||
//int scrollWidth = ttv.getWidth();
|
//int scrollWidth = ttv.getWidth();
|
||||||
@ -228,11 +211,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
|
|
||||||
// get first 100 rows values for the table
|
// get first 100 rows values for the table
|
||||||
Object[][] content = null;
|
Object[][] content = null;
|
||||||
try {
|
content = getRowValues(selectedNode, 100);
|
||||||
content = selectedNode.getRowValues(100);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
// TODO: potential exception is being ignored (see below), should be handled
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (content != null) {
|
if (content != null) {
|
||||||
@ -252,12 +231,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
// turn on the auto resize
|
// turn on the auto resize
|
||||||
ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
|
ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.isImageNode = true;
|
|
||||||
// turn on the auto resize for image result
|
|
||||||
ov.getOutline().getColumnModel().getColumn(0).setPreferredWidth(175);
|
|
||||||
ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Node emptyNode = new AbstractNode(Children.LEAF);
|
Node emptyNode = new AbstractNode(Children.LEAF);
|
||||||
em.setRootContext(emptyNode); // make empty node
|
em.setRootContext(emptyNode); // make empty node
|
||||||
@ -269,6 +243,32 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Object[][] getRowValues(Node node, int rows) {
|
||||||
|
// how many rows are we returning
|
||||||
|
int maxRows = Math.min(rows, node.getChildren().getNodesCount());
|
||||||
|
|
||||||
|
Object[][] objs = new Object[maxRows][];
|
||||||
|
|
||||||
|
for (int i = 0; i < maxRows; i++) {
|
||||||
|
PropertySet[] props = node.getChildren().getNodeAt(i).getPropertySets();
|
||||||
|
Property[] property = props[0].getProperties();
|
||||||
|
objs[i] = new Object[property.length];
|
||||||
|
|
||||||
|
|
||||||
|
for (int j = 0; j < property.length; j++) {
|
||||||
|
try {
|
||||||
|
objs[i][j] = property[j].getValue();
|
||||||
|
} catch (IllegalAccessException ignore) {
|
||||||
|
objs[i][j] = "n/a";
|
||||||
|
} catch (InvocationTargetException ignore) {
|
||||||
|
objs[i][j] = "n/a";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return "Table View";
|
return "Table View";
|
||||||
|
@ -29,7 +29,6 @@ import org.openide.nodes.AbstractNode;
|
|||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,34 +81,23 @@ public class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node getOriginalSelectedNode() {
|
public Node getSelectedNode() {
|
||||||
Node result = null;
|
Node result = null;
|
||||||
|
|
||||||
Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
|
Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
|
||||||
if (selectedNodes.length > 0) {
|
if (selectedNodes.length > 0) {
|
||||||
result = selectedNodes[0];
|
result = selectedNodes[0];
|
||||||
if (result != null && result instanceof ThumbnailViewNode) {
|
|
||||||
result = ((ThumbnailViewNode) result).getOriginal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNode(ContentNode givenNode) {
|
public void setNode(Node givenNode) {
|
||||||
// change the cursor to "waiting cursor" for this operation
|
// change the cursor to "waiting cursor" for this operation
|
||||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
try {
|
try {
|
||||||
if (givenNode != null) {
|
if (givenNode != null) {
|
||||||
Node root = (Node) givenNode;
|
Node root = new AbstractNode(new ThumbnailViewChildren(givenNode));
|
||||||
|
|
||||||
if (root instanceof ThumbnailViewNode) {
|
|
||||||
root = ((ThumbnailViewNode) root).getOriginal();
|
|
||||||
} else {
|
|
||||||
Node temp = new AbstractNode(new ThumbnailViewChildren((ContentNode) root));
|
|
||||||
root = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
em.setRootContext(root);
|
em.setRootContext(root);
|
||||||
} else {
|
} else {
|
||||||
Node emptyNode = new AbstractNode(Children.LEAF);
|
Node emptyNode = new AbstractNode(Children.LEAF);
|
||||||
|
@ -170,7 +170,7 @@ private void jLabel1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:eve
|
|||||||
} catch (MalformedURLException ex) {
|
} catch (MalformedURLException ex) {
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
url = null; // TODO add your handling code here:
|
url = null;
|
||||||
}//GEN-LAST:event_jLabel1MouseClicked
|
}//GEN-LAST:event_jLabel1MouseClicked
|
||||||
|
|
||||||
private void activateVerboseLogging(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_activateVerboseLogging
|
private void activateVerboseLogging(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_activateVerboseLogging
|
||||||
|
@ -37,11 +37,6 @@ class TableFilterNode extends FilterNode {
|
|||||||
this.createChild = crChild;
|
this.createChild = crChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node getOriginal() {
|
|
||||||
return super.getOriginal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the display name / header for the first (tree) column on the
|
* Override the display name / header for the first (tree) column on the
|
||||||
* "TreeTableView".
|
* "TreeTableView".
|
||||||
|
@ -20,31 +20,33 @@ package org.sleuthkit.autopsy.corecomponents;
|
|||||||
|
|
||||||
import org.openide.nodes.FilterNode;
|
import org.openide.nodes.FilterNode;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.ContentVisitor;
|
||||||
|
import org.sleuthkit.datamodel.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complementary class to ThumbnailViewNode
|
* Complementary class to ThumbnailViewNode
|
||||||
*/
|
*/
|
||||||
class ThumbnailViewChildren extends FilterNode.Children {
|
class ThumbnailViewChildren extends FilterNode.Children {
|
||||||
|
|
||||||
|
private static final IsSupportedContentVisitor isSupportedVisitor = new IsSupportedContentVisitor();
|
||||||
|
|
||||||
private int totalChildren;
|
private int totalChildren;
|
||||||
|
|
||||||
/** the constructor */
|
/** the constructor */
|
||||||
ThumbnailViewChildren(ContentNode arg) {
|
ThumbnailViewChildren(Node arg) {
|
||||||
super((Node) arg);
|
super(arg);
|
||||||
this.totalChildren = 1;
|
this.totalChildren = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node copyNode(Node arg0) {
|
protected Node copyNode(Node arg0) {
|
||||||
return new ThumbnailViewNode((ContentNode) arg0);
|
return new ThumbnailViewNode(arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node[] createNodes(Node arg0) {
|
protected Node[] createNodes(Node arg0) {
|
||||||
// filter out the FileNode and the "." and ".." directories
|
if (arg0 != null && isSupported(arg0)) {
|
||||||
if (arg0 != null && //(arg0 instanceof FileNode &&
|
|
||||||
isSupported(arg0)) {
|
|
||||||
totalChildren++;
|
totalChildren++;
|
||||||
return new Node[]{this.copyNode(arg0)};
|
return new Node[]{this.copyNode(arg0)};
|
||||||
} else {
|
} else {
|
||||||
@ -58,7 +60,20 @@ class ThumbnailViewChildren extends FilterNode.Children {
|
|||||||
|
|
||||||
public static boolean isSupported(Node node) {
|
public static boolean isSupported(Node node) {
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
String lowerName = node.getDisplayName().toLowerCase();
|
Content content = node.getLookup().lookup(Content.class);
|
||||||
|
if (content != null) {
|
||||||
|
return content.accept(isSupportedVisitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class IsSupportedContentVisitor extends ContentVisitor.Default<Boolean> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean visit(File f) {
|
||||||
|
String lowerName = f.getName().toLowerCase();
|
||||||
// Note: only supports JPG, GIF, and PNG for now
|
// Note: only supports JPG, GIF, and PNG for now
|
||||||
// TODO: replace giant OR with check if in list
|
// TODO: replace giant OR with check if in list
|
||||||
return lowerName.endsWith(".jpg")
|
return lowerName.endsWith(".jpg")
|
||||||
@ -71,7 +86,10 @@ class ThumbnailViewChildren extends FilterNode.Children {
|
|||||||
//node.getName().toLowerCase().endsWith(".tiff") ||
|
//node.getName().toLowerCase().endsWith(".tiff") ||
|
||||||
//node.getName().toLowerCase().endsWith(".tga") ||
|
//node.getName().toLowerCase().endsWith(".tga") ||
|
||||||
lowerName.endsWith(".png");
|
lowerName.endsWith(".png");
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean defaultVisit(Content cntnt) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ import javax.swing.ImageIcon;
|
|||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import org.openide.nodes.FilterNode;
|
import org.openide.nodes.FilterNode;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.logging.Log;
|
import org.sleuthkit.autopsy.logging.Log;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.TskException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,20 +40,13 @@ import org.sleuthkit.datamodel.TskException;
|
|||||||
*/
|
*/
|
||||||
class ThumbnailViewNode extends FilterNode {
|
class ThumbnailViewNode extends FilterNode {
|
||||||
|
|
||||||
private ContentNode currentNode;
|
|
||||||
// for error handling
|
|
||||||
private SoftReference<Image> iconCache;
|
private SoftReference<Image> iconCache;
|
||||||
private static Image defaultIcon = new ImageIcon("/org/sleuthkit/autopsy/images/file-icon.png").getImage();
|
|
||||||
|
private static final Image defaultIcon = new ImageIcon("/org/sleuthkit/autopsy/images/file-icon.png").getImage();
|
||||||
|
|
||||||
/** the constructor */
|
/** the constructor */
|
||||||
ThumbnailViewNode(ContentNode arg) {
|
ThumbnailViewNode(Node arg) {
|
||||||
super((Node) arg, Children.LEAF);
|
super(arg, Children.LEAF);
|
||||||
this.currentNode = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node getOriginal() {
|
|
||||||
return super.getOriginal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,22 +58,28 @@ class ThumbnailViewNode extends FilterNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
|
Content content = this.getLookup().lookup(Content.class);
|
||||||
|
|
||||||
|
if (content != null) {
|
||||||
try {
|
try {
|
||||||
System.out.println("generate");
|
System.out.println("generate");
|
||||||
icon = generateIcon();
|
icon = generateIcon(content);
|
||||||
iconCache = new SoftReference<Image>(icon);
|
|
||||||
} catch (TskException ex) {
|
} catch (TskException ex) {
|
||||||
icon = ThumbnailViewNode.defaultIcon;
|
icon = ThumbnailViewNode.defaultIcon;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
icon = ThumbnailViewNode.defaultIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
iconCache = new SoftReference<Image>(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image generateIcon() throws TskException {
|
static private Image generateIcon(Content content) throws TskException {
|
||||||
ContentNode temp = currentNode;
|
byte[] data = content.read(0, content.getSize());
|
||||||
byte[] content = temp.read(0, temp.getContent().getSize());
|
Image result = Toolkit.getDefaultToolkit().createImage(data);
|
||||||
Image result = Toolkit.getDefaultToolkit().createImage(content);
|
|
||||||
|
|
||||||
// scale the image
|
// scale the image
|
||||||
MediaTracker mTracker = new MediaTracker(new JFrame());
|
MediaTracker mTracker = new MediaTracker(new JFrame());
|
||||||
|
@ -20,20 +20,10 @@
|
|||||||
|
|
||||||
package org.sleuthkit.autopsy.datamodel;
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
import org.openide.util.lookup.Lookups;
|
import org.openide.util.lookup.Lookups;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.ContentVisitor;
|
|
||||||
import org.sleuthkit.datamodel.Directory;
|
|
||||||
import org.sleuthkit.datamodel.File;
|
|
||||||
import org.sleuthkit.datamodel.FileSystem;
|
|
||||||
import org.sleuthkit.datamodel.Image;
|
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.TskException;
|
||||||
import org.sleuthkit.datamodel.Volume;
|
|
||||||
import org.sleuthkit.datamodel.VolumeSystem;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface class that all Data nodes inherit from.
|
* Interface class that all Data nodes inherit from.
|
||||||
@ -53,7 +43,7 @@ abstract class AbstractContentNode<T extends Content> extends AbstractNode imple
|
|||||||
AbstractContentNode(T content) {
|
AbstractContentNode(T content) {
|
||||||
super(new ContentChildren(content), Lookups.singleton(content));
|
super(new ContentChildren(content), Lookups.singleton(content));
|
||||||
this.content = content;
|
this.content = content;
|
||||||
super.setName(content.accept(systemName));
|
super.setName(ContentUtils.getSystemName(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,26 +56,6 @@ abstract class AbstractContentNode<T extends Content> extends AbstractNode imple
|
|||||||
return super.getName();
|
return super.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the ID of this node.
|
|
||||||
*
|
|
||||||
* @return ID the ID of this node
|
|
||||||
*/
|
|
||||||
public long getID() {
|
|
||||||
return content.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the row values for this node. The main purpose of this method is to
|
|
||||||
* get the 'x' number of the row values for this node to set the width of each
|
|
||||||
* column of the DataResult Table. Row values is the children and it's properties.
|
|
||||||
*
|
|
||||||
* @param rows the number of rows we want to show
|
|
||||||
* @return rowValues the row values for this node.
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
abstract public Object[][] getRowValues(int rows) throws SQLException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the content of this node.
|
* Reads the content of this node.
|
||||||
*
|
*
|
||||||
@ -97,138 +67,4 @@ abstract class AbstractContentNode<T extends Content> extends AbstractNode imple
|
|||||||
public byte[] read(long offset, long len) throws TskException {
|
public byte[] read(long offset, long len) throws TskException {
|
||||||
return content.read(offset, len);
|
return content.read(offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the content of this node.
|
|
||||||
*
|
|
||||||
* @return content the content of this node (can be image, volume, directory, or file)
|
|
||||||
*/
|
|
||||||
public Content getContent() {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final ShortNameVisitor shortName = new ShortNameVisitor();
|
|
||||||
|
|
||||||
private static final GetPathVisitor getDisplayPath = new GetPathVisitor(shortName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns full path to this node.
|
|
||||||
*
|
|
||||||
* @return the path of this node
|
|
||||||
*/
|
|
||||||
public String[] getDisplayPath() {
|
|
||||||
return content.accept(getDisplayPath).toArray(new String[]{});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final SystemNameVisitor systemName = new SystemNameVisitor();
|
|
||||||
|
|
||||||
private static final GetPathVisitor getSystemPath = new GetPathVisitor(systemName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns full path to this node.
|
|
||||||
*
|
|
||||||
* @return the path of this node
|
|
||||||
*/
|
|
||||||
public String[] getSystemPath() {
|
|
||||||
return content.accept(getSystemPath).toArray(new String[]{});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SystemNameVisitor extends ContentVisitor.Default<String> {
|
|
||||||
SystemNameVisitor() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String defaultVisit(Content cntnt) {
|
|
||||||
return cntnt.accept(shortName) + ":" + Long.toString(cntnt.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ShortNameVisitor extends ContentVisitor.Default<String> {
|
|
||||||
ShortNameVisitor() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String defaultVisit(Content cntnt) {
|
|
||||||
throw new UnsupportedOperationException("Can't get short name for given content type:" + cntnt.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(Directory dir) {
|
|
||||||
return DirectoryNode.nameForDirectory(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(File f) {
|
|
||||||
return FileNode.nameForFile(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(Volume v) {
|
|
||||||
return VolumeNode.nameForVolume(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(Image i) {
|
|
||||||
return ImageNode.nameForImage(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GetPathVisitor implements ContentVisitor<List<String>> {
|
|
||||||
ContentVisitor<String> toString;
|
|
||||||
|
|
||||||
GetPathVisitor(ContentVisitor<String> toString) {
|
|
||||||
this.toString = toString;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> visit(Directory dir) {
|
|
||||||
List<String> path;
|
|
||||||
|
|
||||||
if (dir.isRoot()) {
|
|
||||||
path = dir.getFileSystem().accept(this);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
path = dir.getParentDirectory().accept(this);
|
|
||||||
path.add(toString.visit(dir));
|
|
||||||
} catch (TskException ex) {
|
|
||||||
throw new RuntimeException("Couldn't get directory path.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> visit(File file) {
|
|
||||||
try {
|
|
||||||
List<String> path = file.getParentDirectory().accept(this);
|
|
||||||
path.add(toString.visit(file));
|
|
||||||
return path;
|
|
||||||
} catch (TskException ex) {
|
|
||||||
throw new RuntimeException("Couldn't get file path.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> visit(FileSystem fs) {
|
|
||||||
return fs.getParent().accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> visit(Image image) {
|
|
||||||
List<String> path = new LinkedList<String>();
|
|
||||||
path.add(toString.visit(image));
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> visit(Volume volume) {
|
|
||||||
List<String> path = volume.getParent().accept(this);
|
|
||||||
path.add(toString.visit(volume));
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> visit(VolumeSystem vs) {
|
|
||||||
return vs.getParent().accept(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ abstract class AbstractFsContentNode<T extends FsContent> extends AbstractConten
|
|||||||
|
|
||||||
// Note: this order matters for the search result, changed it if the order of property headers on the "KeywordSearchNode"changed
|
// Note: this order matters for the search result, changed it if the order of property headers on the "KeywordSearchNode"changed
|
||||||
ss.put(new NodeProperty(PROPERTY_NAME, "Name", "no description", content.getName()));
|
ss.put(new NodeProperty(PROPERTY_NAME, "Name", "no description", content.getName()));
|
||||||
ss.put(new NodeProperty(PROPERTY_LOCATION, "Location", "no description", DataConversion.getformattedPath(this.getDisplayPath(), 0)));
|
ss.put(new NodeProperty(PROPERTY_LOCATION, "Location", "no description", DataConversion.getformattedPath(ContentUtils.getDisplayPath(content), 0)));
|
||||||
ss.put(new NodeProperty("Modified Time", "Modified Time", "no description", content.getMtimeAsDate()));
|
ss.put(new NodeProperty("Modified Time", "Modified Time", "no description", content.getMtimeAsDate()));
|
||||||
ss.put(new NodeProperty("Changed Time", "Changed Time", "no description", content.getCtimeAsDate()));
|
ss.put(new NodeProperty("Changed Time", "Changed Time", "no description", content.getCtimeAsDate()));
|
||||||
ss.put(new NodeProperty("Access Time", "Access Time", "no description", content.getAtimeAsDate()));
|
ss.put(new NodeProperty("Access Time", "Access Time", "no description", content.getAtimeAsDate()));
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.datamodel;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import org.openide.nodes.FilterNode;
|
|
||||||
import org.openide.nodes.Node;
|
|
||||||
import org.openide.util.Lookup;
|
|
||||||
import org.sleuthkit.datamodel.Content;
|
|
||||||
import org.sleuthkit.datamodel.TskException;
|
|
||||||
|
|
||||||
public class ContentFilterNode extends FilterNode implements ContentNode {
|
|
||||||
|
|
||||||
public ContentFilterNode(ContentNode original) {
|
|
||||||
super((Node) original);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentFilterNode(ContentNode original, Children children) {
|
|
||||||
super((Node) original, children);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentFilterNode(ContentNode original, Children children, Lookup lookup) {
|
|
||||||
super((Node) original, children, lookup);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getID() {
|
|
||||||
return ((ContentNode) super.getOriginal()).getID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[][] getRowValues(int rows) throws SQLException {
|
|
||||||
return ((ContentNode) super.getOriginal()).getRowValues(rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] read(long offset, long len) throws TskException {
|
|
||||||
return ((ContentNode) super.getOriginal()).read(offset, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Content getContent() {
|
|
||||||
return ((ContentNode) super.getOriginal()).getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getDisplayPath() {
|
|
||||||
return ((ContentNode) super.getOriginal()).getDisplayPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getSystemPath() {
|
|
||||||
return ((ContentNode) super.getOriginal()).getSystemPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T accept(ContentNodeVisitor<T> v) {
|
|
||||||
return ((ContentNode) super.getOriginal()).accept(v);
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,73 +18,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datamodel;
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import org.sleuthkit.datamodel.Content;
|
|
||||||
import org.sleuthkit.datamodel.TskException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface class that all Data nodes inherit from.
|
* Interface class that all Data nodes inherit from.
|
||||||
* Provides basic information such as ID, parent ID, etc.
|
* Provides basic information such as ID, parent ID, etc.
|
||||||
*/
|
*/
|
||||||
public interface ContentNode {
|
|
||||||
|
|
||||||
/**
|
interface ContentNode {
|
||||||
* Returns the programmatic name for this node. This is NOT the name to
|
|
||||||
* display to users, or the plain name of the Content object - use
|
|
||||||
* Node.getDisplayName() for that.
|
|
||||||
*
|
|
||||||
* @return name the programmatic name for this node
|
|
||||||
*/
|
|
||||||
public String getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the ID of this node.
|
|
||||||
*
|
|
||||||
* @return ID the ID of this node
|
|
||||||
*/
|
|
||||||
public long getID();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the row values for this node. The main purpose of this method is to
|
|
||||||
* get the 'x' number of the row values for this node to set the width of each
|
|
||||||
* column of the DataResult Table. Row values is the children and it's properties.
|
|
||||||
*
|
|
||||||
* @param rows the number of rows we want to show
|
|
||||||
* @return rowValues the row values for this node.
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
public Object[][] getRowValues(int rows) throws SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the content of this node.
|
|
||||||
*
|
|
||||||
* @param offset the starting offset
|
|
||||||
* @param len the length
|
|
||||||
* @return the bytes
|
|
||||||
* @throws TskException
|
|
||||||
*/
|
|
||||||
public byte[] read(long offset, long len) throws TskException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the content of this node.
|
|
||||||
*
|
|
||||||
* @return content the content of this node (can be image, volume, directory, or file)
|
|
||||||
*/
|
|
||||||
public Content getContent();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns full path to this node.
|
|
||||||
*
|
|
||||||
* @return the path of this node
|
|
||||||
*/
|
|
||||||
public String[] getDisplayPath();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns full path to this node.
|
|
||||||
*
|
|
||||||
* @return the path of this node
|
|
||||||
*/
|
|
||||||
public String[] getSystemPath();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor pattern support.
|
* Visitor pattern support.
|
||||||
@ -93,5 +32,5 @@ public interface ContentNode {
|
|||||||
* @param v visitor
|
* @param v visitor
|
||||||
* @return visitor return value
|
* @return visitor return value
|
||||||
*/
|
*/
|
||||||
public <T> T accept(ContentNodeVisitor<T> v);
|
<T> T accept(ContentNodeVisitor<T> v);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ package org.sleuthkit.autopsy.datamodel;
|
|||||||
* Interface for visitor pattern on ContentNodes
|
* Interface for visitor pattern on ContentNodes
|
||||||
* @param <T> visit method return type
|
* @param <T> visit method return type
|
||||||
*/
|
*/
|
||||||
public interface ContentNodeVisitor<T> {
|
interface ContentNodeVisitor<T> {
|
||||||
|
|
||||||
T visit(DirectoryNode dn);
|
T visit(DirectoryNode dn);
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ public interface ContentNodeVisitor<T> {
|
|||||||
* specific visit types to not use the default behavior.
|
* specific visit types to not use the default behavior.
|
||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
static abstract public class Default<T> implements ContentNodeVisitor<T> {
|
static abstract class Default<T> implements ContentNodeVisitor<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default visit for all types
|
* Default visit for all types
|
||||||
|
323
DataModel/src/org/sleuthkit/autopsy/datamodel/ContentUtils.java
Normal file
323
DataModel/src/org/sleuthkit/autopsy/datamodel/ContentUtils.java
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
* 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.datamodel;
|
||||||
|
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.ContentVisitor;
|
||||||
|
import org.sleuthkit.datamodel.Directory;
|
||||||
|
import org.sleuthkit.datamodel.File;
|
||||||
|
import org.sleuthkit.datamodel.FileSystem;
|
||||||
|
import org.sleuthkit.datamodel.FsContent;
|
||||||
|
import org.sleuthkit.datamodel.Image;
|
||||||
|
import org.sleuthkit.datamodel.TskException;
|
||||||
|
import org.sleuthkit.datamodel.Volume;
|
||||||
|
import org.sleuthkit.datamodel.VolumeSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static class of utility methods for Content objects
|
||||||
|
*/
|
||||||
|
public final class ContentUtils {
|
||||||
|
|
||||||
|
private final static Logger logger = Logger.getLogger(ContentUtils.class.getName());
|
||||||
|
|
||||||
|
// don't instantiate
|
||||||
|
private ContentUtils() {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ShortNameVisitor shortName = new ShortNameVisitor();
|
||||||
|
|
||||||
|
private static final GetPathVisitor getDisplayPath = new GetPathVisitor(shortName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns full path to this node.
|
||||||
|
*
|
||||||
|
* @return the path of this node
|
||||||
|
*/
|
||||||
|
public static String[] getDisplayPath(Content content) {
|
||||||
|
return content.accept(getDisplayPath).toArray(new String[]{});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final SystemNameVisitor systemName = new SystemNameVisitor();
|
||||||
|
|
||||||
|
private static final GetPathVisitor getSystemPath = new GetPathVisitor(systemName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns full path to this node.
|
||||||
|
*
|
||||||
|
* @return the path of this node
|
||||||
|
*/
|
||||||
|
public static String[] getSystemPath(Content content) {
|
||||||
|
return content.accept(getSystemPath).toArray(new String[]{});
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getSystemName(Content content) {
|
||||||
|
return content.accept(systemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SystemNameVisitor extends ContentVisitor.Default<String> {
|
||||||
|
SystemNameVisitor() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String defaultVisit(Content cntnt) {
|
||||||
|
return cntnt.accept(shortName) + ":" + Long.toString(cntnt.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ShortNameVisitor extends ContentVisitor.Default<String> {
|
||||||
|
ShortNameVisitor() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String defaultVisit(Content cntnt) {
|
||||||
|
throw new UnsupportedOperationException("Can't get short name for given content type:" + cntnt.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(Directory dir) {
|
||||||
|
return DirectoryNode.nameForDirectory(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(File f) {
|
||||||
|
return FileNode.nameForFile(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(Volume v) {
|
||||||
|
return VolumeNode.nameForVolume(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(Image i) {
|
||||||
|
return ImageNode.nameForImage(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GetPathVisitor implements ContentVisitor<List<String>> {
|
||||||
|
ContentVisitor<String> toString;
|
||||||
|
|
||||||
|
GetPathVisitor(ContentVisitor<String> toString) {
|
||||||
|
this.toString = toString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> visit(Directory dir) {
|
||||||
|
List<String> path;
|
||||||
|
|
||||||
|
if (dir.isRoot()) {
|
||||||
|
path = dir.getFileSystem().accept(this);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
path = dir.getParentDirectory().accept(this);
|
||||||
|
path.add(toString.visit(dir));
|
||||||
|
} catch (TskException ex) {
|
||||||
|
throw new RuntimeException("Couldn't get directory path.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> visit(File file) {
|
||||||
|
try {
|
||||||
|
List<String> path = file.getParentDirectory().accept(this);
|
||||||
|
path.add(toString.visit(file));
|
||||||
|
return path;
|
||||||
|
} catch (TskException ex) {
|
||||||
|
throw new RuntimeException("Couldn't get file path.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> visit(FileSystem fs) {
|
||||||
|
return fs.getParent().accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> visit(Image image) {
|
||||||
|
List<String> path = new LinkedList<String>();
|
||||||
|
path.add(toString.visit(image));
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> visit(Volume volume) {
|
||||||
|
List<String> path = volume.getParent().accept(this);
|
||||||
|
path.add(toString.visit(volume));
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> visit(VolumeSystem vs) {
|
||||||
|
return vs.getParent().accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final int TO_FILE_BUFFER_SIZE = 8192;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads all the data from any content object and writes it to a file.
|
||||||
|
* @param content Any content object.
|
||||||
|
* @param outputFile Will be created if it doesn't exist, and overwritten if
|
||||||
|
* it does
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void writeToFile(Content content, java.io.File outputFile) throws IOException {
|
||||||
|
|
||||||
|
InputStream in = new ReadContentInputStream(content);
|
||||||
|
|
||||||
|
boolean append = false;
|
||||||
|
FileOutputStream out = new FileOutputStream(outputFile, append);
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] buffer = new byte[TO_FILE_BUFFER_SIZE];
|
||||||
|
int len = in.read(buffer);
|
||||||
|
while (len != -1) {
|
||||||
|
out.write(buffer, 0, len);
|
||||||
|
len = in.read(buffer);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to ignore the '.' and '..' directories
|
||||||
|
*/
|
||||||
|
public static boolean isDotDirectory(Directory dir) {
|
||||||
|
String name = dir.getName();
|
||||||
|
return name.equals(".") || name.equals("..");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts file/folder as given destination file, recursing into folders.
|
||||||
|
* Assumes there will be no collisions with existing directories/files, and
|
||||||
|
* that the directory to contain the destination file already exists.
|
||||||
|
*/
|
||||||
|
public static class ExtractFscContentVisitor extends ContentVisitor.Default<Void> {
|
||||||
|
|
||||||
|
java.io.File dest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make new extractor for a specific destination
|
||||||
|
* @param dest The file/folder visited will be extracted as this file
|
||||||
|
*/
|
||||||
|
public ExtractFscContentVisitor(java.io.File dest) {
|
||||||
|
this.dest = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method to make a new instance for given destination
|
||||||
|
* and extract given content
|
||||||
|
*/
|
||||||
|
public static void extract(Content cntnt, java.io.File dest) {
|
||||||
|
cntnt.accept(new ExtractFscContentVisitor(dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Void visit(File f) {
|
||||||
|
try {
|
||||||
|
ContentUtils.writeToFile(f, dest);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.SEVERE,
|
||||||
|
"Trouble extracting file to " + dest.getAbsolutePath(),
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(Directory dir) {
|
||||||
|
|
||||||
|
// don't extract . and .. directories
|
||||||
|
if (isDotDirectory(dir)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest.mkdir();
|
||||||
|
|
||||||
|
// member visitor to generate destination files for children
|
||||||
|
DestFileContentVisitor destFileCV = new DestFileContentVisitor();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// recurse on children
|
||||||
|
for (Content child : dir.getChildren()) {
|
||||||
|
java.io.File childFile = child.accept(destFileCV);
|
||||||
|
ExtractFscContentVisitor childVisitor =
|
||||||
|
new ExtractFscContentVisitor(childFile);
|
||||||
|
child.accept(childVisitor);
|
||||||
|
}
|
||||||
|
} catch (TskException ex) {
|
||||||
|
logger.log(Level.SEVERE,
|
||||||
|
"Trouble fetching children to extract.", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void defaultVisit(Content cntnt) {
|
||||||
|
throw new UnsupportedOperationException("Can't extract a "
|
||||||
|
+ cntnt.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper visitor to get the destination file for a child Content object
|
||||||
|
*/
|
||||||
|
private class DestFileContentVisitor extends
|
||||||
|
ContentVisitor.Default<java.io.File> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get destination file by adding File/Directory name to the path
|
||||||
|
* of parent
|
||||||
|
*/
|
||||||
|
private java.io.File getFsContentDest(FsContent fsc) {
|
||||||
|
String path = dest.getAbsolutePath() + java.io.File.separator
|
||||||
|
+ fsc.getName();
|
||||||
|
return new java.io.File(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.io.File visit(File f) {
|
||||||
|
return getFsContentDest(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.io.File visit(Directory dir) {
|
||||||
|
return getFsContentDest(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected java.io.File defaultVisit(Content cntnt) {
|
||||||
|
throw new UnsupportedOperationException("Can't get destination file for a "
|
||||||
|
+ cntnt.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -66,40 +66,6 @@ public class DirectoryNode extends AbstractFsContentNode<Directory> {
|
|||||||
return new Action[]{};
|
return new Action[]{};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[][] getRowValues(int rows) {
|
|
||||||
|
|
||||||
// how many rows are we returning
|
|
||||||
int maxRows = rows;
|
|
||||||
if (this.getChildren().getNodesCount() < maxRows) {
|
|
||||||
maxRows = this.getChildren().getNodesCount();
|
|
||||||
}
|
|
||||||
Object[][] objs = new Object[maxRows][];
|
|
||||||
|
|
||||||
for (int i = 0; i < maxRows; i++) {
|
|
||||||
PropertySet[] props = this.getChildren().getNodeAt(i).getPropertySets();
|
|
||||||
Property[] property = props[0].getProperties();
|
|
||||||
objs[i] = new Object[property.length - 1]; // - 1 because we don't want to show the location property
|
|
||||||
|
|
||||||
// name property
|
|
||||||
try {
|
|
||||||
objs[i][0] = property[0].getValue();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
objs[i][0] = "n/a";
|
|
||||||
}
|
|
||||||
|
|
||||||
// the rest of the properties(not including the location property)
|
|
||||||
for (int j = 1; j < property.length - 1; j++) {
|
|
||||||
try {
|
|
||||||
objs[i][j] = property[j + 1].getValue();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
objs[i][j] = "n/a";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return objs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T accept(ContentNodeVisitor<T> v) {
|
public <T> T accept(ContentNodeVisitor<T> v) {
|
||||||
return v.visit(this);
|
return v.visit(this);
|
||||||
|
@ -18,11 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datamodel;
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.sleuthkit.datamodel.File;
|
import org.sleuthkit.datamodel.File;
|
||||||
import org.sleuthkit.datamodel.FsContent;
|
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,31 +67,6 @@ public class FileNode extends AbstractFsContentNode<File> {
|
|||||||
return new Action[]{};
|
return new Action[]{};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[][] getRowValues(int rows) throws SQLException {
|
|
||||||
FsContent con = content;
|
|
||||||
Object[][] objs = new Object[1][16];
|
|
||||||
Arrays.fill(objs, 0, 1, new Object[]{
|
|
||||||
con.getName(),
|
|
||||||
con.getMtimeAsDate(),
|
|
||||||
con.getCtimeAsDate(),
|
|
||||||
con.getAtimeAsDate(),
|
|
||||||
con.getCrtimeAsDate(),
|
|
||||||
con.getSize(),
|
|
||||||
con.getDirFlagsAsString(),
|
|
||||||
con.getMetaFlagsAsString(),
|
|
||||||
con.getModeAsString(),
|
|
||||||
con.getUid(),
|
|
||||||
con.getGid(),
|
|
||||||
con.getMeta_addr(),
|
|
||||||
con.getAttr_type() + "-" + con.getAttr_id(),
|
|
||||||
con.getDirTypeAsString(),
|
|
||||||
con.getMetaTypeAsString(),
|
|
||||||
con.getKnown().getName()
|
|
||||||
});
|
|
||||||
return objs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T accept(ContentNodeVisitor<T> v) {
|
public <T> T accept(ContentNodeVisitor<T> v) {
|
||||||
return v.visit(this);
|
return v.visit(this);
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datamodel;
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
@ -52,33 +51,6 @@ public class ImageNode extends AbstractContentNode<Image> {
|
|||||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/hard-drive-icon.jpg");
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/hard-drive-icon.jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[][] getRowValues(int rows) throws SQLException {
|
|
||||||
// how many rows are we returning
|
|
||||||
int maxRows = rows;
|
|
||||||
if (this.getChildren().getNodesCount() < maxRows) {
|
|
||||||
maxRows = this.getChildren().getNodesCount();
|
|
||||||
}
|
|
||||||
Object[][] objs = new Object[maxRows][];
|
|
||||||
|
|
||||||
for (int i = 0; i < maxRows; i++) {
|
|
||||||
PropertySet[] props = this.getChildren().getNodeAt(i).getPropertySets();
|
|
||||||
Property[] property = props[0].getProperties();
|
|
||||||
objs[i] = new Object[property.length];
|
|
||||||
|
|
||||||
|
|
||||||
// the rest of the properties(not including the location property)
|
|
||||||
for (int j = 0; j < property.length; j++) {
|
|
||||||
try {
|
|
||||||
objs[i][j] = property[j].getValue();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
objs[i][j] = "n/a";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return objs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cookie getCookie(Class clazz) {
|
public Cookie getCookie(Class clazz) {
|
||||||
Children ch = getChildren();
|
Children ch = getChildren();
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import org.openide.nodes.AbstractNode;
|
||||||
|
import org.openide.nodes.Children;
|
||||||
|
import org.openide.nodes.Sheet;
|
||||||
|
|
||||||
|
public class KeyValueNode extends AbstractNode {
|
||||||
|
|
||||||
|
KeyValueThing thing;
|
||||||
|
|
||||||
|
public KeyValueNode(KeyValueThing thing, Children children) {
|
||||||
|
super(children);
|
||||||
|
this.setName(thing.getName());
|
||||||
|
this.thing = thing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Sheet createSheet() {
|
||||||
|
Sheet s = super.createSheet();
|
||||||
|
Sheet.Set ss = s.get(Sheet.PROPERTIES);
|
||||||
|
if (ss == null) {
|
||||||
|
ss = Sheet.createPropertiesSet();
|
||||||
|
s.put(ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
// table view drops first column of properties under assumption
|
||||||
|
// that it contains the node's name
|
||||||
|
ss.put(new NodeProperty("Name", "Name", "n/a", thing.getName()));
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : thing.getMap().entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
ss.put(new NodeProperty(key, key, "n/a", value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class KeyValueThing {
|
||||||
|
Map<String, Object> map;
|
||||||
|
int id;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param map must iterate it keys and values in a consistent order
|
||||||
|
* (use of LinkedHashMap is recommended)
|
||||||
|
* @param id an arbitrary id representing the type of the thing
|
||||||
|
*/
|
||||||
|
public KeyValueThing(String name, Map<String, Object> map, int id) {
|
||||||
|
this.name = name;
|
||||||
|
this.map = map;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getMap() {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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.datamodel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.TskException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InputStream to read bytes from a Content object's data
|
||||||
|
*/
|
||||||
|
class ReadContentInputStream extends InputStream {
|
||||||
|
|
||||||
|
private long position;
|
||||||
|
private long length;
|
||||||
|
private Content content;
|
||||||
|
|
||||||
|
ReadContentInputStream(Content content) {
|
||||||
|
this.content = content;
|
||||||
|
this.position = 0;
|
||||||
|
this.length = content.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
byte[] buff = new byte[1];
|
||||||
|
return (read(buff) != -1) ? buff[0] : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b) throws IOException {
|
||||||
|
return read(b, 0, b.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
|
||||||
|
// must return 0 for zero-length arrays
|
||||||
|
if (b.length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// will get an error from TSK if we try to read an empty file
|
||||||
|
if (this.length == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position < length) {
|
||||||
|
// data remains to be read
|
||||||
|
|
||||||
|
int lenToRead = (int) Math.min(len, length - position);
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] buff = content.read(position, lenToRead);
|
||||||
|
int lenRead = buff.length;
|
||||||
|
|
||||||
|
if (lenRead == 0) {
|
||||||
|
// TSK could not read the whole file, ending partway
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
System.arraycopy(buff, 0, b, off, lenRead);
|
||||||
|
position += lenRead;
|
||||||
|
return lenRead;
|
||||||
|
}
|
||||||
|
} catch (TskException ex) {
|
||||||
|
throw new IOException(ex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// at end of file
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datamodel;
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.sleuthkit.datamodel.Volume;
|
import org.sleuthkit.datamodel.Volume;
|
||||||
@ -56,40 +55,6 @@ public class VolumeNode extends AbstractContentNode<Volume> {
|
|||||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/vol-icon.png");
|
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/vol-icon.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[][] getRowValues(int rows) throws SQLException {
|
|
||||||
|
|
||||||
// how many rows are we returning
|
|
||||||
int maxRows = rows;
|
|
||||||
if (this.getChildren().getNodesCount() < maxRows) {
|
|
||||||
maxRows = this.getChildren().getNodesCount();
|
|
||||||
}
|
|
||||||
Object[][] objs = new Object[maxRows][];
|
|
||||||
|
|
||||||
for (int i = 0; i < maxRows; i++) {
|
|
||||||
PropertySet[] props = this.getChildren().getNodeAt(i).getPropertySets();
|
|
||||||
Property[] property = props[0].getProperties();
|
|
||||||
objs[i] = new Object[property.length - 1]; // - 1 because we don't want to show the location property
|
|
||||||
|
|
||||||
// name property
|
|
||||||
try {
|
|
||||||
objs[i][0] = property[0].getValue();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
objs[i][0] = "n/a";
|
|
||||||
}
|
|
||||||
|
|
||||||
// the rest of the properties(not including the location property)
|
|
||||||
for (int j = 1; j < property.length - 1; j++) {
|
|
||||||
try {
|
|
||||||
objs[i][j] = property[j + 1].getValue();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
objs[i][j] = "n/a";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return objs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Right click action for volume node
|
* Right click action for volume node
|
||||||
*
|
*
|
||||||
|
@ -18,11 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.directorytree;
|
package org.sleuthkit.autopsy.directorytree;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
import org.openide.util.actions.Presenter;
|
import org.openide.util.actions.Presenter;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
|
import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataContentViewerHex;
|
import org.sleuthkit.autopsy.corecomponents.DataContentViewerHex;
|
||||||
@ -37,10 +37,10 @@ import org.sleuthkit.autopsy.logging.Log;
|
|||||||
public class ChangeViewAction extends AbstractAction implements Presenter.Popup {
|
public class ChangeViewAction extends AbstractAction implements Presenter.Popup {
|
||||||
|
|
||||||
private int type; // type 1 = hex view, 2 = string view
|
private int type; // type 1 = hex view, 2 = string view
|
||||||
private ContentNode node;
|
private Node node;
|
||||||
|
|
||||||
/** the constructor */
|
/** the constructor */
|
||||||
public ChangeViewAction(String title, int viewType, ContentNode node) {
|
public ChangeViewAction(String title, int viewType, Node node) {
|
||||||
super(title);
|
super(title);
|
||||||
this.type = viewType;
|
this.type = viewType;
|
||||||
this.node = node;
|
this.node = node;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.directorytree;
|
package org.sleuthkit.autopsy.directorytree;
|
||||||
|
|
||||||
|
import org.openide.explorer.ExplorerManager;
|
||||||
import org.openide.nodes.FilterNode;
|
import org.openide.nodes.FilterNode;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
|
|
||||||
@ -29,18 +30,16 @@ import org.openide.nodes.Node;
|
|||||||
*/
|
*/
|
||||||
public class DataResultFilterChildren extends FilterNode.Children {
|
public class DataResultFilterChildren extends FilterNode.Children {
|
||||||
|
|
||||||
|
ExplorerManager sourceEm;
|
||||||
|
|
||||||
/** the constructor */
|
/** the constructor */
|
||||||
public DataResultFilterChildren(Node arg) {
|
public DataResultFilterChildren(Node arg, ExplorerManager sourceEm) {
|
||||||
super(arg);
|
super(arg);
|
||||||
|
this.sourceEm = sourceEm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node copyNode(Node arg0) {
|
protected Node copyNode(Node arg0) {
|
||||||
return new DataResultFilterNode(arg0);
|
return new DataResultFilterNode(arg0, sourceEm);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Node[] createNodes(Node arg0) {
|
|
||||||
return new Node[]{this.copyNode(arg0)};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,11 +20,9 @@ package org.sleuthkit.autopsy.directorytree;
|
|||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.beans.PropertyVetoException;
|
import java.beans.PropertyVetoException;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.sleuthkit.autopsy.datamodel.ImageNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.VolumeNode;
|
import org.sleuthkit.autopsy.datamodel.VolumeNode;
|
||||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
import org.sleuthkit.autopsy.datamodel.FileNode;
|
||||||
import org.sleuthkit.autopsy.datamodel.DirectoryNode;
|
import org.sleuthkit.autopsy.datamodel.DirectoryNode;
|
||||||
@ -32,35 +30,32 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JPanel;
|
|
||||||
import org.openide.explorer.ExplorerManager;
|
import org.openide.explorer.ExplorerManager;
|
||||||
import org.openide.nodes.FilterNode;
|
import org.openide.nodes.FilterNode;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNodeVisitor;
|
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.ContentVisitor;
|
||||||
|
import org.sleuthkit.datamodel.Directory;
|
||||||
|
import org.sleuthkit.datamodel.File;
|
||||||
|
import org.sleuthkit.datamodel.Image;
|
||||||
|
import org.sleuthkit.datamodel.Volume;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class wraps nodes as they are passed to the DataResult viewers. It
|
* This class wraps nodes as they are passed to the DataResult viewers. It
|
||||||
* defines the actions that the node should have.
|
* defines the actions that the node should have.
|
||||||
*/
|
*/
|
||||||
public class DataResultFilterNode extends FilterNode implements ContentNode {
|
public class DataResultFilterNode extends FilterNode{
|
||||||
|
|
||||||
|
private ExplorerManager sourceEm;
|
||||||
|
private final ContentVisitor<List<Action>> getActionsCV;
|
||||||
|
|
||||||
private Node currentNode;
|
|
||||||
// for error handling
|
|
||||||
private JPanel caller;
|
|
||||||
private String className = this.getClass().toString();
|
|
||||||
|
|
||||||
/** the constructor */
|
/** the constructor */
|
||||||
public DataResultFilterNode(Node arg) {
|
public DataResultFilterNode(Node arg, ExplorerManager em) {
|
||||||
super(arg, new DataResultFilterChildren(arg));
|
super(arg, new DataResultFilterChildren(arg, em));
|
||||||
this.currentNode = arg;
|
this.sourceEm = em;
|
||||||
}
|
getActionsCV = new GetActionsContentVisitor();
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node getOriginal() {
|
|
||||||
return super.getOriginal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,40 +63,59 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
* table and the output view.
|
* table and the output view.
|
||||||
*
|
*
|
||||||
* @param popup
|
* @param popup
|
||||||
* @return actionss
|
* @return actions
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Action[] getActions(boolean popup) {
|
public Action[] getActions(boolean popup) {
|
||||||
|
|
||||||
List<Action> actions = new ArrayList<Action>();
|
List<Action> actions = new ArrayList<Action>();
|
||||||
|
|
||||||
|
actions.add(new NewWindowViewAction("View in New Window", getOriginal()));
|
||||||
|
|
||||||
// right click action(s) for image node
|
Content nodeContent = this.getOriginal().getLookup().lookup(Content.class);
|
||||||
if (this.currentNode instanceof ImageNode) {
|
actions.addAll(nodeContent.accept(getActionsCV));
|
||||||
actions.add(new NewWindowViewAction("View in New Window", (ImageNode) this.currentNode));
|
|
||||||
actions.addAll(ShowDetailActionVisitor.getActions(((ImageNode) this.currentNode).getContent()));
|
|
||||||
} // right click action(s) for volume node
|
|
||||||
else if (this.currentNode instanceof VolumeNode) {
|
|
||||||
actions.add(new NewWindowViewAction("View in New Window", (VolumeNode) this.currentNode));
|
|
||||||
//new ShowDetailActionVisitor("Volume Details", this.currentNode.getName(), (VolumeNode) this.currentNode),
|
|
||||||
actions.addAll(ShowDetailActionVisitor.getActions(((VolumeNode) this.currentNode).getContent()));
|
|
||||||
actions.add(new ChangeViewAction("View", 0, (ContentNode) currentNode));
|
|
||||||
} // right click action(s) for directory node
|
|
||||||
else if (this.currentNode instanceof DirectoryNode) {
|
|
||||||
actions.add(new NewWindowViewAction("View in New Window", (DirectoryNode) this.currentNode));
|
|
||||||
actions.add(new ChangeViewAction("View", 0, (ContentNode) currentNode));
|
|
||||||
actions.add(new ExtractAction("Extract Directory", (DirectoryNode) this.currentNode));
|
|
||||||
} // right click action(s) for the file node
|
|
||||||
else if (this.currentNode instanceof FileNode) {
|
|
||||||
actions.add(new ExternalViewerAction("Open File in External Viewer", (FileNode) this.currentNode));
|
|
||||||
actions.add(new NewWindowViewAction("View in New Window", (FileNode) this.currentNode));
|
|
||||||
actions.add(new ExtractAction("Extract", (FileNode) this.currentNode));
|
|
||||||
actions.add(new ChangeViewAction("View", 0, (ContentNode) currentNode));
|
|
||||||
}
|
|
||||||
|
|
||||||
return actions.toArray(new Action[actions.size()]);
|
return actions.toArray(new Action[actions.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class GetActionsContentVisitor extends ContentVisitor.Default<List<Action>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Action> visit(Image img) {
|
||||||
|
return ShowDetailActionVisitor.getActions(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Action> visit(Volume vol) {
|
||||||
|
List<Action> actions = new ArrayList<Action>();
|
||||||
|
actions.addAll(ShowDetailActionVisitor.getActions(vol));
|
||||||
|
actions.add(new ChangeViewAction("View", 0, getOriginal()));
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Action> visit(Directory dir) {
|
||||||
|
List<Action> actions = new ArrayList<Action>();
|
||||||
|
actions.add(new ChangeViewAction("View", 0, getOriginal()));
|
||||||
|
actions.add(new ExtractAction("Extract Directory", getOriginal()));
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Action> visit(File f) {
|
||||||
|
List<Action> actions = new ArrayList<Action>();
|
||||||
|
actions.add(new ExternalViewerAction("Open in External Viewer", getOriginal()));
|
||||||
|
actions.add(new ExtractAction("Extract", getOriginal()));
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Action> defaultVisit(Content cntnt) {
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Double click action for the nodes that we want to pass to the directory
|
* Double click action for the nodes that we want to pass to the directory
|
||||||
* table and the output view.
|
* table and the output view.
|
||||||
@ -111,11 +125,13 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
@Override
|
@Override
|
||||||
public Action getPreferredAction() {
|
public Action getPreferredAction() {
|
||||||
// double click action(s) for volume node or directory node
|
// double click action(s) for volume node or directory node
|
||||||
if (this.currentNode instanceof VolumeNode || (this.currentNode instanceof DirectoryNode && !this.currentNode.getDisplayName().equals("."))) {
|
|
||||||
|
|
||||||
if (this.currentNode instanceof DirectoryNode && this.currentNode.getDisplayName().equals("..")) {
|
final Node originalNode = this.getOriginal();
|
||||||
ExplorerManager em = DirectoryTreeTopComponent.findInstance().getExplorerManager();
|
|
||||||
Node[] selectedNode = em.getSelectedNodes();
|
if (originalNode instanceof VolumeNode || (originalNode instanceof DirectoryNode && !originalNode.getDisplayName().equals("."))) {
|
||||||
|
|
||||||
|
if (originalNode instanceof DirectoryNode && originalNode.getDisplayName().equals("..")) {
|
||||||
|
Node[] selectedNode = sourceEm.getSelectedNodes();
|
||||||
Node selectedContext = selectedNode[0];
|
Node selectedContext = selectedNode[0];
|
||||||
final Node parentNode = selectedContext.getParentNode();
|
final Node parentNode = selectedContext.getParentNode();
|
||||||
|
|
||||||
@ -124,7 +140,7 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
try {
|
try {
|
||||||
DirectoryTreeTopComponent.findInstance().getExplorerManager().setSelectedNodes(new Node[]{parentNode});
|
sourceEm.setSelectedNodes(new Node[]{parentNode});
|
||||||
} catch (PropertyVetoException ex) {
|
} catch (PropertyVetoException ex) {
|
||||||
Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
|
Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
|
||||||
logger.log(Level.WARNING, "Error: can't open the parent directory.", ex);
|
logger.log(Level.WARNING, "Error: can't open the parent directory.", ex);
|
||||||
@ -132,8 +148,7 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
ExplorerManager em = DirectoryTreeTopComponent.findInstance().getExplorerManager();
|
final Node[] parentNode = sourceEm.getSelectedNodes();
|
||||||
final Node[] parentNode = em.getSelectedNodes();
|
|
||||||
final Node parentContext = parentNode[0];
|
final Node parentContext = parentNode[0];
|
||||||
|
|
||||||
return new AbstractAction() {
|
return new AbstractAction() {
|
||||||
@ -141,12 +156,11 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
if (parentContext != null) {
|
if (parentContext != null) {
|
||||||
ExplorerManager em = DirectoryTreeTopComponent.findInstance().getExplorerManager();
|
|
||||||
for (int i = 0; i < parentContext.getChildren().getNodesCount(); i++) {
|
for (int i = 0; i < parentContext.getChildren().getNodesCount(); i++) {
|
||||||
Node selectedNode = parentContext.getChildren().getNodeAt(i);
|
Node selectedNode = parentContext.getChildren().getNodeAt(i);
|
||||||
if (selectedNode != null && selectedNode.getName().equals(currentNode.getName())) {
|
if (selectedNode != null && selectedNode.getName().equals(originalNode.getName())) {
|
||||||
try {
|
try {
|
||||||
em.setExploredContextAndSelection(selectedNode, new Node[]{selectedNode});
|
sourceEm.setExploredContextAndSelection(selectedNode, new Node[]{selectedNode});
|
||||||
} catch (PropertyVetoException ex) {
|
} catch (PropertyVetoException ex) {
|
||||||
// throw an error here
|
// throw an error here
|
||||||
Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
|
Logger logger = Logger.getLogger(DataResultFilterNode.class.getName());
|
||||||
@ -158,12 +172,7 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
} // // right click action(s) for the file node
|
|
||||||
// if(this.currentNode instanceof FileNode){
|
|
||||||
// // .. put the code here
|
|
||||||
// }
|
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,40 +198,4 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
|
|
||||||
return propertySets;
|
return propertySets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getID() {
|
|
||||||
return ((ContentNode) currentNode).getID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[][] getRowValues(int rows) throws SQLException {
|
|
||||||
return ((ContentNode) currentNode).getRowValues(rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] read(long offset, long len) throws TskException {
|
|
||||||
return ((ContentNode) currentNode).read(offset, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Content getContent() {
|
|
||||||
return ((ContentNode) currentNode).getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getDisplayPath() {
|
|
||||||
return ((ContentNode) currentNode).getDisplayPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T accept(ContentNodeVisitor<T> v) {
|
|
||||||
// TODO: Figure out how visitors should be delegated
|
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getSystemPath() {
|
|
||||||
return ((ContentNode) currentNode).getSystemPath();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -46,11 +46,14 @@ class DirectoryTreeFilterChildren extends FilterNode.Children {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Node[] createNodes(Node arg0) {
|
protected Node[] createNodes(Node arg0) {
|
||||||
|
|
||||||
|
//TODO: ContentNode fix - replace with ContentVisitor
|
||||||
|
|
||||||
// filter out the FileNode and the "." and ".." directories
|
// filter out the FileNode and the "." and ".." directories
|
||||||
if (arg0 != null && (arg0 instanceof ImageNode
|
if (arg0 != null && (arg0 instanceof ImageNode
|
||||||
|| arg0 instanceof VolumeNode || (arg0 instanceof DirectoryNode
|
|| arg0 instanceof VolumeNode || (arg0 instanceof DirectoryNode
|
||||||
&& !((Directory) ((DirectoryNode) arg0).getContent()).getName().equals(".")
|
&& !((DirectoryNode) arg0).getDisplayName().equals("."))
|
||||||
&& !((Directory) ((DirectoryNode) arg0).getContent()).getName().equals("..")))) {
|
&& !((DirectoryNode) arg0).getDisplayName().equals(".."))) {
|
||||||
return new Node[]{this.copyNode(arg0)};
|
return new Node[]{this.copyNode(arg0)};
|
||||||
} else {
|
} else {
|
||||||
return new Node[]{};
|
return new Node[]{};
|
||||||
|
@ -23,29 +23,24 @@ import java.util.List;
|
|||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.openide.nodes.FilterNode;
|
import org.openide.nodes.FilterNode;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.openide.util.lookup.Lookups;
|
||||||
|
import org.openide.util.lookup.ProxyLookup;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
|
||||||
import org.sleuthkit.datamodel.Volume;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class sets the actions for the nodes in the directory tree and creates
|
* This class sets the actions for the nodes in the directory tree and creates
|
||||||
* the children filter so that files and such are hidden from the tree.
|
* the children filter so that files and such are hidden from the tree.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DirectoryTreeFilterNode extends FilterNode {
|
class DirectoryTreeFilterNode extends FilterNode {
|
||||||
|
|
||||||
private static final Action collapseAll = new CollapseAction("Collapse All");
|
private static final Action collapseAll = new CollapseAction("Collapse All");
|
||||||
|
|
||||||
/** the constructor */
|
/** the constructor */
|
||||||
public DirectoryTreeFilterNode(Node arg) {
|
DirectoryTreeFilterNode(Node arg) {
|
||||||
super(arg, DirectoryTreeFilterChildren.createInstance(arg));
|
super(arg, DirectoryTreeFilterChildren.createInstance(arg),
|
||||||
}
|
new ProxyLookup(Lookups.singleton(new OriginalNode(arg)),
|
||||||
|
arg.getLookup()));
|
||||||
// TODO This seems bad. We should have this return the real original and modify code somewhere else to wrap it
|
|
||||||
@Override
|
|
||||||
public Node getOriginal() {
|
|
||||||
return new DataResultFilterNode(super.getOriginal());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +53,7 @@ public class DirectoryTreeFilterNode extends FilterNode {
|
|||||||
public Action[] getActions(boolean popup) {
|
public Action[] getActions(boolean popup) {
|
||||||
List<Action> actions = new ArrayList<Action>();
|
List<Action> actions = new ArrayList<Action>();
|
||||||
|
|
||||||
Content content = super.getOriginal().getLookup().lookup(Content.class);
|
Content content = this.getLookup().lookup(Content.class);
|
||||||
if (content != null) {
|
if (content != null) {
|
||||||
actions.addAll(DirectoryTreeFilterNode.getActions(content));
|
actions.addAll(DirectoryTreeFilterNode.getActions(content));
|
||||||
actions.add(collapseAll);
|
actions.add(collapseAll);
|
||||||
@ -74,4 +69,17 @@ public class DirectoryTreeFilterNode extends FilterNode {
|
|||||||
|
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class OriginalNode {
|
||||||
|
|
||||||
|
private Node original;
|
||||||
|
|
||||||
|
private OriginalNode(Node original) {
|
||||||
|
this.original = original;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node getNode() {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,11 @@ import org.openide.nodes.AbstractNode;
|
|||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
||||||
import org.sleuthkit.autopsy.datamodel.RootContentChildren;
|
import org.sleuthkit.autopsy.datamodel.RootContentChildren;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top component which displays something.
|
* Top component which displays something.
|
||||||
@ -332,23 +334,9 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/*try {
|
|
||||||
root = new DirectoryTreeFilterNode(root);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
JOptionPane.showMessageDialog(caller, "Error: problem making directory filter node.\n \nDetail: \n" + ex.getMessage() + " (at " + className + ").", "Error", JOptionPane.ERROR_MESSAGE);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
// TODO It seems that we can get rid of the first condition. root is an abstract node
|
|
||||||
if (root instanceof DirectoryTreeFilterNode) {
|
|
||||||
root = ((DirectoryTreeFilterNode) root).getOriginal();
|
|
||||||
} else {
|
|
||||||
// try {
|
|
||||||
root = new DirectoryTreeFilterNode(root);
|
root = new DirectoryTreeFilterNode(root);
|
||||||
// } catch (SQLException ex) {
|
|
||||||
// JOptionPane.showMessageDialog(caller, "Error: problem making directory filter node.\n \nDetail: \n" + ex.getMessage() + " (at " + className + ").", "Error", JOptionPane.ERROR_MESSAGE);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
em.setRootContext(root);
|
em.setRootContext(root);
|
||||||
em.getRootContext().setName(currentCase.getName());
|
em.getRootContext().setName(currentCase.getName());
|
||||||
@ -460,16 +448,12 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
|||||||
*
|
*
|
||||||
* @return node the original selected Node
|
* @return node the original selected Node
|
||||||
*/
|
*/
|
||||||
// TODO Rename or get rid of it entirely.
|
public Node getSelectedNode() {
|
||||||
public Node getOriginalSelectedNode() {
|
|
||||||
Node result = null;
|
Node result = null;
|
||||||
|
|
||||||
Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
|
Node[] selectedNodes = this.getExplorerManager().getSelectedNodes();
|
||||||
if (selectedNodes.length > 0) {
|
if (selectedNodes.length > 0) {
|
||||||
result = selectedNodes[0];
|
result = selectedNodes[0];
|
||||||
if (result != null && result instanceof DirectoryTreeFilterNode) {
|
|
||||||
result = ((DirectoryTreeFilterNode) result).getOriginal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -546,8 +530,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
|||||||
// change in node selection
|
// change in node selection
|
||||||
if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)) {
|
if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)) {
|
||||||
|
|
||||||
|
// Some lock that prevents certain Node operations is set during the
|
||||||
// Some lock that prevents certian Node operations is set during the
|
|
||||||
// ExplorerManager selection-change, so we must handle changes after the
|
// ExplorerManager selection-change, so we must handle changes after the
|
||||||
// selection-change event is processed.
|
// selection-change event is processed.
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(new Runnable() {
|
||||||
@ -561,18 +544,21 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
|||||||
// make sure dataResult is open
|
// make sure dataResult is open
|
||||||
dataResult.open();
|
dataResult.open();
|
||||||
|
|
||||||
ContentNode node = (ContentNode) DirectoryTreeTopComponent.this.getOriginalSelectedNode();
|
Node treeNode = DirectoryTreeTopComponent.this.getSelectedNode();
|
||||||
if (node != null) {
|
if (treeNode != null) {
|
||||||
|
Node originNode = treeNode.getLookup().lookup(DirectoryTreeFilterNode.OriginalNode.class).getNode();
|
||||||
|
|
||||||
//pcs.firePropertyChange(DataExplorer.EXPLORER_NODE_SELECTION_CHANGED, "", node);
|
int count = originNode.getChildren().getNodesCount(true);
|
||||||
int count = ((Node) node).getChildren().getNodesCount(true);
|
|
||||||
if (count > 1000) {
|
if (count > 1000) {
|
||||||
DirectoryTreeTopComponent.this.setCursor(null);
|
DirectoryTreeTopComponent.this.setCursor(null);
|
||||||
JOptionPane.showMessageDialog(caller, "Note: The selected directory contains " + count + " child files and folders. It may take some time to display them.\n\nAlso note that in the current version of Autopsy this will also make certain functions very slow (thumbnail view in particular, should be fixed in a future version)", "Large Data", JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.showMessageDialog(caller, "Note: The selected directory contains " + count + " child files and folders. It may take some time to display them.\n\nAlso note that in the current version of Autopsy this will also make certain functions very slow (thumbnail view in particular, should be fixed in a future version)", "Large Data", JOptionPane.INFORMATION_MESSAGE);
|
||||||
DirectoryTreeTopComponent.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
DirectoryTreeTopComponent.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
}
|
}
|
||||||
DirectoryTreeTopComponent.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
DirectoryTreeTopComponent.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
DirectoryTreeTopComponent.this.dataResult.setNode(node);
|
DirectoryTreeTopComponent.this.dataResult.setNode(new DataResultFilterNode(originNode, DirectoryTreeTopComponent.this.em));
|
||||||
|
|
||||||
|
String path = DataConversion.getformattedPath(ContentUtils.getDisplayPath(originNode.getLookup().lookup(Content.class)), 0);
|
||||||
|
DirectoryTreeTopComponent.this.dataResult.setPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the directory listing to be active
|
// set the directory listing to be active
|
||||||
|
@ -21,49 +21,37 @@ package org.sleuthkit.autopsy.directorytree;
|
|||||||
import java.awt.Desktop;
|
import java.awt.Desktop;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.logging.Log;
|
import org.sleuthkit.autopsy.logging.Log;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Extracts a File object to a temporary file in the case directory, and then
|
||||||
* @author jantonius
|
* tries to open it in the user's system with the default associated
|
||||||
|
* application.
|
||||||
*/
|
*/
|
||||||
public class ExternalViewerAction extends AbstractAction {
|
public class ExternalViewerAction extends AbstractAction {
|
||||||
|
|
||||||
private byte[] content;
|
private final static Logger logger = Logger.getLogger(ExternalViewerAction.class.getName());
|
||||||
private FileNode fileNode;
|
private org.sleuthkit.datamodel.File fileObject;
|
||||||
private String fileName;
|
|
||||||
private String extension;
|
|
||||||
// for error handling
|
|
||||||
private JPanel caller;
|
|
||||||
private String className = this.getClass().toString();
|
|
||||||
|
|
||||||
/** the constructor */
|
public ExternalViewerAction(String title, Node fileNode) {
|
||||||
public ExternalViewerAction(String title, FileNode fileNode) {
|
|
||||||
super(title);
|
super(title);
|
||||||
this.fileNode = fileNode;
|
this.fileObject = fileNode.getLookup().lookup(org.sleuthkit.datamodel.File.class);
|
||||||
|
|
||||||
long size = fileNode.getContent().getSize();
|
long size = fileObject.getSize();
|
||||||
String fullFileName = ((Node)fileNode).getDisplayName();
|
String fileName = fileObject.getName();
|
||||||
if (fullFileName.contains(".") && size > 0) {
|
int extPos = fileName.lastIndexOf('.');
|
||||||
String tempFileName = fullFileName.substring(0, fullFileName.indexOf("."));
|
|
||||||
String tempExtension = fullFileName.substring(fullFileName.indexOf("."));
|
// no point opening a file if it's empty, and java doesn't know how to
|
||||||
this.fileName = tempFileName;
|
// find an application for files without an extension
|
||||||
this.extension = tempExtension;
|
if (!(size > 0) || extPos == -1) {
|
||||||
} else {
|
this.setEnabled(false);
|
||||||
this.fileName = fullFileName;
|
|
||||||
this.extension = "";
|
|
||||||
this.setEnabled(false); // fix this later (right now only extract a file with extension)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,54 +59,31 @@ public class ExternalViewerAction extends AbstractAction {
|
|||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
Log.noteAction(this.getClass());
|
Log.noteAction(this.getClass());
|
||||||
|
|
||||||
try {
|
|
||||||
// @@@ Thing to do: maybe throw confirmation first???
|
|
||||||
|
|
||||||
// the menu should be disabled if we can't read the content (for example: on zero-sized file).
|
|
||||||
// Therefore, it should never throw the TSKException.
|
|
||||||
try {
|
|
||||||
this.content = fileNode.getContent().read(0, fileNode.getContent().getSize());
|
|
||||||
} catch (TskException ex) {
|
|
||||||
Logger.getLogger(this.className).log(Level.WARNING, "Error: can't read the content of the file.", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the temp folder path of the case
|
// Get the temp folder path of the case
|
||||||
String tempPath = Case.getCurrentCase().getTempDirectory();
|
String tempPath = Case.getCurrentCase().getTempDirectory();
|
||||||
tempPath = tempPath + File.separator + this.fileName + this.extension;
|
tempPath = tempPath + File.separator + this.fileObject.getName();
|
||||||
|
|
||||||
// create the temporary file
|
// create the temporary file
|
||||||
File file = new File(tempPath);
|
File tempFile = new File(tempPath);
|
||||||
if (file.exists()) {
|
if (tempFile.exists()) {
|
||||||
file.delete();
|
tempFile.delete();
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
file.createNewFile();
|
tempFile.createNewFile();
|
||||||
|
ContentUtils.writeToFile(fileObject, tempFile);
|
||||||
// convert char to byte
|
} catch (IOException ex) {
|
||||||
byte[] dataSource = new byte[content.length];
|
// throw an error here
|
||||||
for (int i = 0; i < content.length; i++) {
|
logger.log(Level.WARNING, "Can't save to temporary file.", ex);
|
||||||
dataSource[i] = (byte) content[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
|
||||||
//fos.write(dataSource);
|
|
||||||
fos.write(dataSource);
|
|
||||||
fos.close();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Desktop.getDesktop().open(file);
|
Desktop.getDesktop().open(tempFile);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
// if can't open the file, throw the error saying: "File type not supported."
|
// if can't open the file, throw the error saying: "File type not supported."
|
||||||
JOptionPane.showMessageDialog(caller, "Error: File type not supported.\n \nDetail: \n" + ex.getMessage() + " (at " + className + ").", "Error", JOptionPane.ERROR_MESSAGE);
|
logger.log(Level.WARNING, "File type not supported.", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the file on exit
|
// delete the file on exit
|
||||||
file.deleteOnExit();
|
tempFile.deleteOnExit();
|
||||||
|
|
||||||
} catch (IOException ex) {
|
|
||||||
// throw an error here
|
|
||||||
Logger.getLogger(this.className).log(Level.WARNING, "Error: can't open the external viewer for this file.", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,201 +18,94 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.directorytree;
|
package org.sleuthkit.autopsy.directorytree;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
|
||||||
import java.io.*;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.filechooser.FileFilter;
|
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.sleuthkit.autopsy.casemodule.GeneralFilter;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor;
|
||||||
import org.sleuthkit.autopsy.datamodel.DirectoryNode;
|
|
||||||
import org.sleuthkit.autopsy.logging.Log;
|
import org.sleuthkit.autopsy.logging.Log;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.ContentVisitor;
|
||||||
|
import org.sleuthkit.datamodel.Directory;
|
||||||
|
import org.sleuthkit.datamodel.FsContent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an action class to extract and save the bytes given as a file.
|
* Exports files and folders
|
||||||
*
|
|
||||||
* @author jantonius
|
|
||||||
*/
|
*/
|
||||||
public final class ExtractAction extends AbstractAction {
|
public final class ExtractAction extends AbstractAction {
|
||||||
|
|
||||||
private JFileChooser fc = new JFileChooser();
|
private static final InitializeContentVisitor initializeCV = new InitializeContentVisitor();
|
||||||
private byte[] source;
|
private FsContent fsContent;
|
||||||
private ContentNode contentNode;
|
|
||||||
private String fileName;
|
|
||||||
private String extension;
|
|
||||||
// for error handling
|
|
||||||
private JPanel caller;
|
|
||||||
private String className = this.getClass().toString();
|
|
||||||
|
|
||||||
/** the constructor */
|
public ExtractAction(String title, Node contentNode) {
|
||||||
public ExtractAction(String title, ContentNode contentNode) {
|
|
||||||
super(title);
|
super(title);
|
||||||
|
Content tempContent = contentNode.getLookup().lookup(Content.class);
|
||||||
|
|
||||||
String fullFileName = ((Node)contentNode).getDisplayName();
|
this.fsContent = tempContent.accept(initializeCV);
|
||||||
|
this.setEnabled(fsContent != null);
|
||||||
if (fullFileName.equals(".")) {
|
|
||||||
// . folders are not associated with their children in the database,
|
|
||||||
// so get original
|
|
||||||
Node parentNode = ((Node) contentNode).getParentNode();
|
|
||||||
this.contentNode = (ContentNode) parentNode;
|
|
||||||
fullFileName = parentNode.getDisplayName();
|
|
||||||
} else {
|
|
||||||
this.contentNode = contentNode;
|
|
||||||
}
|
}
|
||||||
long size = contentNode.getContent().getSize();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks first if the the selected it file or directory. If it's a file,
|
* Returns the FsContent if it is supported, otherwise null
|
||||||
* check if the file size is bigger than 0. If it's a directory, check
|
|
||||||
* if it's not referring to the parent directory. Disables the menu otherwise.
|
|
||||||
*/
|
*/
|
||||||
if ((contentNode instanceof FileNode && size > 0) || (contentNode instanceof DirectoryNode && !fullFileName.equals(".."))) {
|
private static class InitializeContentVisitor extends ContentVisitor.Default<FsContent> {
|
||||||
if (contentNode instanceof FileNode && fullFileName.contains(".")) {
|
|
||||||
String tempFileName = fullFileName.substring(0, fullFileName.indexOf("."));
|
@Override
|
||||||
String tempExtension = fullFileName.substring(fullFileName.indexOf("."));
|
public FsContent visit(org.sleuthkit.datamodel.File f) {
|
||||||
this.fileName = tempFileName;
|
return f;
|
||||||
this.extension = tempExtension;
|
|
||||||
} else {
|
|
||||||
this.fileName = fullFileName;
|
|
||||||
this.extension = "";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.fileName = fullFileName;
|
|
||||||
this.extension = "";
|
|
||||||
this.setEnabled(false); // can't extract zero-sized file or ".." directory
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FsContent visit(Directory dir) {
|
||||||
|
return ContentUtils.isDotDirectory(dir) ? null : dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FsContent defaultVisit(Content cntnt) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts and saves the bytes into the file.
|
* Asks user to choose destination, then extracts file/directory to
|
||||||
*
|
* destination (recursing on directories)
|
||||||
* @param e the action event
|
* @param e the action event
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
Log.noteAction(this.getClass());
|
Log.noteAction(this.getClass());
|
||||||
|
|
||||||
// set the filter for FileNode
|
JFileChooser fc = new JFileChooser();
|
||||||
if (contentNode instanceof FileNode && !extension.equals("")) {
|
fc.setSelectedFile(new File(this.fsContent.getName()));
|
||||||
//FileFilter filter = new ExtensionFileFilter(extension.substring(1).toUpperCase() + " File (*" + extension + ")", new String[]{extension.substring(1)});
|
|
||||||
String[] fileExt = {extension};
|
|
||||||
FileFilter filter = new GeneralFilter(fileExt, extension.substring(1).toUpperCase() + " File (*" + extension + ")", false);
|
|
||||||
fc.setFileFilter(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fc.setSelectedFile(new File(this.fileName));
|
|
||||||
|
|
||||||
int returnValue = fc.showSaveDialog((Component) e.getSource());
|
int returnValue = fc.showSaveDialog((Component) e.getSource());
|
||||||
|
|
||||||
if (returnValue == JFileChooser.APPROVE_OPTION) {
|
if (returnValue == JFileChooser.APPROVE_OPTION) {
|
||||||
String path = fc.getSelectedFile().getPath() + extension;
|
File destination = fc.getSelectedFile();
|
||||||
|
|
||||||
try {
|
// check that it's okay to overwrite existing file
|
||||||
// file extraction
|
if (destination.exists()) {
|
||||||
if (contentNode instanceof FileNode) {
|
int choice = JOptionPane.showConfirmDialog(
|
||||||
extractFile(path, (FileNode) contentNode);
|
(Component) e.getSource(),
|
||||||
|
"Destination file already exists, it will be overwritten.",
|
||||||
|
"Destination already exists!",
|
||||||
|
JOptionPane.OK_CANCEL_OPTION);
|
||||||
|
|
||||||
|
if (choice != JOptionPane.OK_OPTION) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// directory extraction
|
if (!destination.delete()) {
|
||||||
if (contentNode instanceof DirectoryNode) {
|
JOptionPane.showMessageDialog(
|
||||||
extractDirectory(path, (DirectoryNode) contentNode);
|
(Component) e.getSource(),
|
||||||
}
|
"Couldn't delete existing file.");
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.getLogger(this.className).log(Level.WARNING, "Error: Couldn't extract file/directory.", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the content of the given fileNode into the given path.
|
|
||||||
*
|
|
||||||
* @param givenPath the path to extract the file
|
|
||||||
* @param fileNode the file node that contain the file
|
|
||||||
*/
|
|
||||||
private void extractFile(String givenPath, FileNode fileNode) throws Exception {
|
|
||||||
try {
|
|
||||||
if (fileNode.getContent().getSize() > 0) {
|
|
||||||
try {
|
|
||||||
this.source = fileNode.getContent().read(0, fileNode.getContent().getSize());
|
|
||||||
} catch (TskException ex) {
|
|
||||||
throw new Exception("Error: can't read the content of the file.", ex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.source = new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
String path = givenPath;
|
|
||||||
|
|
||||||
File file = new File(path);
|
|
||||||
if (file.exists()) {
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
file.createNewFile();
|
|
||||||
// convert char to byte
|
|
||||||
byte[] dataSource = new byte[source.length];
|
|
||||||
for (int i = 0; i < source.length; i++) {
|
|
||||||
dataSource[i] = (byte) source[i];
|
|
||||||
}
|
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
|
||||||
//fos.write(dataSource);
|
|
||||||
fos.write(dataSource);
|
|
||||||
fos.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new Exception("Error while trying to extract the file.", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
ExtractFscContentVisitor.extract(fsContent, destination);
|
||||||
* Extracts the content of the given directoryNode into the given path.
|
|
||||||
*
|
|
||||||
* @param givenPath the path to extract the directory
|
|
||||||
* @param dirNode the directory node that contain the directory
|
|
||||||
*/
|
|
||||||
private void extractDirectory(String givenPath, DirectoryNode dirNode) throws Exception {
|
|
||||||
String path = givenPath;
|
|
||||||
File dir = new File(path);
|
|
||||||
if (!dir.exists()) {
|
|
||||||
dir.mkdir();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalChildren = dirNode.getChildren().getNodesCount();
|
|
||||||
for (int i = 0; i < totalChildren; i++) {
|
|
||||||
Node childNode = dirNode.getChildren().getNodeAt(i);
|
|
||||||
|
|
||||||
if (childNode instanceof FileNode) {
|
|
||||||
FileNode fileNode = (FileNode) childNode;
|
|
||||||
String tempPath = path + File.separator + ((Node)fileNode).getDisplayName();
|
|
||||||
try {
|
|
||||||
extractFile(tempPath, fileNode);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childNode instanceof DirectoryNode) {
|
|
||||||
DirectoryNode dirNode2 = (DirectoryNode) childNode;
|
|
||||||
String dirNode2Name = ((Node)dirNode2).getDisplayName();
|
|
||||||
|
|
||||||
if (!dirNode2Name.trim().equals(".") && !dirNode2Name.trim().equals("..")) {
|
|
||||||
String tempPath = path + File.separator + dirNode2Name;
|
|
||||||
extractDirectory(tempPath, dirNode2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,21 +22,23 @@ package org.sleuthkit.autopsy.directorytree;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
import org.openide.windows.Mode;
|
import org.openide.windows.Mode;
|
||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
import org.sleuthkit.autopsy.datamodel.DataConversion;
|
||||||
import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
|
import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.logging.Log;
|
import org.sleuthkit.autopsy.logging.Log;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens new ContentViewer pane in a detached window
|
* Opens new ContentViewer pane in a detached window
|
||||||
*/
|
*/
|
||||||
class NewWindowViewAction extends AbstractAction{
|
class NewWindowViewAction extends AbstractAction{
|
||||||
|
|
||||||
private ContentNode contentNode ;
|
private Node contentNode ;
|
||||||
|
|
||||||
NewWindowViewAction(String title, ContentNode contentNode){
|
NewWindowViewAction(String title, Node contentNode){
|
||||||
super(title);
|
super(title);
|
||||||
this.contentNode = contentNode;
|
this.contentNode = contentNode;
|
||||||
}
|
}
|
||||||
@ -45,7 +47,7 @@ class NewWindowViewAction extends AbstractAction{
|
|||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
Log.noteAction(this.getClass());
|
Log.noteAction(this.getClass());
|
||||||
|
|
||||||
String[] filePaths = this.contentNode.getDisplayPath();
|
String[] filePaths = ContentUtils.getDisplayPath((contentNode).getLookup().lookup(Content.class));
|
||||||
String filePath = DataConversion.getformattedPath(filePaths, 0);
|
String filePath = DataConversion.getformattedPath(filePaths, 0);
|
||||||
|
|
||||||
DataContentTopComponent dctc = DataContentTopComponent.createUndocked(filePath, this.contentNode);
|
DataContentTopComponent dctc = DataContentTopComponent.createUndocked(filePath, this.contentNode);
|
||||||
|
@ -84,8 +84,7 @@ class ShowDetailActionVisitor extends ContentVisitor.Default<List<? extends Acti
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
// TODO: fix log action
|
Log.noteAction(ShowDetailActionVisitor.class);
|
||||||
Log.noteAction(this.getClass());
|
|
||||||
|
|
||||||
final JFrame frame = new JFrame(title);
|
final JFrame frame = new JFrame(title);
|
||||||
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
|
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
|
||||||
@ -147,8 +146,7 @@ class ShowDetailActionVisitor extends ContentVisitor.Default<List<? extends Acti
|
|||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
|
||||||
// TODO: fix log action
|
Log.noteAction(ShowDetailActionVisitor.class);
|
||||||
Log.noteAction(this.getClass());
|
|
||||||
|
|
||||||
final JFrame frame = new JFrame(title);
|
final JFrame frame = new JFrame(title);
|
||||||
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
|
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
|
||||||
@ -237,9 +235,7 @@ class ShowDetailActionVisitor extends ContentVisitor.Default<List<? extends Acti
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
Log.noteAction(ShowDetailActionVisitor.class);
|
||||||
// TODO: fix log action
|
|
||||||
Log.noteAction(this.getClass());
|
|
||||||
|
|
||||||
final JFrame frame = new JFrame(title);
|
final JFrame frame = new JFrame(title);
|
||||||
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
|
final JDialog popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
|
||||||
|
@ -18,38 +18,28 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.filesearch;
|
package org.sleuthkit.autopsy.filesearch;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNodeVisitor;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ImageNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.VolumeNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.DirectoryNode;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.openide.nodes.FilterNode;
|
import org.openide.nodes.FilterNode;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
|
||||||
import org.sleuthkit.autopsy.directorytree.ChangeViewAction;
|
import org.sleuthkit.autopsy.directorytree.ChangeViewAction;
|
||||||
|
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
|
||||||
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
import org.sleuthkit.autopsy.directorytree.ExtractAction;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.ContentVisitor;
|
||||||
|
import org.sleuthkit.datamodel.Directory;
|
||||||
|
import org.sleuthkit.datamodel.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class wraps nodes as they are passed to the DataResult viewers. It
|
* This class wraps nodes as they are passed to the DataResult viewers. It
|
||||||
* defines the actions that the node should have.
|
* defines the actions that the node should have.
|
||||||
*/
|
*/
|
||||||
public class DataResultFilterNode extends FilterNode implements ContentNode {
|
public class DataResultFilterNode extends FilterNode {
|
||||||
|
|
||||||
private Node currentNode;
|
|
||||||
|
|
||||||
/** the constructor */
|
/** the constructor */
|
||||||
public DataResultFilterNode(Node arg) {
|
public DataResultFilterNode(Node arg) {
|
||||||
super(arg, new DataResultFilterChildren(arg));
|
super(arg, new DataResultFilterChildren(arg));
|
||||||
this.currentNode = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node getOriginal() {
|
|
||||||
return super.getOriginal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,30 +51,37 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Action[] getActions(boolean popup) {
|
public Action[] getActions(boolean popup) {
|
||||||
// right click action(s) for image node
|
|
||||||
if (this.currentNode instanceof ImageNode) {
|
Content content = getOriginal().getLookup().lookup(Content.class);
|
||||||
return new Action[]{};
|
return content.accept(new GetActionContentVisitor());
|
||||||
} // right click action(s) for volume node
|
}
|
||||||
else if (this.currentNode instanceof VolumeNode) {
|
|
||||||
return new Action[]{};
|
private class GetActionContentVisitor extends ContentVisitor.Default<Action[]> {
|
||||||
} // right click action(s) for directory node
|
@Override
|
||||||
else if (this.currentNode instanceof DirectoryNode) {
|
public Action[] visit(Directory dir) {
|
||||||
return new Action[]{
|
return new Action[]{
|
||||||
new ChangeViewAction("View", 0, (ContentNode) currentNode),
|
new ChangeViewAction("View", 0, getOriginal()),
|
||||||
new OpenParentFolderAction("Open Parent Directory", ((ContentNode) currentNode).getSystemPath())
|
new OpenParentFolderAction("Open Parent Directory", ContentUtils.getSystemPath(dir))
|
||||||
};
|
};
|
||||||
} // right click action(s) for the file node
|
}
|
||||||
else if (this.currentNode instanceof FileNode) {
|
|
||||||
|
@Override
|
||||||
|
public Action[] visit(File f) {
|
||||||
return new Action[]{
|
return new Action[]{
|
||||||
new ExtractAction("Extract", (FileNode) this.currentNode),
|
new ExternalViewerAction("Open in External Viewer", getOriginal()),
|
||||||
new ChangeViewAction("View", 0, (ContentNode) currentNode),
|
new ExtractAction("Extract", getOriginal()),
|
||||||
new OpenParentFolderAction("Open Parent Directory", ((ContentNode) currentNode).getSystemPath())
|
new ChangeViewAction("View", 0, getOriginal()),
|
||||||
|
new OpenParentFolderAction("Open Parent Directory", ContentUtils.getSystemPath(f))
|
||||||
};
|
};
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Action[] defaultVisit(Content cntnt) {
|
||||||
return new Action[]{};
|
return new Action[]{};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Double click action for the nodes that we want to pass to the directory
|
* Double click action for the nodes that we want to pass to the directory
|
||||||
* table and the output view.
|
* table and the output view.
|
||||||
@ -95,40 +92,4 @@ public class DataResultFilterNode extends FilterNode implements ContentNode {
|
|||||||
public Action getPreferredAction() {
|
public Action getPreferredAction() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getID() {
|
|
||||||
return ((ContentNode) currentNode).getID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[][] getRowValues(int rows) throws SQLException {
|
|
||||||
return ((ContentNode) currentNode).getRowValues(rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] read(long offset, long len) throws TskException {
|
|
||||||
return ((ContentNode) currentNode).read(offset, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Content getContent() {
|
|
||||||
return ((ContentNode) currentNode).getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getDisplayPath() {
|
|
||||||
return ((ContentNode) currentNode).getDisplayPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T accept(ContentNodeVisitor<T> v) {
|
|
||||||
//TODO: figure out how to deal with visitors
|
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getSystemPath() {
|
|
||||||
return ((ContentNode) currentNode).getSystemPath();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,6 @@ class DateSearchPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: calendar button stuff
|
|
||||||
/** This method is called from within the constructor to
|
/** This method is called from within the constructor to
|
||||||
* initialize the form.
|
* initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is
|
* WARNING: Do NOT modify this code. The content of this method is
|
||||||
|
@ -71,8 +71,10 @@ class FilterArea extends JPanel {
|
|||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
|
|
||||||
// TODO: this icon (and its twin) should be used in the toggle button
|
|
||||||
// this.dateFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/filesearch/arrow_down.gif"))); // NOI18N
|
|
||||||
|
// Commmented-out code is for collapable filter areas
|
||||||
|
// this.dateFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/filesearch/arrow_down.gif"))); // NOI18N
|
||||||
|
|
||||||
// toggleButton = new JButton();
|
// toggleButton = new JButton();
|
||||||
// toggleButton.setAlignmentX(Component.CENTER_ALIGNMENT);
|
// toggleButton.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
@ -19,21 +19,15 @@
|
|||||||
|
|
||||||
package org.sleuthkit.autopsy.filesearch;
|
package org.sleuthkit.autopsy.filesearch;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
import org.openide.nodes.Node.Property;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNode;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentNodeVisitor;
|
|
||||||
import org.sleuthkit.datamodel.Content;
|
|
||||||
import org.sleuthkit.datamodel.FsContent;
|
import org.sleuthkit.datamodel.FsContent;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author jantonius
|
* @author jantonius
|
||||||
*/
|
*/
|
||||||
class SearchNode extends AbstractNode implements ContentNode {
|
class SearchNode extends AbstractNode {
|
||||||
|
|
||||||
private SearchChildren children;
|
private SearchChildren children;
|
||||||
|
|
||||||
@ -46,69 +40,4 @@ class SearchNode extends AbstractNode implements ContentNode {
|
|||||||
public String getName() {
|
public String getName() {
|
||||||
return "Search Result";
|
return "Search Result";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getID() {
|
|
||||||
return -1; // change this later when needed
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[][] getRowValues(int rows) throws SQLException {
|
|
||||||
int totalNodes = children.getNodesCount();
|
|
||||||
|
|
||||||
Object[][] objs;
|
|
||||||
int maxRows = 0;
|
|
||||||
if(totalNodes > rows){
|
|
||||||
objs = new Object[rows][];
|
|
||||||
maxRows = rows;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
objs = new Object[totalNodes][];
|
|
||||||
maxRows = totalNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < maxRows; i++){
|
|
||||||
PropertySet[] props = children.getNodeAt(i).getPropertySets();
|
|
||||||
Property[] property = props[0].getProperties();
|
|
||||||
objs[i] = new Object[property.length];
|
|
||||||
|
|
||||||
for(int j = 0; j < property.length; j++){
|
|
||||||
try {
|
|
||||||
objs[i][j] = property[j].getValue();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
objs[i][j] = "n/a";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return objs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] read(long offset, long len) throws TskException {
|
|
||||||
// change this in the future when needed
|
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Content getContent() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getDisplayPath() {
|
|
||||||
return new String[]{"KeyWord Search Result:"};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T accept(ContentNodeVisitor<T> v) {
|
|
||||||
//TODO: figure out how to deal with visitors
|
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getSystemPath() {
|
|
||||||
// Shouldn't be used
|
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
|||||||
import org.sleuthkit.autopsy.filesearch.FileSearchTopComponent;
|
import org.sleuthkit.autopsy.filesearch.FileSearchTopComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Menu item lists DataResult tabs.w
|
* Menu item lists DataResult tabs.
|
||||||
*/
|
*/
|
||||||
public class SearchResultMenu extends JMenuItem implements DynamicMenuContent {
|
public class SearchResultMenu extends JMenuItem implements DynamicMenuContent {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user