19 package org.sleuthkit.autopsy.geolocation;
21 import java.awt.BorderLayout;
22 import java.awt.Component;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.beans.PropertyChangeEvent;
26 import java.beans.PropertyChangeListener;
28 import java.io.IOException;
29 import java.text.DateFormat;
30 import java.text.SimpleDateFormat;
31 import java.util.Date;
32 import java.util.EnumSet;
33 import java.util.LinkedHashSet;
34 import java.util.List;
35 import java.util.Locale;
37 import java.util.logging.Level;
38 import javax.swing.JOptionPane;
39 import javax.swing.SwingUtilities;
40 import javax.swing.SwingWorker;
41 import org.openide.filesystems.FileUtil;
42 import org.openide.util.NbBundle.Messages;
43 import org.openide.windows.RetainLocation;
44 import org.openide.windows.TopComponent;
45 import org.openide.windows.WindowManager;
64 @TopComponent.Description(preferredID =
"GeolocationTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
65 @TopComponent.Registration(mode =
"geolocation", openAtStartup =
false)
66 @RetainLocation(
"geolocation")
67 @SuppressWarnings(
"PMD.SingularField")
70 private static final long serialVersionUID = 1L;
80 final RefreshPanel refreshPanel =
new RefreshPanel();
82 private static final String REPORT_PATH_FMT_STR =
"%s" + File.separator +
"%s %s %s" + File.separator;
85 private static final String REPORT_KML =
"ReportKML.kml";
87 private boolean mapInitalized =
false;
90 "GLTopComponent_name=Geolocation",
91 "GLTopComponent_initilzation_error=An error occurred during waypoint initilization. Geolocation data maybe incomplete.",
92 "GLTopComponent_No_dataSource_message=There are no data sources with Geolocation artifacts found.",
93 "GLTopComponent_No_dataSource_Title=No Geolocation artifacts found"
100 @SuppressWarnings(
"deprecation")
104 setName(Bundle.GLTopComponent_name());
106 this.ingestListener = pce -> {
107 String eventType = pce.getPropertyName();
108 if (eventType.equals(DATA_ADDED.toString())) {
111 if (null != eventData
114 || eventData.
getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID()
120 showRefreshPanel(
true);
125 this.caseEventListener = pce -> {
126 mapPanel.clearWaypoints();
127 if (pce.getNewValue() != null) {
132 refreshPanel.addCloseActionListener(
new ActionListener() {
134 public void actionPerformed(ActionEvent e) {
135 showRefreshPanel(
false);
139 refreshPanel.addRefreshActionListner(
new ActionListener() {
141 public void actionPerformed(ActionEvent e) {
142 geoFilterPanel.updateDataSourceList();
143 mapPanel.clearWaypoints();
144 showRefreshPanel(
false);
148 geoFilterPanel =
new GeoFilterPanel();
149 filterPane.setPanel(geoFilterPanel);
150 geoFilterPanel.addActionListener(
new ActionListener() {
152 public void actionPerformed(ActionEvent e) {
157 geoFilterPanel.addPropertyChangeListener(GeoFilterPanel.INITPROPERTY,
new PropertyChangeListener() {
159 public void propertyChange(PropertyChangeEvent evt) {
160 if (geoFilterPanel.hasDataSources()) {
163 geoFilterPanel.setEnabled(
false);
164 setWaypointLoading(
false);
165 JOptionPane.showMessageDialog(GeolocationTopComponent.this,
166 Bundle.GLTopComponent_No_dataSource_message(),
167 Bundle.GLTopComponent_No_dataSource_Title(),
168 JOptionPane.ERROR_MESSAGE);
174 mapPanel.addPropertyChangeListener(
MapPanel.CURRENT_MOUSE_GEOPOSITION,
new PropertyChangeListener() {
176 public void propertyChange(PropertyChangeEvent evt) {
178 Object newValue = evt.getNewValue();
179 if (newValue != null) {
180 label = newValue.toString();
183 coordLabel.setText(label);
198 super.removeNotify();
205 super.componentOpened();
206 WindowManager.getDefault().setTopComponentFloating(
this,
true);
211 "GeolocationTC_connection_failure_message=Failed to connect to map title source.\nPlease review map source in Options dialog.",
212 "GeolocationTC_connection_failure_message_title=Connection Failure"
219 if (!mapInitalized) {
222 mapInitalized =
true;
224 JOptionPane.showMessageDialog(
this,
225 Bundle.GeolocationTC_connection_failure_message(),
226 Bundle.GeolocationTC_connection_failure_message_title(),
227 JOptionPane.ERROR_MESSAGE);
229 Bundle.GeolocationTC_connection_failure_message_title(),
230 Bundle.GeolocationTC_connection_failure_message());
231 logger.log(Level.SEVERE, ex.getMessage(), ex);
236 mapPanel.clearWaypoints();
237 geoFilterPanel.clearDataSourceList();
238 geoFilterPanel.updateDataSourceList();
239 mapPanel.setWaypoints(
new LinkedHashSet<>());
249 SwingUtilities.invokeLater(
new Runnable() {
252 boolean isShowing =
false;
253 Component[] comps = mapPanel.getComponents();
254 for (Component comp : comps) {
255 if (comp.equals(refreshPanel)) {
260 if (show && !isShowing) {
261 mapPanel.add(refreshPanel, BorderLayout.NORTH);
262 mapPanel.revalidate();
263 }
else if (!show && isShowing) {
264 mapPanel.remove(refreshPanel);
265 mapPanel.revalidate();
277 "GeoTopComponent_no_waypoints_returned_mgs=Applied filter failed to find waypoints that matched criteria.\nRevise filter options and try again.",
278 "GeoTopComponent_no_waypoints_returned_Title=No Waypoints Found",
279 "GeoTopComponent_filter_exception_msg=Exception occurred during waypoint filtering.",
280 "GeoTopComponent_filter_exception_Title=Filter Failure",
281 "GeoTopComponent_filer_data_invalid_msg=Unable to run waypoint filter.\nPlease select one or more data sources.",
282 "GeoTopComponent_filer_data_invalid_Title=Filter Failure"
289 filters = geoFilterPanel.getFilterState();
291 JOptionPane.showMessageDialog(
this,
293 Bundle.GeoTopComponent_filer_data_invalid_Title(),
294 JOptionPane.INFORMATION_MESSAGE);
298 setWaypointLoading(
true);
299 geoFilterPanel.setEnabled(
false);
301 Thread thread =
new Thread(
new Runnable() {
307 logger.log(Level.SEVERE,
"Failed to filter waypoints.", ex);
308 SwingUtilities.invokeLater(
new Runnable() {
312 Bundle.GeoTopComponent_filter_exception_Title(),
313 Bundle.GeoTopComponent_filter_exception_msg(),
314 JOptionPane.ERROR_MESSAGE);
316 setWaypointLoading(
false);
333 void addWaypointsToMap(Set<MapWaypoint> waypointList, List<Set<MapWaypoint>> tracks) {
334 SwingUtilities.invokeLater(
new Runnable() {
338 if (waypointList == null || waypointList.isEmpty()) {
339 mapPanel.clearWaypoints();
341 Bundle.GeoTopComponent_no_waypoints_returned_Title(),
342 Bundle.GeoTopComponent_no_waypoints_returned_mgs(),
343 JOptionPane.INFORMATION_MESSAGE);
344 setWaypointLoading(
false);
345 geoFilterPanel.setEnabled(
true);
348 mapPanel.clearWaypoints();
349 mapPanel.setWaypoints(waypointList);
350 mapPanel.setTracks(tracks);
351 mapPanel.initializePainter();
352 setWaypointLoading(
false);
353 geoFilterPanel.setEnabled(
true);
363 void setWaypointLoading(
boolean loading) {
364 progressBar.setEnabled(
true);
365 progressBar.setVisible(loading);
366 progressBar.setString(
"Loading Waypoints");
383 DateFormat dateFormat =
new SimpleDateFormat(
"MM-dd-yyyy-HH-mm-ss", Locale.US);
384 Date date =
new Date();
385 String dateNoTime = dateFormat.format(date);
389 FileUtil.createFolder(
new File(reportPath));
390 }
catch (IOException ex) {
391 throw new IOException(
"Failed to make report folder, unable to generate reports.", ex);
401 @SuppressWarnings(
"unchecked")
403 private
void initComponents() {
404 java.awt.GridBagConstraints gridBagConstraints;
407 statusBar =
new javax.swing.JPanel();
408 reportButton =
new javax.swing.JButton();
409 progressBar =
new javax.swing.JProgressBar();
410 coordLabel =
new javax.swing.JLabel();
413 setLayout(
new java.awt.BorderLayout());
414 add(filterPane, java.awt.BorderLayout.WEST);
416 statusBar.setLayout(
new java.awt.GridBagLayout());
418 org.openide.awt.Mnemonics.setLocalizedText(reportButton,
org.openide.util.NbBundle.getMessage(
GeolocationTopComponent.class,
"GeolocationTopComponent.reportButton.text"));
419 reportButton.addActionListener(
new java.awt.event.ActionListener() {
420 public void actionPerformed(java.awt.event.ActionEvent evt) {
421 reportButtonActionPerformed(evt);
424 gridBagConstraints =
new java.awt.GridBagConstraints();
425 gridBagConstraints.gridx = 2;
426 gridBagConstraints.gridy = 0;
427 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
428 gridBagConstraints.insets =
new java.awt.Insets(5, 5, 5, 5);
429 statusBar.add(reportButton, gridBagConstraints);
431 progressBar.setIndeterminate(
true);
432 gridBagConstraints =
new java.awt.GridBagConstraints();
433 gridBagConstraints.gridx = 1;
434 gridBagConstraints.gridy = 0;
435 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
436 statusBar.add(progressBar, gridBagConstraints);
438 org.openide.awt.Mnemonics.setLocalizedText(coordLabel,
org.openide.util.NbBundle.getMessage(
GeolocationTopComponent.class,
"GeolocationTopComponent.coordLabel.text"));
439 gridBagConstraints =
new java.awt.GridBagConstraints();
440 gridBagConstraints.gridx = 0;
441 gridBagConstraints.gridy = 0;
442 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
443 gridBagConstraints.weightx = 1.0;
444 gridBagConstraints.insets =
new java.awt.Insets(5, 5, 5, 0);
445 statusBar.add(coordLabel, gridBagConstraints);
447 add(statusBar, java.awt.BorderLayout.SOUTH);
448 add(mapPanel, java.awt.BorderLayout.CENTER);
452 "GeolocationTC_empty_waypoint_message=Unable to generate KML report due to a lack of waypoints.\nPlease make sure there are waypoints visible before generating the KML report",
453 "GeolocationTC_KML_report_title=KML Report",
454 "GeolocationTC_report_progress_title=KML Report Progress"
457 List<MapWaypoint> visiblePoints = mapPanel.getVisibleWaypoints();
458 if (visiblePoints.isEmpty()) {
459 JOptionPane.showConfirmDialog(
this, Bundle.GeolocationTC_empty_waypoint_message(), Bundle.GeolocationTC_KML_report_title(), JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE);
465 String reportBaseDir = createReportDirectory();
467 progressPanel.
setLabels(REPORT_KML, reportBaseDir);
469 SwingWorker<Void, Void> worker =
new SwingWorker<Void, Void>() {
471 protected Void doInBackground()
throws Exception {
477 JOptionPane.showConfirmDialog(
this, progressPanel, Bundle.GeolocationTC_report_progress_title(), JOptionPane.CLOSED_OPTION, JOptionPane.PLAIN_MESSAGE);
478 }
catch (IOException ex) {
479 logger.log(Level.WARNING,
"Unable to create KML report", ex);
498 "GeolocationTopComponent.WaypointFetcher.onErrorTitle=Error gathering GPS Track Data",
499 "GeolocationTopComponent.WaypointFetcher.onErrorDescription=There was an error gathering some GPS Track Data. Some results have been excluded."
508 void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints, List<Set<MapWaypoint>> tracks,
boolean wasEntirelySuccessful) {
509 addWaypointsToMap(mapWaypoints, tracks);
512 if (!wasEntirelySuccessful) {
514 Bundle.GeolocationTopComponent_WaypointFetcher_onErrorDescription(),
515 Bundle.GeolocationTopComponent_WaypointFetcher_onErrorTitle(),
516 JOptionPane.ERROR_MESSAGE);
final void setLabels(String reportName, String reportPath)
BlackboardArtifact.Type getBlackboardArtifactType()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static String createReportDirectory()
static synchronized IngestManager getInstance()
void showRefreshPanel(boolean show)
javax.swing.JButton reportButton
String getReportDirectory()
org.sleuthkit.autopsy.geolocation.MapPanel mapPanel
final PropertyChangeListener caseEventListener
javax.swing.JProgressBar progressBar
javax.swing.JLabel coordLabel
final GeoFilterPanel geoFilterPanel
void reportButtonActionPerformed(java.awt.event.ActionEvent evt)
static synchronized KMLReport getDefault()
final PropertyChangeListener ingestListener
void generateReport(String baseReportDir, ReportProgressPanel progressPanel, List< Waypoint > waypointList)
static void error(String title, String message)
void addIngestModuleEventListener(final PropertyChangeListener listener)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
org.sleuthkit.autopsy.geolocation.HidingPane filterPane
javax.swing.JPanel statusBar
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)