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) {
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 setWaypointLoading(
false);
351 geoFilterPanel.setEnabled(
true);
361 void setWaypointLoading(
boolean loading) {
362 progressBar.setEnabled(
true);
363 progressBar.setVisible(loading);
364 progressBar.setString(
"Loading Waypoints");
381 DateFormat dateFormat =
new SimpleDateFormat(
"MM-dd-yyyy-HH-mm-ss", Locale.US);
382 Date date =
new Date();
383 String dateNoTime = dateFormat.format(date);
387 FileUtil.createFolder(
new File(reportPath));
388 }
catch (IOException ex) {
389 throw new IOException(
"Failed to make report folder, unable to generate reports.", ex);
399 @SuppressWarnings(
"unchecked")
401 private
void initComponents() {
402 java.awt.GridBagConstraints gridBagConstraints;
405 statusBar =
new javax.swing.JPanel();
406 reportButton =
new javax.swing.JButton();
407 progressBar =
new javax.swing.JProgressBar();
408 coordLabel =
new javax.swing.JLabel();
411 setLayout(
new java.awt.BorderLayout());
412 add(filterPane, java.awt.BorderLayout.WEST);
414 statusBar.setLayout(
new java.awt.GridBagLayout());
416 org.openide.awt.Mnemonics.setLocalizedText(reportButton,
org.openide.util.NbBundle.getMessage(
GeolocationTopComponent.class,
"GeolocationTopComponent.reportButton.text"));
417 reportButton.addActionListener(
new java.awt.event.ActionListener() {
418 public void actionPerformed(java.awt.event.ActionEvent evt) {
419 reportButtonActionPerformed(evt);
422 gridBagConstraints =
new java.awt.GridBagConstraints();
423 gridBagConstraints.gridx = 2;
424 gridBagConstraints.gridy = 0;
425 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
426 gridBagConstraints.insets =
new java.awt.Insets(5, 5, 5, 5);
427 statusBar.add(reportButton, gridBagConstraints);
429 progressBar.setIndeterminate(
true);
430 gridBagConstraints =
new java.awt.GridBagConstraints();
431 gridBagConstraints.gridx = 1;
432 gridBagConstraints.gridy = 0;
433 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
434 statusBar.add(progressBar, gridBagConstraints);
436 org.openide.awt.Mnemonics.setLocalizedText(coordLabel,
org.openide.util.NbBundle.getMessage(
GeolocationTopComponent.class,
"GeolocationTopComponent.coordLabel.text"));
437 gridBagConstraints =
new java.awt.GridBagConstraints();
438 gridBagConstraints.gridx = 0;
439 gridBagConstraints.gridy = 0;
440 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
441 gridBagConstraints.weightx = 1.0;
442 gridBagConstraints.insets =
new java.awt.Insets(5, 5, 5, 0);
443 statusBar.add(coordLabel, gridBagConstraints);
445 add(statusBar, java.awt.BorderLayout.SOUTH);
446 add(mapPanel, java.awt.BorderLayout.CENTER);
450 "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",
451 "GeolocationTC_KML_report_title=KML Report",
452 "GeolocationTC_report_progress_title=KML Report Progress"
455 List<MapWaypoint> visiblePoints = mapPanel.getVisibleWaypoints();
456 if (visiblePoints.isEmpty()) {
457 JOptionPane.showConfirmDialog(
this, Bundle.GeolocationTC_empty_waypoint_message(), Bundle.GeolocationTC_KML_report_title(), JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE);
463 String reportBaseDir = createReportDirectory();
465 progressPanel.
setLabels(REPORT_KML, reportBaseDir);
467 SwingWorker<Void, Void> worker =
new SwingWorker<Void, Void>() {
469 protected Void doInBackground()
throws Exception {
475 JOptionPane.showConfirmDialog(
this, progressPanel, Bundle.GeolocationTC_report_progress_title(), JOptionPane.CLOSED_OPTION, JOptionPane.PLAIN_MESSAGE);
476 }
catch (IOException ex) {
477 logger.log(Level.WARNING,
"Unable to create KML report", ex);
502 void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints) {
503 addWaypointsToMap(mapWaypoints);
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)