more error checking in timeline

This commit is contained in:
adam-m 2013-03-05 11:25:07 -05:00
parent db89cc5d43
commit 62b8c384ea

View File

@ -78,7 +78,6 @@ import org.openide.modules.InstalledFileLocator;
import org.openide.nodes.ChildFactory; import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.util.HelpCtx; import org.openide.util.HelpCtx;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.CallableSystemAction;
@ -109,8 +108,8 @@ import org.sleuthkit.datamodel.TskData;
@ActionReferences(value = { @ActionReferences(value = {
@ActionReference(path = "Menu/Tools", position = 100)}) @ActionReference(path = "Menu/Tools", position = 100)})
@NbBundle.Messages(value = "CTL_TimelineView=Generate Timeline") @NbBundle.Messages(value = "CTL_TimelineView=Generate Timeline")
public class Simile2 extends CallableSystemAction implements Presenter.Toolbar, PropertyChangeListener { public class Simile2 extends CallableSystemAction implements Presenter.Toolbar, PropertyChangeListener {
private static final Logger logger = Logger.getLogger(Simile2.class.getName()); private static final Logger logger = Logger.getLogger(Simile2.class.getName());
private final java.io.File macRoot = InstalledFileLocator.getDefault().locate("mactime", Simile2.class.getPackage().getName(), false); private final java.io.File macRoot = InstalledFileLocator.getDefault().locate("mactime", Simile2.class.getPackage().getName(), false);
private JFrame jf; //frame for holding all the elements private JFrame jf; //frame for holding all the elements
@ -123,7 +122,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
private ScrollPane scroll_Events; //Scroll Panes for dealing with oversized an oversized chart private ScrollPane scroll_Events; //Scroll Panes for dealing with oversized an oversized chart
private final int Height_Frame = 850; //Sizing constants private final int Height_Frame = 850; //Sizing constants
private final int Width_Frame = 1300; private final int Width_Frame = 1300;
private Button button_DrillUp; //Navigation buttons private Button button_DrillUp; //Navigation buttons
private Button button_Go; private Button button_Go;
private ComboBox<String> dropdown_SelectYears; //Dropdown box for selecting years. Useful when the charts' scale means some years are unclickable, despite having events. private ComboBox<String> dropdown_SelectYears; //Dropdown box for selecting years. Useful when the charts' scale means some years are unclickable, despite having events.
private final Stack<BarChart> stack_PrevCharts = new Stack<BarChart>(); //Stack for storing drill-up information. private final Stack<BarChart> stack_PrevCharts = new Stack<BarChart>(); //Stack for storing drill-up information.
@ -154,11 +153,11 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
} }
}); });
} }
private void customize() { private void customize() {
//Making the main frame * //Making the main frame *
jf = new JFrame(Case.getCurrentCase().getName() + " - Autopsy Timeline (Beta)"); jf = new JFrame(Case.getCurrentCase().getName() + " - Autopsy Timeline (Beta)");
//use the same icon on jframe as main application //use the same icon on jframe as main application
jf.setIconImage(WindowManager.getDefault().getMainWindow().getIconImage()); jf.setIconImage(WindowManager.getDefault().getMainWindow().getIconImage());
jf.setSize(Width_Frame, Height_Frame); //(Width, Height) jf.setSize(Width_Frame, Height_Frame); //(Width, Height)
@ -176,7 +175,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
//ComboJPanel holds both of the above JPanels together, //ComboJPanel holds both of the above JPanels together,
//aligned vertically (Y_AXIS) //aligned vertically (Y_AXIS)
// create a horizontal split pane // create a horizontal split pane
final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, chartJPanel, viewerJPanel); final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, chartJPanel, viewerJPanel);
splitPane.setDividerLocation(450); splitPane.setDividerLocation(450);
@ -210,7 +209,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
if (!moduleDir.exists()) { if (!moduleDir.exists()) {
moduleDir.mkdir(); moduleDir.mkdir();
} }
java.io.File mactimeFile = new java.io.File(moduleDir, mactimeFileName); java.io.File mactimeFile = new java.io.File(moduleDir, mactimeFileName);
if (!mactimeFile.exists()) { if (!mactimeFile.exists()) {
logger.log(Level.INFO, "Creating mactime file."); logger.log(Level.INFO, "Creating mactime file.");
@ -233,8 +232,8 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
ObservableList<String> listSelect = FXCollections.observableArrayList(lsi); ObservableList<String> listSelect = FXCollections.observableArrayList(lsi);
dropdown_SelectYears = new ComboBox(listSelect); dropdown_SelectYears = new ComboBox(listSelect);
//Buttons for navigating up and down the timeline //Buttons for navigating up and down the timeline
button_DrillUp = new Button("Zoom Out"); button_DrillUp = new Button("Zoom Out");
button_DrillUp.setOnAction(new EventHandler<ActionEvent>() { button_DrillUp.setOnAction(new EventHandler<ActionEvent>() {
@Override @Override
public void handle(ActionEvent e) { public void handle(ActionEvent e) {
@ -248,7 +247,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
scroll_Events.setContent(chart_Events); scroll_Events.setContent(chart_Events);
} }
}); });
button_Go = new Button(""); button_Go = new Button("");
button_Go.setOnAction(new EventHandler<ActionEvent>() { button_Go.setOnAction(new EventHandler<ActionEvent>() {
@Override @Override
@ -260,9 +259,9 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
} }
}); });
//Adding things to the V and H boxes. //Adding things to the V and H boxes.
//hBox_Charts stores the pseudo menu bar at the top of the timeline. |Zoom Out|View Year: [Select Year]|| //hBox_Charts stores the pseudo menu bar at the top of the timeline. |Zoom Out|View Year: [Select Year]||
hBox_Charts.getChildren().addAll(button_DrillUp, new Label("View Year:"), dropdown_SelectYears, button_Go); hBox_Charts.getChildren().addAll(button_DrillUp, new Label("View Year:"), dropdown_SelectYears, button_Go);
vBox_FX.getChildren().addAll(hBox_Charts, scroll_Events); //FxBox_V holds things in a visual stack. vBox_FX.getChildren().addAll(hBox_Charts, scroll_Events); //FxBox_V holds things in a visual stack.
group_Charts.getChildren().add(vBox_FX); //Adding the FxBox to the group. Groups make things easier to manipulate without having to update a hundred things every change. group_Charts.getChildren().add(vBox_FX); //Adding the FxBox to the group. Groups make things easier to manipulate without having to update a hundred things every change.
panel_Charts.setScene(scene_Charts); panel_Charts.setScene(scene_Charts);
@ -286,7 +285,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
} finally { } finally {
// stop the progress bar // stop the progress bar
progress.finish(); progress.finish();
// close the dialog // close the dialog
dialog.doClose(0); dialog.doClose(0);
} }
@ -330,27 +329,27 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
data.getNode().setScaleX(.5); data.getNode().setScaleX(.5);
data.getNode().addEventHandler(MouseEvent.MOUSE_CLICKED, data.getNode().addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() { new EventHandler<MouseEvent>() {
@Override @Override
public void handle(MouseEvent e) { public void handle(MouseEvent e) {
if (e.getButton().equals(MouseButton.PRIMARY)) { if (e.getButton().equals(MouseButton.PRIMARY)) {
if (e.getClickCount() == 2) { //Checking for a doubleclick if (e.getClickCount() == 2) { //Checking for a doubleclick
PlatformImpl.startup(new Runnable() { PlatformImpl.startup(new Runnable() {
@Override @Override
public void run() { public void run() {
BarChart b = createMonthsWithDrill((YearEpoch) findYear(allYears, Integer.valueOf((String) data.getXValue()))); BarChart b = createMonthsWithDrill((YearEpoch) findYear(allYears, Integer.valueOf((String) data.getXValue())));
chart_Events = b; chart_Events = b;
scroll_Events.setContent(chart_Events); scroll_Events.setContent(chart_Events);
}
});
//If a single click, hover a label over the cursor with information about the selection
} else if (e.getClickCount() == 1) {
l.setText(findYear(allYears, Integer.valueOf((String) data.getXValue())).getNumFiles() + " events");
l.setTranslateX(e.getX());
l.setTranslateY(e.getY());
} }
} });
//If a single click, hover a label over the cursor with information about the selection
} else if (e.getClickCount() == 1) {
l.setText(findYear(allYears, Integer.valueOf((String) data.getXValue())).getNumFiles() + " events");
l.setTranslateX(e.getX());
l.setTranslateY(e.getY());
} }
}); }
}
});
} }
bc.autosize(); //Get an auto height bc.autosize(); //Get an auto height
@ -389,24 +388,24 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
// Sometimes I've had it jacked up to as much as x2400 just to see a sliver of information. // Sometimes I've had it jacked up to as much as x2400 just to see a sliver of information.
// But that doesn't work all the time. Adding it to a scrollpane and letting the user scroll up and down to view the chart is the other workaround. Both of these fixes suck. // But that doesn't work all the time. Adding it to a scrollpane and letting the user scroll up and down to view the chart is the other workaround. Both of these fixes suck.
data.getNode().setScaleX(.5); data.getNode().setScaleX(.5);
data.getNode().addEventHandler(MouseEvent.MOUSE_PRESSED, data.getNode().addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() { new EventHandler<MouseEvent>() {
@Override @Override
public void handle(MouseEvent e) { public void handle(MouseEvent e) {
if (e.getButton().equals(MouseButton.PRIMARY)) { if (e.getButton().equals(MouseButton.PRIMARY)) {
if (e.getClickCount() == 2) { if (e.getClickCount() == 2) {
PlatformImpl.startup(new Runnable() { PlatformImpl.startup(new Runnable() {
@Override @Override
public void run() { public void run() {
chart_Events = createEventsByMonth(findMonth(ye.months, monthStringToInt((String) data.getXValue())), ye); chart_Events = createEventsByMonth(findMonth(ye.months, monthStringToInt((String) data.getXValue())), ye);
scroll_Events.setContent(chart_Events); scroll_Events.setContent(chart_Events);
}
});
} }
} });
} }
}); }
}
});
} }
} }
@ -430,7 +429,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
ObservableList<BarChart.Data> bcData = makeObservableListByMonthAllDays(me, ye.getYear()); ObservableList<BarChart.Data> bcData = makeObservableListByMonthAllDays(me, ye.getYear());
BarChart.Series<String, Number> series = new BarChart.Series(bcData); BarChart.Series<String, Number> series = new BarChart.Series(bcData);
series.setName(me.getMonthName() + " " + ye.getYear()); series.setName(me.getMonthName() + " " + ye.getYear());
ObservableList<BarChart.Series<String, Number>> ol = FXCollections.observableArrayList(series); ObservableList<BarChart.Series<String, Number>> ol = FXCollections.observableArrayList(series);
@ -439,31 +438,31 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
//data.getNode().setScaleX(2); //data.getNode().setScaleX(2);
data.getNode().addEventHandler(MouseEvent.MOUSE_PRESSED, data.getNode().addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() { new EventHandler<MouseEvent>() {
MonthEpoch myme = me; MonthEpoch myme = me;
@Override
public void handle(MouseEvent e) {
int day = (Integer.valueOf(((String) data.getXValue()).split("-")[1]));
DayEpoch de = myme.getDay(day);
List<AbstractFile> afs = Collections.EMPTY_LIST;
if (de != null) {
afs = de.getEvents();
} else {
logger.log(Level.SEVERE, "There were no events for the clicked-on day.");
}
final FsContentRootNode d = new FsContentRootNode("Test Root", afs);
SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void handle(MouseEvent e) { public void run() {
int day = (Integer.valueOf(((String) data.getXValue()).split("-")[1])); dataResult.setNode(d);
DayEpoch de = myme.getDay(day);
List<AbstractFile> afs = Collections.EMPTY_LIST;
if (de != null) {
afs = de.getEvents();
} else {
logger.log(Level.SEVERE, "There were no events for the clicked-on day.");
}
final FsContentRootNode d = new FsContentRootNode("Test Root", afs);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dataResult.setNode(d);
}
});
//set result viewer title path with the current date
String dateString = ye.getYear() + "-" + (1+me.getMonthInt()) + "-" + + de.dayNum;
dataResult.setPath(dateString);
} }
}); });
//set result viewer title path with the current date
String dateString = ye.getYear() + "-" + (1 + me.getMonthInt()) + "-" + +de.dayNum;
dataResult.setPath(dateString);
}
});
} }
bc.autosize(); bc.autosize();
bc.setPrefWidth(Width_Frame); bc.setPrefWidth(Width_Frame);
@ -487,8 +486,9 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
* Section for Utility functions * Section for Utility functions
*/ */
/** /**
* *
* @param mon The month to convert. Must be minimum 4 characters long "February" and "Febr" are acceptable. * @param mon The month to convert. Must be minimum 4 characters long
* "February" and "Febr" are acceptable.
* @return The integer value of the month. February = 1, July = 6 * @return The integer value of the month. February = 1, July = 6
*/ */
private static int monthStringToInt(String mon) { private static int monthStringToInt(String mon) {
@ -505,8 +505,10 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
/** /**
* Used for finding the proper month in a list of available months * Used for finding the proper month in a list of available months
* @param lst The list of months to search through. It is assumed that the desired match is in this list. *
* @param match The month, in integer format, to retrieve. * @param lst The list of months to search through. It is assumed that the
* desired match is in this list.
* @param match The month, in integer format, to retrieve.
* @return The month epoch as specified by match. * @return The month epoch as specified by match.
*/ */
private static MonthEpoch findMonth(List<MonthEpoch> lst, int match) { private static MonthEpoch findMonth(List<MonthEpoch> lst, int match) {
@ -518,10 +520,12 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
return null; return null;
} }
/** /**
* Used for finding the proper year in a list of available years * Used for finding the proper year in a list of available years
* @param lst The list of years to search through. It is assumed that the desired match is in this list. *
* @param match The year to retrieve. * @param lst The list of years to search through. It is assumed that the
* desired match is in this list.
* @param match The year to retrieve.
* @return The year epoch as specified by match. * @return The year epoch as specified by match.
*/ */
private static YearEpoch findYear(List<YearEpoch> lst, int match) { private static YearEpoch findYear(List<YearEpoch> lst, int match) {
@ -557,11 +561,11 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
jf.dispose(); jf.dispose();
jf = null; jf = null;
} }
data = null; data = null;
} }
} }
private void clearMactimeData() { private void clearMactimeData() {
// get rid of the old data // get rid of the old data
data = null; data = null;
@ -575,11 +579,9 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
jf.dispose(); jf.dispose();
// remove ourself as change listener on Case // remove ourself as change listener on Case
Case currcase = Case.getCurrentCase(); Case.removePropertyChangeListener(this);
if (currcase != null) { listeningToAddImage = false;
currcase.removePropertyChangeListener(this);
listeningToAddImage = false;
}
} }
/* /*
@ -587,6 +589,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
* All of those are Epochs. * All of those are Epochs.
*/ */
abstract class Epoch { abstract class Epoch {
abstract public int getNumFiles(); abstract public int getNumFiles();
} }
@ -594,15 +597,15 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
private int year; private int year;
private List<MonthEpoch> months = new ArrayList<>(); private List<MonthEpoch> months = new ArrayList<>();
YearEpoch(int year) { YearEpoch(int year) {
this.year = year; this.year = year;
} }
public int getYear() { public int getYear() {
return year; return year;
} }
@Override @Override
public int getNumFiles() { public int getNumFiles() {
int size = 0; int size = 0;
@ -611,10 +614,10 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
} }
return size; return size;
} }
public MonthEpoch getMonth(int monthNum) { public MonthEpoch getMonth(int monthNum) {
MonthEpoch month = null; MonthEpoch month = null;
for (MonthEpoch me :months) { for (MonthEpoch me : months) {
if (me.getMonthInt() == monthNum) { if (me.getMonthInt() == monthNum) {
month = me; month = me;
break; break;
@ -622,7 +625,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
} }
return month; return month;
} }
public void add(AbstractFile af, int month, int day) { public void add(AbstractFile af, int month, int day) {
// see if this month is in the list // see if this month is in the list
MonthEpoch monthEpoch = null; MonthEpoch monthEpoch = null;
@ -632,12 +635,12 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
break; break;
} }
} }
if (monthEpoch == null) { if (monthEpoch == null) {
monthEpoch = new MonthEpoch(month); monthEpoch = new MonthEpoch(month);
months.add(monthEpoch); months.add(monthEpoch);
} }
// add the file the the MonthEpoch object // add the file the the MonthEpoch object
monthEpoch.add(af, day); monthEpoch.add(af, day);
} }
@ -651,17 +654,17 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
MonthEpoch(int month) { MonthEpoch(int month) {
this.month = month; this.month = month;
} }
public int getMonthInt() { public int getMonthInt() {
return month; return month;
} }
public int getTotalNumDays(int year) { public int getTotalNumDays(int year) {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.set(year, month, 1); cal.set(year, month, 1);
return cal.getActualMaximum(Calendar.DAY_OF_MONTH); return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
} }
@Override @Override
public int getNumFiles() { public int getNumFiles() {
int numFiles = 0; int numFiles = 0;
@ -670,7 +673,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
} }
return numFiles; return numFiles;
} }
public DayEpoch getDay(int dayNum) { public DayEpoch getDay(int dayNum) {
DayEpoch de = null; DayEpoch de = null;
for (DayEpoch d : days) { for (DayEpoch d : days) {
@ -681,7 +684,7 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
} }
return de; return de;
} }
public void add(AbstractFile af, int day) { public void add(AbstractFile af, int day) {
DayEpoch dayEpoch = null; DayEpoch dayEpoch = null;
for (DayEpoch de : days) { for (DayEpoch de : days) {
@ -690,12 +693,12 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
break; break;
} }
} }
if (dayEpoch == null) { if (dayEpoch == null) {
dayEpoch = new DayEpoch(day); dayEpoch = new DayEpoch(day);
days.add(dayEpoch); days.add(dayEpoch);
} }
dayEpoch.add(af); dayEpoch.add(af);
} }
@ -718,20 +721,20 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
private List<AbstractFile> files = new ArrayList<>(); private List<AbstractFile> files = new ArrayList<>();
int dayNum = 0; //Day of the month this Epoch represents, 1 indexed: 28=28. int dayNum = 0; //Day of the month this Epoch represents, 1 indexed: 28=28.
DayEpoch(int dayOfMonth) { DayEpoch(int dayOfMonth) {
this.dayNum = dayOfMonth; this.dayNum = dayOfMonth;
} }
public int getDayInt() { public int getDayInt() {
return dayNum; return dayNum;
} }
@Override @Override
public int getNumFiles() { public int getNumFiles() {
return files.size(); return files.size();
} }
public void add(AbstractFile af) { public void add(AbstractFile af) {
files.add(af); files.add(af);
} }
@ -743,37 +746,44 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
// The node factories used to make lists of files to send to the result viewer // The node factories used to make lists of files to send to the result viewer
private class FsContentNodeChildFactory extends ChildFactory<AbstractFile> { private class FsContentNodeChildFactory extends ChildFactory<AbstractFile> {
List<AbstractFile> l; List<AbstractFile> l;
FsContentNodeChildFactory(List<AbstractFile> l) { FsContentNodeChildFactory(List<AbstractFile> l) {
this.l = l; this.l = l;
} }
@Override @Override
protected boolean createKeys(List<AbstractFile> list) { protected boolean createKeys(List<AbstractFile> list) {
list.addAll(l); list.addAll(l);
return true; return true;
} }
@Override @Override
protected Node createNodeForKey(AbstractFile file) { protected Node createNodeForKey(AbstractFile file) {
Node wrapped; Node wrapped;
if (file.isDir()) { if (file.isDir()) {
wrapped = new DirectoryNode((Directory) file, false); wrapped = new DirectoryNode((Directory) file, false);
} else { } else {
wrapped = new FileNode((File) file, false); wrapped = new FileNode((File) file, false);
} }
return new FilterNodeLeaf(wrapped); return new FilterNodeLeaf(wrapped);
} }
} }
private class FsContentRootNode extends DisplayableItemNode { private class FsContentRootNode extends DisplayableItemNode {
FsContentRootNode(String NAME, List<AbstractFile> l) { FsContentRootNode(String NAME, List<AbstractFile> l) {
super(Children.create(new FsContentNodeChildFactory(l), true)); super(Children.create(new FsContentNodeChildFactory(l), true));
super.setName(NAME); super.setName(NAME);
super.setDisplayName(NAME); super.setDisplayName(NAME);
} }
@Override @Override
public DisplayableItemNode.TYPE getDisplayableItemNodeType() { public DisplayableItemNode.TYPE getDisplayableItemNodeType() {
return DisplayableItemNode.TYPE.CONTENT; return DisplayableItemNode.TYPE.CONTENT;
} }
@Override @Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) { public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return null; return null;
@ -823,20 +833,26 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
ye.add(file, month, day); ye.add(file, month, day);
} }
} }
scan.close(); scan.close();
return years; return years;
} }
/**
* Crate a body file and return its path or null if error
*
* @return absolute path string or null if error
*/
private String makeBodyFile() { private String makeBodyFile() {
// Setup timestamp // Setup timestamp
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss"); DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date(); Date date = new Date();
String datenotime = dateFormat.format(date); String datenotime = dateFormat.format(date);
Case currentCase = Case.getCurrentCase(); final Case currentCase = Case.getCurrentCase();
SleuthkitCase skCase = currentCase.getSleuthkitCase(); final SleuthkitCase skCase = currentCase.getSleuthkitCase();
// Get report path // Get report path
String bodyFilePath = moduleDir.getAbsolutePath() String bodyFilePath = moduleDir.getAbsolutePath()
+ java.io.File.separator + currentCase.getName() + "-" + datenotime + ".txt"; + java.io.File.separator + currentCase.getName() + "-" + datenotime + ".txt";
@ -845,34 +861,39 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
String filesAndDirs = "type = '" + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType() + "' " String filesAndDirs = "type = '" + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType() + "' "
+ "AND name != '.' " + "AND name != '.' "
+ "AND name != '..'"; + "AND name != '..'";
List<FsContent> fs = Collections.EMPTY_LIST; List<FsContent> fs = null;
try { try {
fs = skCase.findFilesWhere(filesAndDirs); fs = skCase.findFilesWhere(filesAndDirs);
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
Exceptions.printStackTrace(ex); logger.log(Level.SEVERE, "Error querying image files to make a body file: " + bodyFilePath, ex);
return null;
} }
// Loop files and write info to report // Loop files and write info to report
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(bodyFilePath, true);
} catch (IOException ex) {
logger.log(Level.SEVERE, "Error creating output stream to write body file to: " + bodyFilePath, ex);
return null;
}
BufferedWriter out = null; BufferedWriter out = null;
try { try {
out = new BufferedWriter(new FileWriter(bodyFilePath, true)); out = new BufferedWriter(fileWriter);
} catch (IOException ex) { for (FsContent file : fs) {
logger.log(Level.WARNING, "Could not create new BufferedWriter for body file.", ex); // try {
}
for (FsContent file : fs) {
try {
// MD5|name|inode|mode_as_string|ObjId|GID|size|atime|mtime|ctime|crtime // MD5|name|inode|mode_as_string|ObjId|GID|size|atime|mtime|ctime|crtime
//out = new BufferedWriter(new FileWriter(bodyFilePath, true));
if (file.getMd5Hash() != null) { if (file.getMd5Hash() != null) {
out.write(file.getMd5Hash()); out.write(file.getMd5Hash());
} }
out.write("|"); out.write("|");
String path = ""; String path = null;
try { try {
path = file.getUniquePath(); path = file.getUniquePath();
} catch (TskCoreException e) { } catch (TskCoreException e) {
logger.log(Level.WARNING, "Failed to get the unique path.", e); logger.log(Level.SEVERE, "Failed to get the unique path of: " + file + " and writing body file.", e);
return null;
} }
out.write(path); out.write(path);
@ -899,18 +920,21 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
out.write("|"); out.write("|");
out.write(Long.toString(file.getCrtime())); out.write(Long.toString(file.getCrtime()));
out.write("\n"); out.write("\n");
} catch (IOException ex) { }
logger.log(Level.WARNING, "Probelm while trying to write data to the body file.", ex); } catch (IOException ex) {
break; logger.log(Level.WARNING, "Error while trying to write data to the body file.", ex);
return null;
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException ex1) {
logger.log(Level.WARNING, "Could not flush and/or close body file.", ex1);
}
} }
} }
try {
out.flush();
out.close();
} catch (IOException ex1) {
logger.log(Level.WARNING, "Could not flush and/or close body file.", ex1);
}
return bodyFilePath; return bodyFilePath;
} }
@ -952,11 +976,13 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
return; return;
} }
final Case currentCase = Case.getCurrentCase();
try { try {
if (Case.getCurrentCase().getImages().isEmpty()) { if (currentCase.getImages().isEmpty()) {
logger.log(Level.INFO, "Error creating timeline, there are no images to parse"); logger.log(Level.INFO, "Error creating timeline, there are no images to parse");
} else { } else {
if (IngestManager.getDefault().isIngestRunning()) { if (IngestManager.getDefault().isIngestRunning()) {
int answer = JOptionPane.showConfirmDialog(new JFrame(), int answer = JOptionPane.showConfirmDialog(new JFrame(),
"You are trying to generate a timeline before " "You are trying to generate a timeline before "
@ -967,25 +993,24 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
return; return;
} }
} }
logger.log(Level.INFO, "Beginning generation of timeline"); logger.log(Level.INFO, "Beginning generation of timeline");
// if the timeline window is already open, do nothing // if the timeline window is already open, do nothing
if (jf != null && jf.isVisible()) { if (jf != null && jf.isVisible()) {
return; return;
} }
Platform.setImplicitExit(false); Platform.setImplicitExit(false);
// listen for case changes (specifically images being added). // listen for case changes (specifically images being added).
Case currcase = Case.getCurrentCase(); if (Case.isCaseOpen() && !listeningToAddImage) {
if (currcase != null && !listeningToAddImage) { Case.addPropertyChangeListener(this);
currcase.addPropertyChangeListener(this);
listeningToAddImage = true; listeningToAddImage = true;
} }
// create the modal dialog // create the modal dialog
SwingUtilities.invokeLater(new Runnable () { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
dialog = new TimelineProgressDialog(jf, true); dialog = new TimelineProgressDialog(jf, true);
@ -994,11 +1019,11 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
}); });
// initialize mactimeFileName // initialize mactimeFileName
mactimeFileName = Case.getCurrentCase().getName() + "-MACTIME.txt"; mactimeFileName = currentCase.getName() + "-MACTIME.txt";
// see if data has been added to the database since the last // see if data has been added to the database since the last
// time timeline ran // time timeline ran
long objId = Case.getCurrentCase().getSleuthkitCase().getLastObjectId(); long objId = currentCase.getSleuthkitCase().getLastObjectId();
if (objId != lastObjectId && lastObjectId != -1) { if (objId != lastObjectId && lastObjectId != -1) {
clearMactimeData(); clearMactimeData();
} }
@ -1008,7 +1033,9 @@ public class Simile2 extends CallableSystemAction implements Presenter.Toolbar,
customize(); customize();
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
Exceptions.printStackTrace(ex); logger.log(Level.SEVERE, "Error when generating timeline, ", ex);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Unexpected error when generating timeline, ", ex);
} }
} }