19 package org.sleuthkit.autopsy.geolocation;
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;
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;
40 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
49 class GeoFilterPanel
extends javax.swing.JPanel {
51 final static String INITPROPERTY =
"FilterPanelInitCompleted";
53 private static final long serialVersionUID = 1L;
54 private static final Logger logger = Logger.getLogger(GeoFilterPanel.class.getName());
56 private final SpinnerNumberModel numberModel;
57 private final CheckBoxListPanel<DataSource> dsCheckboxPanel;
58 private final CheckBoxListPanel<ARTIFACT_TYPE> atCheckboxPanel;
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
76 "GeoFilterPanel_DataSource_List_Title=Data Sources",
77 "GeoFilterPanel_ArtifactType_List_Title=Types"
81 numberModel =
new SpinnerNumberModel(10, 1, Integer.MAX_VALUE, 1);
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);
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);
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);
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);
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);
133 void updateDataSourceList() {
134 DataSourceUpdater updater =
new DataSourceUpdater();
141 void clearDataSourceList() {
142 dsCheckboxPanel.clearList();
143 atCheckboxPanel.clearList();
146 boolean hasDataSources() {
147 return !dsCheckboxPanel.isEmpty();
155 void addActionListener(ActionListener listener) {
156 applyButton.addActionListener(listener);
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."
170 GeoFilter getFilterState() throws GeoLocationUIException {
171 List<DataSource> dataSources = dsCheckboxPanel.getSelectedElements();
172 if (dataSources.isEmpty()) {
173 throw new GeoLocationUIException(Bundle.GeoFilterPanel_empty_dataSource());
176 List<ARTIFACT_TYPE> artifactTypes = atCheckboxPanel.getSelectedElements();
177 if (artifactTypes.isEmpty()) {
178 throw new GeoLocationUIException(Bundle.GeoFilterPanel_empty_artifactType());
180 return new GeoFilter(allButton.isSelected(),
181 showWaypointsWOTSCheckBox.isSelected(),
182 numberModel.getNumber().intValue(),
191 private void updateWaypointOptions() {
192 boolean selected = mostRecentButton.isSelected();
193 showWaypointsWOTSCheckBox.setEnabled(selected);
194 daysSpinner.setEnabled(selected);
202 @SuppressWarnings(
"unchecked")
204 private
void initComponents() {
205 java.awt.GridBagConstraints gridBagConstraints;
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();
219 setLayout(
new java.awt.GridBagLayout());
221 waypointSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(
org.openide.util.NbBundle.getMessage(GeoFilterPanel.class,
"GeoFilterPanel.waypointSettings.border.title")));
222 waypointSettings.setLayout(
new java.awt.GridBagLayout());
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"));
227 allButton.addActionListener(
new java.awt.event.ActionListener() {
228 public void actionPerformed(java.awt.event.ActionEvent evt) {
229 allButtonActionPerformed(evt);
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);
240 buttonGroup.add(mostRecentButton);
241 org.openide.awt.Mnemonics.setLocalizedText(mostRecentButton,
org.openide.util.NbBundle.getMessage(GeoFilterPanel.class,
"GeoFilterPanel.mostRecentButton.text"));
242 mostRecentButton.addActionListener(
new java.awt.event.ActionListener() {
243 public void actionPerformed(java.awt.event.ActionEvent evt) {
244 mostRecentButtonActionPerformed(evt);
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);
254 org.openide.awt.Mnemonics.setLocalizedText(showWaypointsWOTSCheckBox,
org.openide.util.NbBundle.getMessage(GeoFilterPanel.class,
"GeoFilterPanel.showWaypointsWOTSCheckBox.text"));
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);
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);
272 org.openide.awt.Mnemonics.setLocalizedText(daysLabel,
org.openide.util.NbBundle.getMessage(GeoFilterPanel.class,
"GeoFilterPanel.daysLabel.text"));
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);
281 org.openide.awt.Mnemonics.setLocalizedText(showLabel,
org.openide.util.NbBundle.getMessage(GeoFilterPanel.class,
"GeoFilterPanel.showLabel.text"));
282 showLabel.setToolTipText(
org.openide.util.NbBundle.getMessage(GeoFilterPanel.class,
"GeoFilterPanel.showLabel.toolTipText"));
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);
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);
298 buttonPanel.setLayout(
new java.awt.GridBagLayout());
300 applyButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/tick.png")));
301 org.openide.awt.Mnemonics.setLocalizedText(applyButton,
org.openide.util.NbBundle.getMessage(GeoFilterPanel.class,
"GeoFilterPanel.applyButton.text"));
302 gridBagConstraints =
new java.awt.GridBagConstraints();
303 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
304 gridBagConstraints.weightx = 1.0;
305 buttonPanel.add(applyButton, gridBagConstraints);
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);
316 optionsLabel.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/blueGeo16.png")));
317 org.openide.awt.Mnemonics.setLocalizedText(optionsLabel,
org.openide.util.NbBundle.getMessage(GeoFilterPanel.class,
"GeoFilterPanel.optionsLabel.text"));
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);
326 private void allButtonActionPerformed(java.awt.event.ActionEvent evt) {
327 updateWaypointOptions();
330 private void mostRecentButtonActionPerformed(java.awt.event.ActionEvent evt) {
331 updateWaypointOptions();
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;
348 final class GeoFilter {
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;
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;
393 boolean showAllWaypoints() {
404 boolean showWaypointsWithoutTimeStamp() {
405 return showWithoutTimeStamp;
414 int getMostRecentNumDays() {
415 return mostRecentNumDays;
425 List<DataSource> getDataSources() {
426 return Collections.unmodifiableList(dataSources);
436 List<ARTIFACT_TYPE> getArtifactTypes() {
437 return Collections.unmodifiableList(artifactTypes);
445 final List<Pair<String, DataSource>> dataSources;
446 final Map<ARTIFACT_TYPE, Long> artifactTypes;
448 private Sources(List<Pair<String, DataSource>> dataSources,
449 Map<ARTIFACT_TYPE, Long> artifactTypes) {
450 this.dataSources = dataSources;
451 this.artifactTypes = artifactTypes;
466 List<Pair<String, DataSource>> validSources =
new ArrayList<>();
467 HashMap<ARTIFACT_TYPE, Long> atCountsTotal =
new HashMap<>();
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());
476 String dsName = sleuthkitCase.getContentById(dataSource.getId()).getName();
477 Pair<String, DataSource> pair =
new Pair<>(dsName, dataSource);
478 validSources.add(pair);
481 return new Sources(validSources, atCountsTotal);
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());
500 ret.put(type, count);
511 }
catch (InterruptedException | ExecutionException ex) {
512 Throwable cause = ex.getCause();
514 logger.log(Level.SEVERE, cause.getMessage(), cause);
516 logger.log(Level.SEVERE, ex.getMessage(), ex);
520 if (sources != null) {
521 for (Pair<String, DataSource> source : sources.dataSources) {
522 dsCheckboxPanel.addElement(source.getKey(), null, source.getValue());
524 for (Map.Entry<ARTIFACT_TYPE, Long> entry : sources.artifactTypes.entrySet()) {
525 String dispName = entry.getKey().getDisplayName() +
" (" + entry.getValue() +
")";
527 Icon icon =
new ImageIcon(getClass().getResource(iconPath));
528 atCheckboxPanel.addElement(dispName, icon, entry.getKey());
532 GeoFilterPanel.this.firePropertyChange(INITPROPERTY,
false,
true);
Map< ARTIFACT_TYPE, Long > getGPSDataSources(SleuthkitCase sleuthkitCase, DataSource dataSource)
Sources(List< Pair< String, DataSource >> dataSources, Map< ARTIFACT_TYPE, Long > artifactTypes)
static String getIconFilePath(int typeID)
SleuthkitCase getSleuthkitCase()
static Case getCurrentCase()