Delete report/s implemented. Misc bugs fixed

This commit is contained in:
sidheshenator 2015-06-26 14:19:06 -04:00
parent 6187bf0f8f
commit 84d7fbd735
6 changed files with 95 additions and 4 deletions

View File

@ -220,4 +220,6 @@ XMLCaseManagement.open.msgDlg.notAutCase.msg=Error\: This is not an Autopsy conf
Detail\: \n\
Cannot open a non-Autopsy config file (at {1}).
XMLCaseManagement.open.msgDlg.notAutCase.title=Error
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel
Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk.
Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1}

View File

@ -29,6 +29,7 @@ import java.nio.file.InvalidPathException;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
@ -39,6 +40,7 @@ import java.util.TimeZone;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.apache.commons.io.FileUtils;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
@ -128,7 +130,13 @@ public class Case implements SleuthkitCase.ErrorObserver {
* case. The old value supplied by the event object is null and the new
* value is a reference to a Report object representing the new report.
*/
REPORT_ADDED;
REPORT_ADDED,
/**
* Name for the property change event when a report/s is/are deleted
* from the case. Both the old value and the new value supplied by the
* event object are null.
*/
REPORTS_DELETED;
};
private String name;
@ -1185,6 +1193,37 @@ public class Case implements SleuthkitCase.ErrorObserver {
return this.db.getAllReports();
}
public void deleteReports(Collection<? extends Report> reports) throws TskCoreException {
String pathToReportsFolder = Paths.get(this.db.getDbDirPath(), "Reports").normalize().toString();
for (Report report : reports) {
// traverse to the root directory of Report report.
String reportPath = report.getPath();
while (!Paths.get(reportPath, "..").normalize().toString().equals(pathToReportsFolder)) {
reportPath = Paths.get(reportPath, "..").normalize().toString();
}
// delete from the disk.
try {
FileUtils.deleteDirectory(new File(reportPath));
} catch (IOException | SecurityException ex) {
logger.log(Level.WARNING, NbBundle.getMessage(Case.class, "Case.deleteReports.deleteFromDiskException.log.msg"), ex);
JOptionPane.showMessageDialog(null, NbBundle.getMessage(Case.class, "Case.deleteReports.deleteFromDiskException.msg", report.getReportName(), reportPath));
}
// delete from the database.
this.db.deleteReport(report);
// fire property change event.
try {
Case.pcs.firePropertyChange(Events.REPORTS_DELETED.toString(), null, null);
} catch (Exception ex) {
String errorMessage = String.format("A Case %s listener threw an exception", Events.REPORTS_DELETED.toString()); //NON-NLS
logger.log(Level.SEVERE, errorMessage, ex);
}
}
}
/**
* Returns if the case has data in it yet.
*

View File

@ -280,3 +280,6 @@ VolumeNode.createSheet.flags.displayName=Flags
VolumeNode.createSheet.flags.desc=no description
AbstractAbstractFileNode.objectId=Object ID
ArtifactStringContent.getStr.artifactId.text=Artifact ID
DeleteReportAction.actionDisplayName=Delete Report(s)
DeleteReportAction.actionPerformed.showConfirmDialog.title=Confirm Deletion
DeleteReportAction.actionPerformed.showConfirmDialog.msg=Delete {0} reports.\nClick OK to proceed.

View File

@ -27,6 +27,7 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import javax.swing.AbstractAction;
@ -37,8 +38,10 @@ import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.Report;
import org.sleuthkit.datamodel.TskCoreException;
@ -97,7 +100,7 @@ public final class Reports implements AutopsyVisitableItem {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String eventType = evt.getPropertyName();
if (eventType.equals(Case.Events.REPORT_ADDED.toString())) {
if (eventType.equals(Case.Events.REPORT_ADDED.toString()) || eventType.equals(Case.Events.REPORTS_DELETED.toString())) {
ReportNodeFactory.this.refresh(true);
}
}
@ -183,6 +186,7 @@ public final class Reports implements AutopsyVisitableItem {
List<Action> actions = new ArrayList<>();
actions.addAll(Arrays.asList(super.getActions(true)));
actions.add(new OpenReportAction());
actions.add(DeleteReportAction.getInstance());
return actions.toArray(new Action[actions.size()]);
}
@ -191,6 +195,45 @@ public final class Reports implements AutopsyVisitableItem {
return new OpenReportAction();
}
private static class DeleteReportAction extends AbstractAction {
private static DeleteReportAction instance;
// This class is a singleton to support multi-selection of nodes,
// since org.openide.nodes.NodeOp.findActions(Node[] nodes) will
// only pick up an Action if every node in the array returns a
// reference to the same action object from Node.getActions(boolean).
private static DeleteReportAction getInstance() {
if (instance == null) {
instance = new DeleteReportAction();
}
return instance;
}
/**
* Do not instantiate directly. Use
* DeleteReportAction.getInstance(), instead.
*/
private DeleteReportAction() {
super(NbBundle.getMessage(DeleteReportAction.class, "DeleteReportAction.actionDisplayName"));
}
@Override
public void actionPerformed(ActionEvent e) {
Collection<? extends Report> selectedReportsCollection = Utilities.actionsGlobalContext().lookupAll(Report.class);
if (JOptionPane.showConfirmDialog(null,
NbBundle.getMessage(DeleteReportAction.class, "DeleteReportAction.actionPerformed.showConfirmDialog.title"),
NbBundle.getMessage(DeleteReportAction.class, "DeleteReportAction.actionPerformed.showConfirmDialog.msg", selectedReportsCollection.size()),
JOptionPane.OK_CANCEL_OPTION) == 0) {
try {
Case.getCurrentCase().deleteReports(selectedReportsCollection);
DataContentTopComponent.findInstance().repaint();
} catch (TskCoreException | IllegalStateException ex) {
Logger.getLogger(DeleteReportAction.class.getName()).log(Level.INFO, "Error deleting the reports. ", ex); // NON-NLS - Provide solution to the user?
}
}
}
}
private final class OpenReportAction extends AbstractAction {
private OpenReportAction() {

View File

@ -118,7 +118,10 @@ public class DataResultFilterNode extends FilterNode {
List<Action> actions = new ArrayList<>();
final DisplayableItemNode originalNode = (DisplayableItemNode) this.getOriginal();
actions.addAll(originalNode.accept(getActionsDIV));
List<Action> accept = originalNode.accept(getActionsDIV);
if(accept != null) {
actions.addAll(accept);
}
//actions.add(new IndexContentFilesAction(nodeContent, "Index"));
return actions.toArray(new Action[actions.size()]);

View File

@ -321,6 +321,7 @@ class ReportKML implements GeneralReportModule {
// read the next line
line = reader.readLine();
}
reader.close();
progressPanel.increment();
/*
* Step 4: write the XML file