Autopsy  4.14.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
GeoFilterPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.geolocation;
20 
21 import java.awt.GridBagConstraints;
22 import java.awt.event.ActionListener;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.concurrent.ExecutionException;
29 import java.util.logging.Level;
30 import javafx.util.Pair;
31 import javax.swing.Icon;
32 import javax.swing.ImageIcon;
33 import javax.swing.SpinnerNumberModel;
34 import javax.swing.SwingWorker;
35 import org.openide.util.NbBundle.Messages;
39 import org.sleuthkit.datamodel.BlackboardArtifact;
40 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
41 import org.sleuthkit.datamodel.DataSource;
42 import org.sleuthkit.datamodel.SleuthkitCase;
43 import org.sleuthkit.datamodel.TskCoreException;
44 
49 class GeoFilterPanel extends javax.swing.JPanel {
50 
51  final static String INITPROPERTY = "FilterPanelInitCompleted";
52 
53  private static final long serialVersionUID = 1L;
54  private static final Logger logger = Logger.getLogger(GeoFilterPanel.class.getName());
55 
56  private final SpinnerNumberModel numberModel;
57  private final CheckBoxListPanel<DataSource> dsCheckboxPanel;
58  private final CheckBoxListPanel<ARTIFACT_TYPE> atCheckboxPanel;
59 
60  // Make sure to update if other GPS artifacts are added
61  @SuppressWarnings("deprecation")
62  private static final ARTIFACT_TYPE[] GPS_ARTIFACT_TYPES = {
63  ARTIFACT_TYPE.TSK_GPS_BOOKMARK,
64  ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION,
65  ARTIFACT_TYPE.TSK_GPS_ROUTE,
66  ARTIFACT_TYPE.TSK_GPS_SEARCH,
67  ARTIFACT_TYPE.TSK_GPS_TRACK,
68  ARTIFACT_TYPE.TSK_GPS_TRACKPOINT,
69  ARTIFACT_TYPE.TSK_METADATA_EXIF
70  };
71 
75  @Messages({
76  "GeoFilterPanel_DataSource_List_Title=Data Sources",
77  "GeoFilterPanel_ArtifactType_List_Title=Types"
78  })
79  GeoFilterPanel() {
80  // numberModel is used in initComponents
81  numberModel = new SpinnerNumberModel(10, 1, Integer.MAX_VALUE, 1);
82 
83  initComponents();
84 
85  // The gui builder cannot handle using CheckBoxListPanel due to its
86  // use of generics so we will initalize it here.
87  dsCheckboxPanel = new CheckBoxListPanel<>();
88  dsCheckboxPanel.setPanelTitle(Bundle.GeoFilterPanel_DataSource_List_Title());
89  dsCheckboxPanel.setPanelTitleIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/image.png")));
90  dsCheckboxPanel.setSetAllSelected(true);
91 
92  atCheckboxPanel = new CheckBoxListPanel<>();
93  atCheckboxPanel.setPanelTitle(Bundle.GeoFilterPanel_ArtifactType_List_Title());
94  atCheckboxPanel.setPanelTitleIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/extracted_content.png")));
95  atCheckboxPanel.setSetAllSelected(true);
96 
97  GridBagConstraints gridBagConstraints = new GridBagConstraints();
98  gridBagConstraints.gridx = 0;
99  gridBagConstraints.gridy = 3;
100  gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
101  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
102  gridBagConstraints.weightx = 1.0;
103  gridBagConstraints.weighty = 1.0;
104  gridBagConstraints.insets = new java.awt.Insets(0, 15, 0, 15);
105  add(dsCheckboxPanel, gridBagConstraints);
106 
107  gridBagConstraints = new GridBagConstraints();
108  gridBagConstraints.gridx = 0;
109  gridBagConstraints.gridy = 4;
110  gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
111  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
112  gridBagConstraints.weightx = 1.0;
113  gridBagConstraints.weighty = 1.0;
114  gridBagConstraints.insets = new java.awt.Insets(0, 15, 0, 15);
115  add(atCheckboxPanel, gridBagConstraints);
116  }
117 
118  @Override
119  public void setEnabled(boolean enabled) {
120  applyButton.setEnabled(enabled);
121  mostRecentButton.setEnabled(enabled);
122  allButton.setEnabled(enabled);
123  showWaypointsWOTSCheckBox.setEnabled(enabled && mostRecentButton.isSelected());
124  dsCheckboxPanel.setEnabled(enabled);
125  atCheckboxPanel.setEnabled(enabled);
126  daysLabel.setEnabled(enabled);
127  daysSpinner.setEnabled(enabled);
128  }
129 
133  void updateDataSourceList() {
134  DataSourceUpdater updater = new DataSourceUpdater();
135  updater.execute();
136  }
137 
141  void clearDataSourceList() {
142  dsCheckboxPanel.clearList();
143  atCheckboxPanel.clearList();
144  }
145 
146  boolean hasDataSources() {
147  return !dsCheckboxPanel.isEmpty();
148  }
149 
155  void addActionListener(ActionListener listener) {
156  applyButton.addActionListener(listener);
157  }
158 
166  @Messages({
167  "GeoFilterPanel_empty_dataSource=Unable to apply filter, please select one or more data sources.",
168  "GeoFilterPanel_empty_artifactType=Unable to apply filter, please select one or more artifact types."
169  })
170  GeoFilter getFilterState() throws GeoLocationUIException {
171  List<DataSource> dataSources = dsCheckboxPanel.getSelectedElements();
172  if (dataSources.isEmpty()) {
173  throw new GeoLocationUIException(Bundle.GeoFilterPanel_empty_dataSource());
174  }
175 
176  List<ARTIFACT_TYPE> artifactTypes = atCheckboxPanel.getSelectedElements();
177  if (artifactTypes.isEmpty()) {
178  throw new GeoLocationUIException(Bundle.GeoFilterPanel_empty_artifactType());
179  }
180  return new GeoFilter(allButton.isSelected(),
181  showWaypointsWOTSCheckBox.isSelected(),
182  numberModel.getNumber().intValue(),
183  dataSources,
184  artifactTypes);
185  }
186 
191  private void updateWaypointOptions() {
192  boolean selected = mostRecentButton.isSelected();
193  showWaypointsWOTSCheckBox.setEnabled(selected);
194  daysSpinner.setEnabled(selected);
195  }
196 
202  @SuppressWarnings("unchecked")
203  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
204  private void initComponents() {
205  java.awt.GridBagConstraints gridBagConstraints;
206 
207  javax.swing.ButtonGroup buttonGroup = new javax.swing.ButtonGroup();
208  javax.swing.JPanel waypointSettings = new javax.swing.JPanel();
209  allButton = new javax.swing.JRadioButton();
210  mostRecentButton = new javax.swing.JRadioButton();
211  showWaypointsWOTSCheckBox = new javax.swing.JCheckBox();
212  daysSpinner = new javax.swing.JSpinner(numberModel);
213  daysLabel = new javax.swing.JLabel();
214  showLabel = new javax.swing.JLabel();
215  javax.swing.JPanel buttonPanel = new javax.swing.JPanel();
216  applyButton = new javax.swing.JButton();
217  javax.swing.JLabel optionsLabel = new javax.swing.JLabel();
218 
219  setLayout(new java.awt.GridBagLayout());
220 
221  waypointSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.waypointSettings.border.title"))); // NOI18N
222  waypointSettings.setLayout(new java.awt.GridBagLayout());
223 
224  buttonGroup.add(allButton);
225  allButton.setSelected(true);
226  org.openide.awt.Mnemonics.setLocalizedText(allButton, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.allButton.text")); // NOI18N
227  allButton.addActionListener(new java.awt.event.ActionListener() {
228  public void actionPerformed(java.awt.event.ActionEvent evt) {
229  allButtonActionPerformed(evt);
230  }
231  });
232  gridBagConstraints = new java.awt.GridBagConstraints();
233  gridBagConstraints.gridx = 0;
234  gridBagConstraints.gridy = 1;
235  gridBagConstraints.gridwidth = 4;
236  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
237  gridBagConstraints.weightx = 1.0;
238  waypointSettings.add(allButton, gridBagConstraints);
239 
240  buttonGroup.add(mostRecentButton);
241  org.openide.awt.Mnemonics.setLocalizedText(mostRecentButton, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.mostRecentButton.text")); // NOI18N
242  mostRecentButton.addActionListener(new java.awt.event.ActionListener() {
243  public void actionPerformed(java.awt.event.ActionEvent evt) {
244  mostRecentButtonActionPerformed(evt);
245  }
246  });
247  gridBagConstraints = new java.awt.GridBagConstraints();
248  gridBagConstraints.gridx = 0;
249  gridBagConstraints.gridy = 2;
250  gridBagConstraints.gridwidth = 2;
251  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
252  waypointSettings.add(mostRecentButton, gridBagConstraints);
253 
254  org.openide.awt.Mnemonics.setLocalizedText(showWaypointsWOTSCheckBox, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.showWaypointsWOTSCheckBox.text")); // NOI18N
255  showWaypointsWOTSCheckBox.setEnabled(false);
256  gridBagConstraints = new java.awt.GridBagConstraints();
257  gridBagConstraints.gridx = 1;
258  gridBagConstraints.gridy = 3;
259  gridBagConstraints.gridwidth = 3;
260  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
261  gridBagConstraints.insets = new java.awt.Insets(0, -20, 0, 5);
262  waypointSettings.add(showWaypointsWOTSCheckBox, gridBagConstraints);
263 
264  daysSpinner.setEnabled(false);
265  daysSpinner.setPreferredSize(new java.awt.Dimension(75, 26));
266  gridBagConstraints = new java.awt.GridBagConstraints();
267  gridBagConstraints.gridx = 2;
268  gridBagConstraints.gridy = 2;
269  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
270  waypointSettings.add(daysSpinner, gridBagConstraints);
271 
272  org.openide.awt.Mnemonics.setLocalizedText(daysLabel, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.daysLabel.text")); // NOI18N
273  gridBagConstraints = new java.awt.GridBagConstraints();
274  gridBagConstraints.gridx = 3;
275  gridBagConstraints.gridy = 2;
276  gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
277  gridBagConstraints.weightx = 1.0;
278  gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
279  waypointSettings.add(daysLabel, gridBagConstraints);
280 
281  org.openide.awt.Mnemonics.setLocalizedText(showLabel, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.showLabel.text")); // NOI18N
282  showLabel.setToolTipText(org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.showLabel.toolTipText")); // NOI18N
283  gridBagConstraints = new java.awt.GridBagConstraints();
284  gridBagConstraints.gridx = 0;
285  gridBagConstraints.gridy = 0;
286  gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
287  waypointSettings.add(showLabel, gridBagConstraints);
288 
289  gridBagConstraints = new java.awt.GridBagConstraints();
290  gridBagConstraints.gridx = 0;
291  gridBagConstraints.gridy = 2;
292  gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
293  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
294  gridBagConstraints.weightx = 1.0;
295  gridBagConstraints.insets = new java.awt.Insets(5, 15, 9, 15);
296  add(waypointSettings, gridBagConstraints);
297 
298  buttonPanel.setLayout(new java.awt.GridBagLayout());
299 
300  applyButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/tick.png"))); // NOI18N
301  org.openide.awt.Mnemonics.setLocalizedText(applyButton, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.applyButton.text")); // NOI18N
302  gridBagConstraints = new java.awt.GridBagConstraints();
303  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
304  gridBagConstraints.weightx = 1.0;
305  buttonPanel.add(applyButton, gridBagConstraints);
306 
307  gridBagConstraints = new java.awt.GridBagConstraints();
308  gridBagConstraints.gridx = 0;
309  gridBagConstraints.gridy = 0;
310  gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
311  gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
312  gridBagConstraints.weightx = 1.0;
313  gridBagConstraints.insets = new java.awt.Insets(9, 15, 0, 15);
314  add(buttonPanel, gridBagConstraints);
315 
316  optionsLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/blueGeo16.png"))); // NOI18N
317  org.openide.awt.Mnemonics.setLocalizedText(optionsLabel, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.optionsLabel.text")); // NOI18N
318  gridBagConstraints = new java.awt.GridBagConstraints();
319  gridBagConstraints.gridx = 0;
320  gridBagConstraints.gridy = 1;
321  gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
322  gridBagConstraints.insets = new java.awt.Insets(0, 15, 0, 0);
323  add(optionsLabel, gridBagConstraints);
324  }// </editor-fold>//GEN-END:initComponents
325 
326  private void allButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allButtonActionPerformed
327  updateWaypointOptions();
328  }//GEN-LAST:event_allButtonActionPerformed
329 
330  private void mostRecentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mostRecentButtonActionPerformed
331  updateWaypointOptions();
332  }//GEN-LAST:event_mostRecentButtonActionPerformed
333 
334 
335  // Variables declaration - do not modify//GEN-BEGIN:variables
336  private javax.swing.JRadioButton allButton;
337  private javax.swing.JButton applyButton;
338  private javax.swing.JLabel daysLabel;
339  private javax.swing.JSpinner daysSpinner;
340  private javax.swing.JRadioButton mostRecentButton;
341  private javax.swing.JLabel showLabel;
342  private javax.swing.JCheckBox showWaypointsWOTSCheckBox;
343  // End of variables declaration//GEN-END:variables
344 
348  final class GeoFilter {
349 
350  private final boolean showAll;
351  private final boolean showWithoutTimeStamp;
352  private final int mostRecentNumDays;
353  private final List<DataSource> dataSources;
354  private final List<ARTIFACT_TYPE> artifactTypes;
355 
378  GeoFilter(boolean showAll, boolean withoutTimeStamp,
379  int mostRecentNumDays, List<DataSource> dataSources,
380  List<ARTIFACT_TYPE> artifactTypes) {
381  this.showAll = showAll;
382  this.showWithoutTimeStamp = withoutTimeStamp;
383  this.mostRecentNumDays = mostRecentNumDays;
384  this.dataSources = dataSources;
385  this.artifactTypes = artifactTypes;
386  }
387 
393  boolean showAllWaypoints() {
394  return showAll;
395  }
396 
404  boolean showWaypointsWithoutTimeStamp() {
405  return showWithoutTimeStamp;
406  }
407 
414  int getMostRecentNumDays() {
415  return mostRecentNumDays;
416  }
417 
425  List<DataSource> getDataSources() {
426  return Collections.unmodifiableList(dataSources);
427  }
428 
436  List<ARTIFACT_TYPE> getArtifactTypes() {
437  return Collections.unmodifiableList(artifactTypes);
438  }
439  }
440 
444  final private class Sources {
445  final List<Pair<String, DataSource>> dataSources;
446  final Map<ARTIFACT_TYPE, Long> artifactTypes;
447 
448  private Sources(List<Pair<String, DataSource>> dataSources,
449  Map<ARTIFACT_TYPE, Long> artifactTypes) {
450  this.dataSources = dataSources;
451  this.artifactTypes = artifactTypes;
452  }
453  }
454 
461  final private class DataSourceUpdater extends SwingWorker<Sources, Void> {
462 
463  @Override
464  protected Sources doInBackground() throws Exception {
465  SleuthkitCase sleuthkitCase = Case.getCurrentCase().getSleuthkitCase();
466  List<Pair<String, DataSource>> validSources = new ArrayList<>();
467  HashMap<ARTIFACT_TYPE, Long> atCountsTotal = new HashMap<>();
468 
469  for (DataSource dataSource : sleuthkitCase.getDataSources()) {
470  Map<ARTIFACT_TYPE, Long> atCounts = getGPSDataSources(sleuthkitCase, dataSource);
471  if (!atCounts.isEmpty()) {
472  for (Map.Entry<ARTIFACT_TYPE, Long> entry : atCounts.entrySet()) {
473  atCountsTotal.putIfAbsent(entry.getKey(), 0L);
474  atCountsTotal.put(entry.getKey(), atCountsTotal.get(entry.getKey()) + entry.getValue());
475  }
476  String dsName = sleuthkitCase.getContentById(dataSource.getId()).getName();
477  Pair<String, DataSource> pair = new Pair<>(dsName, dataSource);
478  validSources.add(pair);
479  }
480  }
481  return new Sources(validSources, atCountsTotal);
482  }
483 
495  private Map<ARTIFACT_TYPE, Long> getGPSDataSources(SleuthkitCase sleuthkitCase, DataSource dataSource) throws TskCoreException {
496  HashMap<ARTIFACT_TYPE, Long> ret = new HashMap<>();
497  for (BlackboardArtifact.ARTIFACT_TYPE type : GPS_ARTIFACT_TYPES) {
498  long count = sleuthkitCase.getBlackboardArtifactsTypeCount(type.getTypeID(), dataSource.getId());
499  if (count > 0) {
500  ret.put(type, count);
501  }
502  }
503  return ret;
504  }
505 
506  @Override
507  public void done() {
508  Sources sources = null;
509  try {
510  sources = get();
511  } catch (InterruptedException | ExecutionException ex) {
512  Throwable cause = ex.getCause();
513  if (cause != null) {
514  logger.log(Level.SEVERE, cause.getMessage(), cause);
515  } else {
516  logger.log(Level.SEVERE, ex.getMessage(), ex);
517  }
518  }
519 
520  if (sources != null) {
521  for (Pair<String, DataSource> source : sources.dataSources) {
522  dsCheckboxPanel.addElement(source.getKey(), null, source.getValue());
523  }
524  for (Map.Entry<ARTIFACT_TYPE, Long> entry : sources.artifactTypes.entrySet()) {
525  String dispName = entry.getKey().getDisplayName() + " (" + entry.getValue() + ")";
526  String iconPath = IconsUtil.getIconFilePath(entry.getKey().getTypeID());
527  Icon icon = new ImageIcon(getClass().getResource(iconPath));
528  atCheckboxPanel.addElement(dispName, icon, entry.getKey());
529  }
530  }
531 
532  GeoFilterPanel.this.firePropertyChange(INITPROPERTY, false, true);
533  }
534 
535  }
536 
537 }
Map< ARTIFACT_TYPE, Long > getGPSDataSources(SleuthkitCase sleuthkitCase, DataSource dataSource)
Sources(List< Pair< String, DataSource >> dataSources, Map< ARTIFACT_TYPE, Long > artifactTypes)

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.