diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 588df9b53a..34b0dbbeba 100644 --- a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -104,7 +104,7 @@ public class DataResultFilterNode extends FilterNode{ @Override public List visit(File f) { List actions = new ArrayList(); - actions.add(new ExternalViewerAction("Open File in External Viewer", getOriginal())); + actions.add(new ExternalViewerAction("Open in External Viewer", getOriginal())); actions.add(new ExtractAction("Extract", getOriginal())); return actions; } diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExternalViewerAction.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExternalViewerAction.java index 5c7ff513f6..e3a8e1bc31 100644 --- a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExternalViewerAction.java +++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ExternalViewerAction.java @@ -21,51 +21,31 @@ package org.sleuthkit.autopsy.directorytree; import java.awt.Desktop; import java.awt.event.ActionEvent; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; -import javax.swing.JOptionPane; -import javax.swing.JPanel; import org.openide.nodes.Node; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.logging.Log; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.TskException; - -// TODO: clean up external viewer action - /** - * - * @author jantonius + * Extracts a File object to a temporary file in the case directory, and then + * tries to open it in the user's system with the default associated + * application. */ public class ExternalViewerAction extends AbstractAction { - private byte[] content; - private Content contentObject; - private String fileName; - private String extension; - // for error handling - private JPanel caller; - private String className = this.getClass().toString(); - /** the constructor */ + private final static Logger logger = Logger.getLogger(ExternalViewerAction.class.getName()); + private org.sleuthkit.datamodel.File fileObject; + public ExternalViewerAction(String title, Node fileNode) { super(title); - this.contentObject = fileNode.getLookup().lookup(Content.class); - - long size = contentObject.getSize(); - String fullFileName = fileNode.getDisplayName(); - if (fullFileName.contains(".") && size > 0) { - String tempFileName = fullFileName.substring(0, fullFileName.indexOf(".")); - String tempExtension = fullFileName.substring(fullFileName.indexOf(".")); - this.fileName = tempFileName; - this.extension = tempExtension; - } else { - this.fileName = fullFileName; - this.extension = ""; - this.setEnabled(false); //TODO: fix this later (right now only extract a file with extension) + this.fileObject = fileNode.getLookup().lookup(org.sleuthkit.datamodel.File.class); + long size = fileObject.getSize(); + if (!(size > 0)) { + this.setEnabled(false); } } @@ -73,54 +53,35 @@ public class ExternalViewerAction extends AbstractAction { public void actionPerformed(ActionEvent e) { Log.noteAction(this.getClass()); + + // 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. + + // Get the temp folder path of the case + String tempPath = Case.getCurrentCase().getTempDirectory(); + tempPath = tempPath + File.separator + this.fileObject.getName(); + + // create the temporary file + File tempFile = new File(tempPath); + if (tempFile.exists()) { + tempFile.delete(); + } 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 = contentObject.read(0, contentObject.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 - String tempPath = Case.getCurrentCase().getTempDirectory(); - tempPath = tempPath + File.separator + this.fileName + this.extension; - - // create the temporary file - File file = new File(tempPath); - if (file.exists()) { - file.delete(); - } - - file.createNewFile(); - - // convert char to byte - byte[] dataSource = new byte[content.length]; - for (int i = 0; i < content.length; i++) { - dataSource[i] = (byte) content[i]; - } - - FileOutputStream fos = new FileOutputStream(file); - //fos.write(dataSource); - fos.write(dataSource); - fos.close(); - - try { - Desktop.getDesktop().open(file); - } catch (IOException ex) { - // 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); - } - - // delete the file on exit - file.deleteOnExit(); - + tempFile.createNewFile(); + ContentUtils.writeToFile(fileObject, tempFile); } 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); + logger.log(Level.WARNING, "Can't save to temporary file.", ex); } + try { + Desktop.getDesktop().open(tempFile); + } catch (IOException ex) { + // if can't open the file, throw the error saying: "File type not supported." + logger.log(Level.WARNING, "File type not supported.", ex); + } + + // delete the file on exit + tempFile.deleteOnExit(); } } diff --git a/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterNode.java b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterNode.java index e0b5a813f4..a2fc84d708 100644 --- a/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterNode.java +++ b/FileSearch/src/org/sleuthkit/autopsy/filesearch/DataResultFilterNode.java @@ -23,6 +23,7 @@ import org.openide.nodes.FilterNode; import org.openide.nodes.Node; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.directorytree.ChangeViewAction; +import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentVisitor; @@ -67,6 +68,7 @@ public class DataResultFilterNode extends FilterNode { @Override public Action[] visit(File f) { return new Action[]{ + new ExternalViewerAction("Open in External Viewer", getOriginal()), new ExtractAction("Extract", getOriginal()), new ChangeViewAction("View", 0, getOriginal()), new OpenParentFolderAction("Open Parent Directory", ContentUtils.getSystemPath(f))