mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-16 09:47:42 +00:00
First pass of the waypoint filtering
This commit is contained in:
parent
4a2e1f8b8e
commit
d154ac98b6
@ -7,3 +7,13 @@ RefreshPanel.closeButton.text=
|
|||||||
MapPanel.cordLabel.text=
|
MapPanel.cordLabel.text=
|
||||||
WaypointDetailPanel.closeButton.text=
|
WaypointDetailPanel.closeButton.text=
|
||||||
WaypointDetailPanel.imageLabel.text=
|
WaypointDetailPanel.imageLabel.text=
|
||||||
|
GeoFilterPanel.waypointSettings.border.title=
|
||||||
|
GeoFilterPanel.allButton.text=Show All
|
||||||
|
GeoFilterPanel.mostRecentButton.text=Hide items older than
|
||||||
|
GeoFilterPanel.applyButton.text=Apply
|
||||||
|
GeoFilterPanel.showWaypointsWOTSCheckBox.text=Show waypoints without time stamp
|
||||||
|
GeoFilterPanel.daysLabel.text=days
|
||||||
|
CheckBoxListPanel.titleLabel.text=jLabel1
|
||||||
|
CheckBoxListPanel.checkButton.text=Check All
|
||||||
|
CheckBoxListPanel.uncheckButton.text=Uncheck All
|
||||||
|
GeoFilterPanel.optionsLabel.text=Waypoints
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
CTL_OpenGeolocation=Geolocation
|
CTL_OpenGeolocation=Geolocation
|
||||||
CTL_GeolocationTopComponentAction=GeolocationTopComponent
|
CTL_GeolocationTopComponentAction=GeolocationTopComponent
|
||||||
CTL_GeolocationTopComponent=Geolocation
|
CTL_GeolocationTopComponent=Geolocation
|
||||||
|
GeoFilterPanel_DataSource_List_Title=Data Sources
|
||||||
|
GeoFilterPanel_empty_dataSource=Data Source list is empty.
|
||||||
GLTopComponent_initilzation_error=An error occurred during waypoint initilization. Geolocation data maybe incomplete.
|
GLTopComponent_initilzation_error=An error occurred during waypoint initilization. Geolocation data maybe incomplete.
|
||||||
GLTopComponent_name=Geolocation
|
GLTopComponent_name=Geolocation
|
||||||
MayWaypoint_ExternalViewer_label=Open in ExternalViewer
|
MayWaypoint_ExternalViewer_label=Open in ExternalViewer
|
||||||
@ -12,4 +14,14 @@ RefreshPanel.closeButton.text=
|
|||||||
MapPanel.cordLabel.text=
|
MapPanel.cordLabel.text=
|
||||||
WaypointDetailPanel.closeButton.text=
|
WaypointDetailPanel.closeButton.text=
|
||||||
WaypointDetailPanel.imageLabel.text=
|
WaypointDetailPanel.imageLabel.text=
|
||||||
|
GeoFilterPanel.waypointSettings.border.title=
|
||||||
|
GeoFilterPanel.allButton.text=Show All
|
||||||
|
GeoFilterPanel.mostRecentButton.text=Hide items older than
|
||||||
|
GeoFilterPanel.applyButton.text=Apply
|
||||||
|
GeoFilterPanel.showWaypointsWOTSCheckBox.text=Show waypoints without time stamp
|
||||||
|
GeoFilterPanel.daysLabel.text=days
|
||||||
|
CheckBoxListPanel.titleLabel.text=jLabel1
|
||||||
|
CheckBoxListPanel.checkButton.text=Check All
|
||||||
|
CheckBoxListPanel.uncheckButton.text=Uncheck All
|
||||||
|
GeoFilterPanel.optionsLabel.text=Waypoints
|
||||||
WaypointExtractAction_label=Extract Files(s)
|
WaypointExtractAction_label=Extract Files(s)
|
||||||
|
109
Core/src/org/sleuthkit/autopsy/geolocation/CheckBoxJList.java
Executable file
109
Core/src/org/sleuthkit/autopsy/geolocation/CheckBoxJList.java
Executable file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.geolocation;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import javax.swing.JCheckBox;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.ListCellRenderer;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JList that renders the list items as check boxes.
|
||||||
|
*/
|
||||||
|
final class CheckBoxJList<T extends CheckBoxJList.CheckboxListItem> extends JList<T> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple interface that must be implement for an object to be displayed as
|
||||||
|
* a checkbox in CheckBoxJList.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
interface CheckboxListItem {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the checkbox state.
|
||||||
|
*
|
||||||
|
* @return True if the check box should be checked
|
||||||
|
*/
|
||||||
|
boolean isChecked();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the state of the check box.
|
||||||
|
*
|
||||||
|
* @param checked
|
||||||
|
*/
|
||||||
|
void setChecked(boolean checked);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns String to display as the check box label
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new JCheckBoxList.
|
||||||
|
*/
|
||||||
|
CheckBoxJList() {
|
||||||
|
initalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do all of the UI initialization.
|
||||||
|
*/
|
||||||
|
private void initalize() {
|
||||||
|
setCellRenderer(new CellRenderer());
|
||||||
|
addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
int index = locationToIndex(e.getPoint());
|
||||||
|
if (index != -1) {
|
||||||
|
CheckBoxJList.CheckboxListItem element = getModel().getElementAt(index);
|
||||||
|
element.setChecked(!element.isChecked());
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ListCellRenderer that renders list elements as check boxes.
|
||||||
|
*/
|
||||||
|
class CellRenderer extends JCheckBox implements ListCellRenderer<CheckBoxJList.CheckboxListItem> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getListCellRendererComponent(
|
||||||
|
JList<? extends CheckBoxJList.CheckboxListItem> list, CheckBoxJList.CheckboxListItem value, int index,
|
||||||
|
boolean isSelected, boolean cellHasFocus) {
|
||||||
|
|
||||||
|
setBackground(list.getBackground());
|
||||||
|
setSelected(value.isChecked());
|
||||||
|
setText(value.getDisplayName());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
71
Core/src/org/sleuthkit/autopsy/geolocation/CheckBoxListPanel.form
Executable file
71
Core/src/org/sleuthkit/autopsy/geolocation/CheckBoxListPanel.form
Executable file
@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JLabel" name="titleLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="CheckBoxListPanel.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="uncheckButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="CheckBoxListPanel.uncheckButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="uncheckButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="9" anchor="12" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="checkButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="CheckBoxListPanel.checkButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="checkButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="2" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="12" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="scrollPane">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="1" gridWidth="3" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="0" insetsBottom="9" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
234
Core/src/org/sleuthkit/autopsy/geolocation/CheckBoxListPanel.java
Executable file
234
Core/src/org/sleuthkit/autopsy/geolocation/CheckBoxListPanel.java
Executable file
@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.geolocation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.swing.DefaultListModel;
|
||||||
|
import javax.swing.Icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A panel for showing Content objects in a check box list.
|
||||||
|
*/
|
||||||
|
final class CheckBoxListPanel<T> extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final DefaultListModel<ObjectCheckBox<T>> model = new DefaultListModel<>();
|
||||||
|
private final CheckBoxJList<ObjectCheckBox<T>> checkboxList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new CheckboxFilterPanel
|
||||||
|
*/
|
||||||
|
CheckBoxListPanel() {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
checkboxList = new CheckBoxJList<>();
|
||||||
|
checkboxList.setModel(model);
|
||||||
|
scrollPane.setViewportView(checkboxList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new element to the check box list.
|
||||||
|
*
|
||||||
|
* @param displayName display name for the checkbox
|
||||||
|
* @param obj Object that the checkbox represents
|
||||||
|
*/
|
||||||
|
void addElement(String displayName, T obj) {
|
||||||
|
model.addElement(new ObjectCheckBox<>(displayName, true, obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all of the selected elements.
|
||||||
|
*
|
||||||
|
* @return List of selected elements.
|
||||||
|
*/
|
||||||
|
List<T> getSelectedElements() {
|
||||||
|
List<T> selectedElements = new ArrayList<>();
|
||||||
|
Enumeration<ObjectCheckBox<T>> elements = model.elements();
|
||||||
|
|
||||||
|
while (elements.hasMoreElements()) {
|
||||||
|
ObjectCheckBox<T> element = elements.nextElement();
|
||||||
|
if (element.isChecked()) {
|
||||||
|
selectedElements.add(element.getObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectedElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the selection state of the all the check boxes in the list.
|
||||||
|
*
|
||||||
|
* @param selected True to check the boxes, false to unchecked
|
||||||
|
*/
|
||||||
|
void setSetAllSelected(boolean selected) {
|
||||||
|
Enumeration<ObjectCheckBox<T>> enumeration = model.elements();
|
||||||
|
while (enumeration.hasMoreElements()) {
|
||||||
|
ObjectCheckBox<T> element = enumeration.nextElement();
|
||||||
|
element.setChecked(selected);
|
||||||
|
checkboxList.repaint();
|
||||||
|
checkboxList.revalidate();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the panel title.
|
||||||
|
*
|
||||||
|
* @param title Panel title or null for no title.
|
||||||
|
*/
|
||||||
|
void setPanelTitle(String title) {
|
||||||
|
titleLabel.setText(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the panel title icon.
|
||||||
|
*
|
||||||
|
* @param icon Icon to set or null for no icon
|
||||||
|
*/
|
||||||
|
void setPanelTitleIcon(Icon icon) {
|
||||||
|
titleLabel.setIcon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
java.awt.GridBagConstraints gridBagConstraints;
|
||||||
|
|
||||||
|
titleLabel = new javax.swing.JLabel();
|
||||||
|
uncheckButton = new javax.swing.JButton();
|
||||||
|
checkButton = new javax.swing.JButton();
|
||||||
|
scrollPane = new javax.swing.JScrollPane();
|
||||||
|
|
||||||
|
setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(CheckBoxListPanel.class, "CheckBoxListPanel.titleLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.gridwidth = 3;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
add(titleLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(uncheckButton, org.openide.util.NbBundle.getMessage(CheckBoxListPanel.class, "CheckBoxListPanel.uncheckButton.text")); // NOI18N
|
||||||
|
uncheckButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
uncheckButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 9);
|
||||||
|
add(uncheckButton, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(checkButton, org.openide.util.NbBundle.getMessage(CheckBoxListPanel.class, "CheckBoxListPanel.checkButton.text")); // NOI18N
|
||||||
|
checkButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
checkButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 2;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
|
||||||
|
add(checkButton, gridBagConstraints);
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.gridwidth = 3;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.weighty = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 0, 9, 0);
|
||||||
|
add(scrollPane, gridBagConstraints);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void uncheckButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_uncheckButtonActionPerformed
|
||||||
|
setSetAllSelected(false);
|
||||||
|
}//GEN-LAST:event_uncheckButtonActionPerformed
|
||||||
|
|
||||||
|
private void checkButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkButtonActionPerformed
|
||||||
|
setSetAllSelected(true);
|
||||||
|
}//GEN-LAST:event_checkButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JButton checkButton;
|
||||||
|
private javax.swing.JScrollPane scrollPane;
|
||||||
|
private javax.swing.JLabel titleLabel;
|
||||||
|
private javax.swing.JButton uncheckButton;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around T that implements CheckboxListItem
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
final class ObjectCheckBox<T> implements CheckBoxJList.CheckboxListItem {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final T object;
|
||||||
|
private final String displayName;
|
||||||
|
private boolean checked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ObjectCheckBox
|
||||||
|
*
|
||||||
|
* @param displayName String to show as the check box label
|
||||||
|
* @param initialState Sets the initial state of the check box
|
||||||
|
* @param object Object that the check box represents.
|
||||||
|
*/
|
||||||
|
ObjectCheckBox(String displayName, boolean initialState, T object) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.object = object;
|
||||||
|
this.checked = initialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
T getObject() {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChecked() {
|
||||||
|
return checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setChecked(boolean checked) {
|
||||||
|
this.checked = checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
168
Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.form
Executable file
168
Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.form
Executable file
@ -0,0 +1,168 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<NonVisualComponents>
|
||||||
|
<Component class="javax.swing.ButtonGroup" name="buttonGroup">
|
||||||
|
</Component>
|
||||||
|
</NonVisualComponents>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,3,32"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="waypointSettings">
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
|
<TitledBorder title="">
|
||||||
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeoFilterPanel.waypointSettings.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</TitledBorder>
|
||||||
|
</Border>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="15" insetsBottom="9" insetsRight="15" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JRadioButton" name="allButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||||
|
<ComponentRef name="buttonGroup"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="selected" type="boolean" value="true"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeoFilterPanel.allButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="allButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="4" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JRadioButton" name="mostRecentButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||||
|
<ComponentRef name="buttonGroup"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeoFilterPanel.mostRecentButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="mostRecentButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="1" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="showWaypointsWOTSCheckBox">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeoFilterPanel.showWaypointsWOTSCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="2" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="30" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JSpinner" name="daysSpinner">
|
||||||
|
<Properties>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new javax.swing.JSpinner(numberModel)"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="daysLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeoFilterPanel.daysLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="3" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="17" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Container class="javax.swing.JPanel" name="buttonPanel">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="15" insetsBottom="0" insetsRight="15" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JButton" name="applyButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
|
<Image iconType="3" name="/org/sleuthkit/autopsy/geolocation/images/tick.png"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeoFilterPanel.applyButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="12" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.JLabel" name="optionsLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||||
|
<Image iconType="3" name="/org/sleuthkit/autopsy/geolocation/images/blueGeo16.png"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeoFilterPanel.optionsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="15" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
360
Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java
Executable file
360
Core/src/org/sleuthkit/autopsy/geolocation/GeoFilterPanel.java
Executable file
@ -0,0 +1,360 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.geolocation;
|
||||||
|
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Panel to display the filter options for geolocation waypoints.
|
||||||
|
*/
|
||||||
|
class GeoFilterPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final Logger logger = Logger.getLogger(GeoFilterPanel.class.getName());
|
||||||
|
|
||||||
|
private final SpinnerNumberModel numberModel;
|
||||||
|
private final CheckBoxListPanel<DataSource> checkboxPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new GeoFilterPanel
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"GeoFilterPanel_DataSource_List_Title=Data Sources"
|
||||||
|
})
|
||||||
|
GeoFilterPanel() {
|
||||||
|
// numberModel is used in initComponents
|
||||||
|
numberModel = new SpinnerNumberModel(10, 1, Integer.MAX_VALUE, 1);
|
||||||
|
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
// The gui builder cannot handle using CheckBoxListPanel due to its
|
||||||
|
// use of generics so we will initalize it here.
|
||||||
|
checkboxPanel = new CheckBoxListPanel<>();
|
||||||
|
checkboxPanel.setPanelTitle(Bundle.GeoFilterPanel_DataSource_List_Title());
|
||||||
|
checkboxPanel.setPanelTitleIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/image.png")));
|
||||||
|
checkboxPanel.setSetAllSelected(true);
|
||||||
|
|
||||||
|
GridBagConstraints gridBagConstraints = new GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 3;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.weighty = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 15, 0, 15);
|
||||||
|
add(checkboxPanel, gridBagConstraints);
|
||||||
|
|
||||||
|
try {
|
||||||
|
initCheckboxList();
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to initialize the CheckboxListPane", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an actionListener to listen for the filter apply action
|
||||||
|
*
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
void addActionListener(ActionListener listener) {
|
||||||
|
applyButton.addActionListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the selected filter values.
|
||||||
|
*
|
||||||
|
* @return A GeoFilter object with the user selected filter values
|
||||||
|
*
|
||||||
|
* @throws GeoLocationUIException
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"GeoFilterPanel_empty_dataSource=Data Source list is empty."
|
||||||
|
})
|
||||||
|
GeoFilter getFilterState() throws GeoLocationUIException {
|
||||||
|
boolean showAll = allButton.isSelected();
|
||||||
|
boolean withTimeStamp = showWaypointsWOTSCheckBox.isSelected();
|
||||||
|
int dayCnt = numberModel.getNumber().intValue();
|
||||||
|
|
||||||
|
List<DataSource> dataSources = checkboxPanel.getSelectedElements();
|
||||||
|
|
||||||
|
if (dataSources.isEmpty()) {
|
||||||
|
throw new GeoLocationUIException(Bundle.GeoFilterPanel_empty_dataSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new GeoFilter(showAll, withTimeStamp, dayCnt, dataSources);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the checkbox list panel
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
private void initCheckboxList() throws TskCoreException {
|
||||||
|
final SleuthkitCase sleuthkitCase = Case.getCurrentCase().getSleuthkitCase();
|
||||||
|
|
||||||
|
for (DataSource dataSource : sleuthkitCase.getDataSources()) {
|
||||||
|
String dsName = sleuthkitCase.getContentById(dataSource.getId()).getName();
|
||||||
|
checkboxPanel.addElement(dsName, dataSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Based on the state of mostRecent radio button Change the state of the cnt
|
||||||
|
* spinner and the time stamp checkbox.
|
||||||
|
*/
|
||||||
|
private void updateWaypointOptions() {
|
||||||
|
boolean selected = mostRecentButton.isSelected();
|
||||||
|
showWaypointsWOTSCheckBox.setEnabled(selected);
|
||||||
|
daysSpinner.setEnabled(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
java.awt.GridBagConstraints gridBagConstraints;
|
||||||
|
|
||||||
|
buttonGroup = new javax.swing.ButtonGroup();
|
||||||
|
waypointSettings = new javax.swing.JPanel();
|
||||||
|
allButton = new javax.swing.JRadioButton();
|
||||||
|
mostRecentButton = new javax.swing.JRadioButton();
|
||||||
|
showWaypointsWOTSCheckBox = new javax.swing.JCheckBox();
|
||||||
|
daysSpinner = new javax.swing.JSpinner(numberModel);
|
||||||
|
javax.swing.JLabel daysLabel = new javax.swing.JLabel();
|
||||||
|
buttonPanel = new javax.swing.JPanel();
|
||||||
|
applyButton = new javax.swing.JButton();
|
||||||
|
javax.swing.JLabel optionsLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
|
setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
waypointSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.waypointSettings.border.title"))); // NOI18N
|
||||||
|
waypointSettings.setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
buttonGroup.add(allButton);
|
||||||
|
allButton.setSelected(true);
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(allButton, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.allButton.text")); // NOI18N
|
||||||
|
allButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
allButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.gridwidth = 4;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
waypointSettings.add(allButton, gridBagConstraints);
|
||||||
|
|
||||||
|
buttonGroup.add(mostRecentButton);
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(mostRecentButton, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.mostRecentButton.text")); // NOI18N
|
||||||
|
mostRecentButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
mostRecentButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.gridwidth = 2;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(9, 0, 0, 0);
|
||||||
|
waypointSettings.add(mostRecentButton, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(showWaypointsWOTSCheckBox, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.showWaypointsWOTSCheckBox.text")); // NOI18N
|
||||||
|
showWaypointsWOTSCheckBox.setEnabled(false);
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.gridwidth = 3;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 30, 0, 0);
|
||||||
|
waypointSettings.add(showWaypointsWOTSCheckBox, gridBagConstraints);
|
||||||
|
|
||||||
|
daysSpinner.setEnabled(false);
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 2;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(9, 0, 0, 0);
|
||||||
|
waypointSettings.add(daysSpinner, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(daysLabel, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.daysLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 3;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(9, 5, 0, 0);
|
||||||
|
waypointSettings.add(daysLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 2;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 15, 9, 15);
|
||||||
|
add(waypointSettings, gridBagConstraints);
|
||||||
|
|
||||||
|
buttonPanel.setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
applyButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/geolocation/images/tick.png"))); // NOI18N
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(applyButton, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.applyButton.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
buttonPanel.add(applyButton, gridBagConstraints);
|
||||||
|
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(9, 15, 0, 15);
|
||||||
|
add(buttonPanel, gridBagConstraints);
|
||||||
|
|
||||||
|
optionsLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/geolocation/images/blueGeo16.png"))); // NOI18N
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(optionsLabel, org.openide.util.NbBundle.getMessage(GeoFilterPanel.class, "GeoFilterPanel.optionsLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 15, 0, 0);
|
||||||
|
add(optionsLabel, gridBagConstraints);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void allButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allButtonActionPerformed
|
||||||
|
updateWaypointOptions();
|
||||||
|
}//GEN-LAST:event_allButtonActionPerformed
|
||||||
|
|
||||||
|
private void mostRecentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mostRecentButtonActionPerformed
|
||||||
|
updateWaypointOptions();
|
||||||
|
}//GEN-LAST:event_mostRecentButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JRadioButton allButton;
|
||||||
|
private javax.swing.JButton applyButton;
|
||||||
|
private javax.swing.ButtonGroup buttonGroup;
|
||||||
|
private javax.swing.JPanel buttonPanel;
|
||||||
|
private javax.swing.JSpinner daysSpinner;
|
||||||
|
private javax.swing.JRadioButton mostRecentButton;
|
||||||
|
private javax.swing.JCheckBox showWaypointsWOTSCheckBox;
|
||||||
|
private javax.swing.JPanel waypointSettings;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to store the values of the Geolocation user set filter parameters
|
||||||
|
*/
|
||||||
|
final class GeoFilter {
|
||||||
|
|
||||||
|
private final boolean showAll;
|
||||||
|
private final boolean showWithoutTimeStamp;
|
||||||
|
private final int mostRecentNumDays;
|
||||||
|
private final List<DataSource> dataSources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a Geolocation filter. showAll and mostRecentNumDays are
|
||||||
|
* exclusive filters, ie they cannot be used together.
|
||||||
|
*
|
||||||
|
* withoutTimeStamp is only applicable if mostRecentNumDays is true.
|
||||||
|
*
|
||||||
|
* When using the filters "most recent days" means to include waypoints
|
||||||
|
* for the numbers of days after the most recent waypoint, not the
|
||||||
|
* current date.
|
||||||
|
*
|
||||||
|
* @param showAll True if all waypoints should be shown
|
||||||
|
* @param withoutTimeStamp True to show waypoints without timeStamps,
|
||||||
|
* this filter is only applicable if
|
||||||
|
* mostRecentNumDays is true
|
||||||
|
* @param mostRecentNumDays Show Waypoint for the most recent given
|
||||||
|
* number of days. This parameter is ignored if
|
||||||
|
* showAll is true.
|
||||||
|
* @param dataSources A list of dataSources to filter waypoint
|
||||||
|
* for.
|
||||||
|
*/
|
||||||
|
GeoFilter(boolean showAll, boolean withoutTimeStamp, int mostRecentNumDays, List<DataSource> dataSources) {
|
||||||
|
this.showAll = showAll;
|
||||||
|
this.showWithoutTimeStamp = withoutTimeStamp;
|
||||||
|
this.mostRecentNumDays = mostRecentNumDays;
|
||||||
|
this.dataSources = dataSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not to show all waypoints.
|
||||||
|
*
|
||||||
|
* @return True if all waypoints should be shown.
|
||||||
|
*/
|
||||||
|
boolean showAll() {
|
||||||
|
return showAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not to include waypoints with time stamps.
|
||||||
|
*
|
||||||
|
* This filter is only applicable if "showAll" is true.
|
||||||
|
*
|
||||||
|
* @return True if waypoints with time stamps should be shown.
|
||||||
|
*/
|
||||||
|
boolean showWithoutTimeStamp() {
|
||||||
|
return showWithoutTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of most recent days to show waypoints for. This
|
||||||
|
* value should be ignored if showAll is true.
|
||||||
|
*
|
||||||
|
* @return The number of most recent days to show waypoints for
|
||||||
|
*/
|
||||||
|
int getMostRecentNumDays() {
|
||||||
|
return mostRecentNumDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of data sources to filter the waypoints by, or null if
|
||||||
|
* all datasources should be include.
|
||||||
|
*
|
||||||
|
* @return A list of dataSources or null if all dataSources should be
|
||||||
|
* included.
|
||||||
|
*/
|
||||||
|
List<DataSource> getDataSources() {
|
||||||
|
return Collections.unmodifiableList(dataSources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
Core/src/org/sleuthkit/autopsy/geolocation/GeoLocationUIException.java
Executable file
46
Core/src/org/sleuthkit/autopsy/geolocation/GeoLocationUIException.java
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.geolocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* An exception call for Exceptions that occure in the geolocation dialog.
|
||||||
|
*/
|
||||||
|
public class GeoLocationUIException extends Exception{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create exception containing the error message
|
||||||
|
*
|
||||||
|
* @param msg the message
|
||||||
|
*/
|
||||||
|
public GeoLocationUIException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create exception containing the error message and cause exception
|
||||||
|
*
|
||||||
|
* @param msg the message
|
||||||
|
* @param ex cause exception
|
||||||
|
*/
|
||||||
|
public GeoLocationUIException(String msg, Exception ex) {
|
||||||
|
super(msg, ex);
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@
|
|||||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||||
@ -23,6 +24,17 @@
|
|||||||
</Constraints>
|
</Constraints>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="org.sleuthkit.autopsy.geolocation.HidingPane" name="filterPane">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||||
|
<BorderConstraints direction="Before"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
@ -27,6 +27,7 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.windows.RetainLocation;
|
import org.openide.windows.RetainLocation;
|
||||||
@ -37,6 +38,11 @@ import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE;
|
|||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
|
import org.sleuthkit.autopsy.geolocation.GeoFilterPanel.GeoFilter;
|
||||||
|
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
|
||||||
|
import org.sleuthkit.autopsy.geolocation.datamodel.Waypoint;
|
||||||
|
import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder;
|
||||||
|
import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder.WaypointFilterQueryCallBack;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
@ -59,6 +65,7 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(DATA_ADDED);
|
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(DATA_ADDED);
|
||||||
|
|
||||||
private final PropertyChangeListener ingestListener;
|
private final PropertyChangeListener ingestListener;
|
||||||
|
private final GeoFilterPanel geoFilterPanel;
|
||||||
|
|
||||||
final RefreshPanel refreshPanel = new RefreshPanel();
|
final RefreshPanel refreshPanel = new RefreshPanel();
|
||||||
|
|
||||||
@ -109,6 +116,16 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
showRefreshPanel(false);
|
showRefreshPanel(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
geoFilterPanel = new GeoFilterPanel();
|
||||||
|
filterPane.setPanel(geoFilterPanel);
|
||||||
|
geoFilterPanel.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
filterWaypoints();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -151,14 +168,12 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Use a SwingWorker thread to get a list of waypoints.
|
* Use a SwingWorker thread to get a list of waypoints.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private void initWaypoints() {
|
private void initWaypoints() {
|
||||||
SwingWorker<List<MapWaypoint>, MapWaypoint> worker = new SwingWorker<List<MapWaypoint>, MapWaypoint>() {
|
SwingWorker<List<MapWaypoint>, MapWaypoint> worker = new SwingWorker<List<MapWaypoint>, MapWaypoint>() {
|
||||||
@Override
|
@Override
|
||||||
protected List<MapWaypoint> doInBackground() throws Exception {
|
protected List<MapWaypoint> doInBackground() throws Exception {
|
||||||
Case currentCase = Case.getCurrentCaseThrows();
|
Case currentCase = Case.getCurrentCaseThrows();
|
||||||
|
|
||||||
return MapWaypoint.getWaypoints(currentCase.getSleuthkitCase());
|
return MapWaypoint.getWaypoints(currentCase.getSleuthkitCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +204,59 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
worker.execute();
|
worker.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the list of waypoints based on the user selections in the filter
|
||||||
|
* pane.
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"GeoTopComponent_no_waypoints_returned_mgs=Applied filter failed to find waypoints that matched criteria.\nRevise filter options and try again.",
|
||||||
|
"GeoTopComponent_no_waypoints_returned_Title=No Waypoints Found",
|
||||||
|
"GeoTopComponent_filter_exception_msg=Exception occured during waypoint filtering.",
|
||||||
|
"GeoTopComponent_filter_exception_Title=Filter Failure",
|
||||||
|
"GeoTopComponent_filer_data_invalid_msg=Unable to run waypoint filter.\nPlease select one or more data sources.",
|
||||||
|
"GeoTopComponent_filer_data_invalid_Title=Filter Failure"
|
||||||
|
})
|
||||||
|
private void filterWaypoints() {
|
||||||
|
GeoFilter filters;
|
||||||
|
|
||||||
|
// Show a warning message if the user has not selected a data source
|
||||||
|
try {
|
||||||
|
filters = geoFilterPanel.getFilterState();
|
||||||
|
} catch (GeoLocationUIException ex) {
|
||||||
|
MessageNotifyUtil.Notify.info(
|
||||||
|
Bundle.GeoTopComponent_filer_data_invalid_Title(),
|
||||||
|
Bundle.GeoTopComponent_filer_data_invalid_msg());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
Case currentCase = Case.getCurrentCase();
|
||||||
|
try {
|
||||||
|
WaypointBuilder.getAllWaypoints(currentCase.getSleuthkitCase(), filters.getDataSources(), filters.showAll(), filters.getMostRecentNumDays(), filters.showWithoutTimeStamp(), new WaypointFilterQueryCallBack() {
|
||||||
|
@Override
|
||||||
|
public void process(List<Waypoint> waypoints) {
|
||||||
|
// If the list is empty, tell the user and do not change
|
||||||
|
// the visible waypoints.
|
||||||
|
if (waypoints == null || waypoints.isEmpty()) {
|
||||||
|
MessageNotifyUtil.Notify.info(
|
||||||
|
Bundle.GeoTopComponent_no_waypoints_returned_Title(),
|
||||||
|
Bundle.GeoTopComponent_no_waypoints_returned());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mapPanel.setWaypoints(MapWaypoint.getWaypoints(waypoints));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (GeoLocationDataException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to filter waypoints.", ex);
|
||||||
|
MessageNotifyUtil.Notify.error(
|
||||||
|
Bundle.GeoTopComponent_filter_exception_Title(),
|
||||||
|
Bundle.GeoTopComponent_filter_exception_msg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -199,13 +267,18 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
mapPanel = new org.sleuthkit.autopsy.geolocation.MapPanel();
|
mapPanel = new org.sleuthkit.autopsy.geolocation.MapPanel();
|
||||||
|
filterPane = new org.sleuthkit.autopsy.geolocation.HidingPane();
|
||||||
|
|
||||||
setLayout(new java.awt.BorderLayout());
|
setLayout(new java.awt.BorderLayout());
|
||||||
|
|
||||||
|
mapPanel.add(filterPane, java.awt.BorderLayout.LINE_START);
|
||||||
|
|
||||||
add(mapPanel, java.awt.BorderLayout.CENTER);
|
add(mapPanel, java.awt.BorderLayout.CENTER);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private org.sleuthkit.autopsy.geolocation.HidingPane filterPane;
|
||||||
private org.sleuthkit.autopsy.geolocation.MapPanel mapPanel;
|
private org.sleuthkit.autopsy.geolocation.MapPanel mapPanel;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
}
|
}
|
||||||
|
120
Core/src/org/sleuthkit/autopsy/geolocation/HidingPane.java
Executable file
120
Core/src/org/sleuthkit/autopsy/geolocation/HidingPane.java
Executable file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.geolocation;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTabbedPane;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* A JTabbed pane with one tab that says "Filters". When the user clicks on that
|
||||||
|
* table the content of the tab will be hidden.
|
||||||
|
*
|
||||||
|
* The content pane provides support for scrolling.
|
||||||
|
*/
|
||||||
|
public final class HidingPane extends JTabbedPane {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final JScrollPane scrollPane;
|
||||||
|
private final JPanel panel;
|
||||||
|
private final JLabel tabLabel;
|
||||||
|
|
||||||
|
private boolean panelVisible = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new HidingFilterPane
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"HidingPane_default_title=Filters"
|
||||||
|
})
|
||||||
|
public HidingPane() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
scrollPane = new JScrollPane();
|
||||||
|
panel = new JPanel();
|
||||||
|
panel.setLayout(new BorderLayout());
|
||||||
|
panel.add(scrollPane, BorderLayout.CENTER);
|
||||||
|
tabLabel = new JLabel(Bundle.HidingPane_default_title());
|
||||||
|
tabLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/geolocation/images/funnel.png")));
|
||||||
|
tabLabel.setUI(new VerticalLabelUI(true));
|
||||||
|
tabLabel.setOpaque(false);
|
||||||
|
Font font = tabLabel.getFont().deriveFont(18).deriveFont(Font.BOLD);
|
||||||
|
tabLabel.setFont(font);
|
||||||
|
|
||||||
|
addTab(null, panel);
|
||||||
|
setTabComponentAt(0, tabLabel);
|
||||||
|
|
||||||
|
this.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent evt) {
|
||||||
|
handleMouseClick(evt.getPoint());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setTabPlacement(JTabbedPane.RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the title of the tab.
|
||||||
|
*
|
||||||
|
* @param title
|
||||||
|
*/
|
||||||
|
void setTitle(String title) {
|
||||||
|
tabLabel.setText(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the icon that appears on the tab.
|
||||||
|
*
|
||||||
|
* @param icon
|
||||||
|
*/
|
||||||
|
void setIcon(Icon icon) {
|
||||||
|
tabLabel.setIcon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the content for this panel.
|
||||||
|
*
|
||||||
|
* @param panel A panel to display in the tabbed pane.
|
||||||
|
*/
|
||||||
|
void setPanel(JPanel panel) {
|
||||||
|
scrollPane.setViewportView(panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the mouse click.
|
||||||
|
*
|
||||||
|
* @param point
|
||||||
|
*/
|
||||||
|
private void handleMouseClick(Point point) {
|
||||||
|
int index = indexAtLocation(point.x, point.y);
|
||||||
|
|
||||||
|
if(index == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(panelVisible) {
|
||||||
|
panel.removeAll();
|
||||||
|
panel.revalidate();
|
||||||
|
panelVisible = false;
|
||||||
|
} else {
|
||||||
|
panel.add(scrollPane, BorderLayout.CENTER);
|
||||||
|
panel.revalidate();
|
||||||
|
panelVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -56,7 +56,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
/**
|
/**
|
||||||
* The map panel. This panel contains the jxmapviewer MapViewer
|
* The map panel. This panel contains the jxmapviewer MapViewer
|
||||||
*/
|
*/
|
||||||
final class MapPanel extends javax.swing.JPanel {
|
final public class MapPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(MapPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(MapPanel.class.getName());
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ final class MapPanel extends javax.swing.JPanel {
|
|||||||
/**
|
/**
|
||||||
* Creates new form MapPanel
|
* Creates new form MapPanel
|
||||||
*/
|
*/
|
||||||
MapPanel() {
|
public MapPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
initMap();
|
initMap();
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
|
|||||||
import org.sleuthkit.autopsy.geolocation.datamodel.Route;
|
import org.sleuthkit.autopsy.geolocation.datamodel.Route;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.autopsy.geolocation.datamodel.Waypoint;
|
import org.sleuthkit.autopsy.geolocation.datamodel.Waypoint;
|
||||||
|
import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder;
|
||||||
import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction;
|
import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
@ -79,7 +80,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
|||||||
* @throws GeoLocationDataException
|
* @throws GeoLocationDataException
|
||||||
*/
|
*/
|
||||||
static List<MapWaypoint> getWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
static List<MapWaypoint> getWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||||
List<Waypoint> points = Waypoint.getAllWaypoints(skCase);
|
List<Waypoint> points = WaypointBuilder.getAllWaypoints(skCase);
|
||||||
|
|
||||||
List<Route> routes = Route.getRoutes(skCase);
|
List<Route> routes = Route.getRoutes(skCase);
|
||||||
for (Route route : routes) {
|
for (Route route : routes) {
|
||||||
@ -95,6 +96,28 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
|||||||
return mapPoints;
|
return mapPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of of MapWaypoint objects for the given list of
|
||||||
|
* datamodel.Waypoint objects.
|
||||||
|
*
|
||||||
|
* @param dmWaypoints
|
||||||
|
*
|
||||||
|
* @return List of MapWaypoint objects. List will be empty if dmWaypoints was
|
||||||
|
* empty or null.
|
||||||
|
*/
|
||||||
|
static List<MapWaypoint> getWaypoints(List<Waypoint> dmWaypoints) {
|
||||||
|
List<MapWaypoint> mapPoints = new ArrayList<>();
|
||||||
|
|
||||||
|
if (dmWaypoints != null) {
|
||||||
|
|
||||||
|
for (Waypoint point : dmWaypoints) {
|
||||||
|
mapPoints.add(new MapWaypoint(point));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a MapWaypoint without a reference to the datamodel waypoint.
|
* Returns a MapWaypoint without a reference to the datamodel waypoint.
|
||||||
*
|
*
|
||||||
|
110
Core/src/org/sleuthkit/autopsy/geolocation/VerticalLabelUI.java
Executable file
110
Core/src/org/sleuthkit/autopsy/geolocation/VerticalLabelUI.java
Executable file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.geolocation;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.plaf.basic.BasicLabelUI;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is an overload of BasicLabelUI to draw labels vertically.
|
||||||
|
*
|
||||||
|
* This code was found at:
|
||||||
|
* https://tech.chitgoks.com/2009/11/13/rotate-jlabel-vertically/
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
final class VerticalLabelUI extends BasicLabelUI {
|
||||||
|
|
||||||
|
private static final Rectangle paintIconR = new Rectangle();
|
||||||
|
private static final Rectangle paintTextR = new Rectangle();
|
||||||
|
private static final Rectangle paintViewR = new Rectangle();
|
||||||
|
private static Insets paintViewInsets = new Insets(0, 0, 0, 0);
|
||||||
|
|
||||||
|
static {
|
||||||
|
labelUI = new VerticalLabelUI(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean clockwise;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new VerticalLabelUI
|
||||||
|
* @param clockwise
|
||||||
|
*/
|
||||||
|
VerticalLabelUI(boolean clockwise) {
|
||||||
|
super();
|
||||||
|
this.clockwise = clockwise;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize(JComponent c) {
|
||||||
|
Dimension dim = super.getPreferredSize(c);
|
||||||
|
return new Dimension( dim.height, dim.width );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint(Graphics g, JComponent c) {
|
||||||
|
JLabel label = (JLabel)c;
|
||||||
|
String text = label.getText();
|
||||||
|
Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();
|
||||||
|
|
||||||
|
if ((icon == null) && (text == null)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FontMetrics fm = g.getFontMetrics();
|
||||||
|
paintViewInsets = c.getInsets(paintViewInsets);
|
||||||
|
|
||||||
|
paintViewR.x = paintViewInsets.left;
|
||||||
|
paintViewR.y = paintViewInsets.top;
|
||||||
|
|
||||||
|
// Use inverted height & width
|
||||||
|
paintViewR.height = c.getWidth() - (paintViewInsets.left + paintViewInsets.right);
|
||||||
|
paintViewR.width = c.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);
|
||||||
|
|
||||||
|
paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
|
||||||
|
paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
|
||||||
|
|
||||||
|
String clippedText = layoutCL(label, fm, text, icon, paintViewR, paintIconR, paintTextR);
|
||||||
|
|
||||||
|
Graphics2D g2 = (Graphics2D) g;
|
||||||
|
AffineTransform tr = g2.getTransform();
|
||||||
|
if (clockwise) {
|
||||||
|
g2.rotate( Math.PI / 2 );
|
||||||
|
g2.translate( 0, - c.getWidth() );
|
||||||
|
} else {
|
||||||
|
g2.rotate( - Math.PI / 2 );
|
||||||
|
g2.translate( - c.getHeight(), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icon != null) {
|
||||||
|
icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text != null) {
|
||||||
|
int textX = paintTextR.x;
|
||||||
|
int textY = paintTextR.y + fm.getAscent();
|
||||||
|
|
||||||
|
if (label.isEnabled()) {
|
||||||
|
paintEnabledText(label, g, clippedText, textX, textY);
|
||||||
|
} else {
|
||||||
|
paintDisabledText(label, g, clippedText, textX, textY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g2.setTransform( tr );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -263,186 +263,6 @@ public class Waypoint {
|
|||||||
return attributeMap;
|
return attributeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of Waypoints for the artifacts with geolocation
|
|
||||||
* information.
|
|
||||||
*
|
|
||||||
* List will include artifacts of type: TSK_GPS_TRACKPOINT TSK_GPS_SEARCH
|
|
||||||
* TSK_GPS_LAST_KNOWN_LOCATION TSK_GPS_BOOKMARK TSK_METADATA_EXIF
|
|
||||||
*
|
|
||||||
* @param skCase Currently open SleuthkitCase
|
|
||||||
*
|
|
||||||
* @return List of Waypoint
|
|
||||||
*
|
|
||||||
* @throws GeoLocationDataException
|
|
||||||
*/
|
|
||||||
public static List<Waypoint> getAllWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
|
||||||
List<Waypoint> points = new ArrayList<>();
|
|
||||||
|
|
||||||
points.addAll(getTrackpointWaypoints(skCase));
|
|
||||||
points.addAll(getEXIFWaypoints(skCase));
|
|
||||||
points.addAll(getSearchWaypoints(skCase));
|
|
||||||
points.addAll(getLastKnownWaypoints(skCase));
|
|
||||||
points.addAll(getBookmarkWaypoints(skCase));
|
|
||||||
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of Waypoints for TSK_GPS_TRACKPOINT artifacts.
|
|
||||||
*
|
|
||||||
* @param skCase Currently open SleuthkitCase
|
|
||||||
*
|
|
||||||
* @return List of Waypoint
|
|
||||||
*
|
|
||||||
* @throws GeoLocationDataException
|
|
||||||
*/
|
|
||||||
public static List<Waypoint> getTrackpointWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
|
||||||
List<BlackboardArtifact> artifacts = null;
|
|
||||||
try {
|
|
||||||
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_TRACKPOINT", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Waypoint> points = new ArrayList<>();
|
|
||||||
for (BlackboardArtifact artifact : artifacts) {
|
|
||||||
try {
|
|
||||||
Waypoint point = new TrackpointWaypoint(artifact);
|
|
||||||
points.add(point);
|
|
||||||
} catch (GeoLocationDataException ex) {
|
|
||||||
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_TRACKPOINT artifactID: %d", artifact.getArtifactID()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of Waypoints for TSK_METADATA_EXIF artifacts.
|
|
||||||
*
|
|
||||||
* @param skCase Currently open SleuthkitCase
|
|
||||||
*
|
|
||||||
* @return List of Waypoint
|
|
||||||
*
|
|
||||||
* @throws GeoLocationDataException
|
|
||||||
*/
|
|
||||||
static public List<Waypoint> getEXIFWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
|
||||||
List<BlackboardArtifact> artifacts = null;
|
|
||||||
try {
|
|
||||||
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_LAST_KNOWN_LOCATION", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Waypoint> points = new ArrayList<>();
|
|
||||||
if (artifacts != null) {
|
|
||||||
for (BlackboardArtifact artifact : artifacts) {
|
|
||||||
try {
|
|
||||||
Waypoint point = new EXIFWaypoint(artifact);
|
|
||||||
points.add(point);
|
|
||||||
} catch (GeoLocationDataException ex) {
|
|
||||||
// I am a little relucant to log this error because I suspect
|
|
||||||
// this will happen more often than not. It is valid for
|
|
||||||
// METADAT_EXIF to not have longitude and latitude
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of Waypoints for TSK_GPS_SEARCH artifacts.
|
|
||||||
*
|
|
||||||
* @param skCase Currently open SleuthkitCase
|
|
||||||
*
|
|
||||||
* @return List of Waypoint
|
|
||||||
*
|
|
||||||
* @throws GeoLocationDataException
|
|
||||||
*/
|
|
||||||
public static List<Waypoint> getSearchWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
|
||||||
List<BlackboardArtifact> artifacts = null;
|
|
||||||
try {
|
|
||||||
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_SEARCH", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Waypoint> points = new ArrayList<>();
|
|
||||||
if (artifacts != null) {
|
|
||||||
for (BlackboardArtifact artifact : artifacts) {
|
|
||||||
try {
|
|
||||||
Waypoint point = new SearchWaypoint(artifact);
|
|
||||||
points.add(point);
|
|
||||||
} catch (GeoLocationDataException ex) {
|
|
||||||
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_SEARCH artifactID: %d", artifact.getArtifactID()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of Waypoints for TSK_GPS_LAST_KNOWN_LOCATION artifacts.
|
|
||||||
*
|
|
||||||
* @param skCase Currently open SleuthkitCase
|
|
||||||
*
|
|
||||||
* @return List of Waypoint
|
|
||||||
*
|
|
||||||
* @throws GeoLocationDataException
|
|
||||||
*/
|
|
||||||
public static List<Waypoint> getLastKnownWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
|
||||||
List<BlackboardArtifact> artifacts = null;
|
|
||||||
try {
|
|
||||||
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_LAST_KNOWN_LOCATION", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Waypoint> points = new ArrayList<>();
|
|
||||||
if (artifacts != null) {
|
|
||||||
for (BlackboardArtifact artifact : artifacts) {
|
|
||||||
try {
|
|
||||||
Waypoint point = new LastKnownWaypoint(artifact);
|
|
||||||
points.add(point);
|
|
||||||
} catch (GeoLocationDataException ex) {
|
|
||||||
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_LAST_KNOWN_LOCATION artifactID: %d", artifact.getArtifactID()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of Waypoints for TSK_GPS_BOOKMARK artifacts.
|
|
||||||
*
|
|
||||||
* @param skCase Currently open SleuthkitCase
|
|
||||||
*
|
|
||||||
* @return List of Waypoint
|
|
||||||
*
|
|
||||||
* @throws GeoLocationDataException
|
|
||||||
*/
|
|
||||||
public static List<Waypoint> getBookmarkWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
|
||||||
List<BlackboardArtifact> artifacts = null;
|
|
||||||
try {
|
|
||||||
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK);
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_BOOKMARK", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Waypoint> points = new ArrayList<>();
|
|
||||||
if (artifacts != null) {
|
|
||||||
for (BlackboardArtifact artifact : artifacts) {
|
|
||||||
try {
|
|
||||||
Waypoint point = new Waypoint(artifact);
|
|
||||||
points.add(point);
|
|
||||||
} catch (GeoLocationDataException ex) {
|
|
||||||
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_BOOKMARK artifactID: %d", artifact.getArtifactID()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of Waypoint.Property objects for the given artifact. This list
|
* Get a list of Waypoint.Property objects for the given artifact. This list
|
||||||
* will not include attributes that the Waypoint interfact has get functions
|
* will not include attributes that the Waypoint interfact has get functions
|
||||||
|
484
Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java
Executable file
484
Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java
Executable file
@ -0,0 +1,484 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.geolocation.datamodel;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.CaseDbAccessManager;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for building lists of waypoints.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class WaypointBuilder {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(WaypointBuilder.class.getName());
|
||||||
|
|
||||||
|
// SELECT statement for getting a list of waypoints. Replace the %s after
|
||||||
|
// after the SELECT with the list of parameters to return
|
||||||
|
final static String GEO_ARTIFACT_QUERY
|
||||||
|
= "SELECT artifact_id, artifact_type_id "
|
||||||
|
+ "FROM blackboard_attributes "
|
||||||
|
+ "WHERE attribute_type_id IN (%d, %d) "; //NON-NLS
|
||||||
|
|
||||||
|
// This Query will return a list of waypoint artifacts
|
||||||
|
final static String GEO_ARTIFACT_WITH_DATA_SOURCES_QUERY
|
||||||
|
= "SELECT blackboard_attributes.artifact_id "
|
||||||
|
+ "FROM blackboard_attributes "
|
||||||
|
+ "JOIN blackboard_artifacts ON blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id "
|
||||||
|
+ "WHERE blackboard_attributes.attribute_type_id IN(%d, %d) "
|
||||||
|
+ "AND data_source_obj_id IN (%s)"; //NON-NLS
|
||||||
|
|
||||||
|
final static String MOST_RECENT_TIME
|
||||||
|
= "SELECT MAX(value_int64) - (%d * 86400)" //86400 is the number of seconds in a day.
|
||||||
|
+ "FROM blackboard_attributes "
|
||||||
|
+ "WHERE attribute_type_id IN(%d, %d) "
|
||||||
|
+ "AND artifact_id "
|
||||||
|
+ "IN ( "
|
||||||
|
+ "%s" //GEO_ARTIFACT with or without data source
|
||||||
|
+ " )";
|
||||||
|
|
||||||
|
final static String SELECT_WO_TIMESTAMP =
|
||||||
|
"SELECT DISTINCT artifact_id, artifact_type_id "
|
||||||
|
+ "FROM blackboard_attributes "
|
||||||
|
+ "WHERE artifact_id NOT IN (%s) "
|
||||||
|
+ "AND artifact_id IN (%s)"; //NON-NLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback interface to process the results of waypoint filtering.
|
||||||
|
*/
|
||||||
|
public interface WaypointFilterQueryCallBack {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will be called after the waypoints have been filtered.
|
||||||
|
*
|
||||||
|
* @param wwaypoints This of waypoints.
|
||||||
|
*/
|
||||||
|
void process(List<Waypoint> wwaypoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private constructor
|
||||||
|
*/
|
||||||
|
private WaypointBuilder() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of Waypoints for the artifacts with geolocation
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* List will include artifacts of type: TSK_GPS_TRACKPOINT TSK_GPS_SEARCH
|
||||||
|
* TSK_GPS_LAST_KNOWN_LOCATION TSK_GPS_BOOKMARK TSK_METADATA_EXIF
|
||||||
|
*
|
||||||
|
* @param skCase Currently open SleuthkitCase
|
||||||
|
*
|
||||||
|
* @return List of Waypoint
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getAllWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||||
|
List<Waypoint> points = new ArrayList<>();
|
||||||
|
|
||||||
|
points.addAll(getTrackpointWaypoints(skCase));
|
||||||
|
points.addAll(getEXIFWaypoints(skCase));
|
||||||
|
points.addAll(getSearchWaypoints(skCase));
|
||||||
|
points.addAll(getLastKnownWaypoints(skCase));
|
||||||
|
points.addAll(getBookmarkWaypoints(skCase));
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of Waypoints for TSK_GPS_TRACKPOINT artifacts.
|
||||||
|
*
|
||||||
|
* @param skCase Currently open SleuthkitCase
|
||||||
|
*
|
||||||
|
* @return List of Waypoint
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getTrackpointWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||||
|
List<BlackboardArtifact> artifacts = null;
|
||||||
|
try {
|
||||||
|
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_TRACKPOINT", ex);//NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Waypoint> points = new ArrayList<>();
|
||||||
|
for (BlackboardArtifact artifact : artifacts) {
|
||||||
|
try {
|
||||||
|
Waypoint point = new TrackpointWaypoint(artifact);
|
||||||
|
points.add(point);
|
||||||
|
} catch (GeoLocationDataException ex) {
|
||||||
|
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_TRACKPOINT artifactID: %d", artifact.getArtifactID()));//NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of Waypoints for TSK_METADATA_EXIF artifacts.
|
||||||
|
*
|
||||||
|
* @param skCase Currently open SleuthkitCase
|
||||||
|
*
|
||||||
|
* @return List of Waypoint
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
static public List<Waypoint> getEXIFWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||||
|
List<BlackboardArtifact> artifacts = null;
|
||||||
|
try {
|
||||||
|
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_LAST_KNOWN_LOCATION", ex);//NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Waypoint> points = new ArrayList<>();
|
||||||
|
if (artifacts != null) {
|
||||||
|
for (BlackboardArtifact artifact : artifacts) {
|
||||||
|
try {
|
||||||
|
Waypoint point = new EXIFWaypoint(artifact);
|
||||||
|
points.add(point);
|
||||||
|
} catch (GeoLocationDataException ex) {
|
||||||
|
// I am a little relucant to log this error because I suspect
|
||||||
|
// this will happen more often than not. It is valid for
|
||||||
|
// METADAT_EXIF to not have longitude and latitude
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of Waypoints for TSK_GPS_SEARCH artifacts.
|
||||||
|
*
|
||||||
|
* @param skCase Currently open SleuthkitCase
|
||||||
|
*
|
||||||
|
* @return List of Waypoint
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getSearchWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||||
|
List<BlackboardArtifact> artifacts = null;
|
||||||
|
try {
|
||||||
|
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_SEARCH", ex);//NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Waypoint> points = new ArrayList<>();
|
||||||
|
if (artifacts != null) {
|
||||||
|
for (BlackboardArtifact artifact : artifacts) {
|
||||||
|
try {
|
||||||
|
Waypoint point = new SearchWaypoint(artifact);
|
||||||
|
points.add(point);
|
||||||
|
} catch (GeoLocationDataException ex) {
|
||||||
|
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_SEARCH artifactID: %d", artifact.getArtifactID()));//NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of Waypoints for TSK_GPS_LAST_KNOWN_LOCATION artifacts.
|
||||||
|
*
|
||||||
|
* @param skCase Currently open SleuthkitCase
|
||||||
|
*
|
||||||
|
* @return List of Waypoint
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getLastKnownWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||||
|
List<BlackboardArtifact> artifacts = null;
|
||||||
|
try {
|
||||||
|
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_LAST_KNOWN_LOCATION", ex);//NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Waypoint> points = new ArrayList<>();
|
||||||
|
if (artifacts != null) {
|
||||||
|
for (BlackboardArtifact artifact : artifacts) {
|
||||||
|
try {
|
||||||
|
Waypoint point = new LastKnownWaypoint(artifact);
|
||||||
|
points.add(point);
|
||||||
|
} catch (GeoLocationDataException ex) {
|
||||||
|
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_LAST_KNOWN_LOCATION artifactID: %d", artifact.getArtifactID()));//NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of Waypoints for TSK_GPS_BOOKMARK artifacts.
|
||||||
|
*
|
||||||
|
* @param skCase Currently open SleuthkitCase
|
||||||
|
*
|
||||||
|
* @return List of Waypoint
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getBookmarkWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||||
|
List<BlackboardArtifact> artifacts = null;
|
||||||
|
try {
|
||||||
|
artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_BOOKMARK", ex);//NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Waypoint> points = new ArrayList<>();
|
||||||
|
if (artifacts != null) {
|
||||||
|
for (BlackboardArtifact artifact : artifacts) {
|
||||||
|
try {
|
||||||
|
Waypoint point = new Waypoint(artifact);
|
||||||
|
points.add(point);
|
||||||
|
} catch (GeoLocationDataException ex) {
|
||||||
|
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_BOOKMARK artifactID: %d", artifact.getArtifactID()), ex);//NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a filtered list of waypoints.
|
||||||
|
*
|
||||||
|
* If showAll is true, the values of cntDaysFromRecent and notTimeStamp will
|
||||||
|
* be ignored.
|
||||||
|
*
|
||||||
|
* To include data from all dataSources pass a null or empty dataSource
|
||||||
|
* list.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param skCase Currently open sleuthkit case.
|
||||||
|
* @param dataSources This of data sources to filter the waypoints by.
|
||||||
|
* Pass a null or empty list to show way points for
|
||||||
|
* all dataSources.
|
||||||
|
*
|
||||||
|
* @param showAll True to get all waypoints.
|
||||||
|
*
|
||||||
|
* @param cntDaysFromRecent Number of days from the most recent time stamp
|
||||||
|
* to get waypoints for. This parameter will be
|
||||||
|
* ignored if showAll is true;
|
||||||
|
*
|
||||||
|
* @param noTimeStamp True to include waypoints without timestamp.
|
||||||
|
* This parameter will be ignored if showAll is
|
||||||
|
* true.
|
||||||
|
*
|
||||||
|
* @param queryCallBack Function to call after the DB query has
|
||||||
|
* completed.
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
static public void getAllWaypoints(SleuthkitCase skCase, List<DataSource> dataSources, boolean showAll, int cntDaysFromRecent, boolean noTimeStamp, WaypointFilterQueryCallBack queryCallBack) throws GeoLocationDataException {
|
||||||
|
String query = buildQuery(dataSources, showAll, cntDaysFromRecent, noTimeStamp);
|
||||||
|
|
||||||
|
logger.log(Level.INFO, query);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// The CaseDBAccessManager.select function will add a SELECT
|
||||||
|
// to the beginning of the query
|
||||||
|
if (query.startsWith("SELECT")) { //NON-NLS
|
||||||
|
query = query.replaceFirst("SELECT", ""); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
skCase.getCaseDbAccessManager().select(query, new CaseDbAccessManager.CaseDbAccessQueryCallback() {
|
||||||
|
@Override
|
||||||
|
public void process(ResultSet rs) {
|
||||||
|
List<Waypoint> waypoints = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
while (rs.next()) {
|
||||||
|
int artifact_type_id = rs.getInt("artifact_type_id"); //NON-NLS
|
||||||
|
long artifact_id = rs.getLong("artifact_id"); //NON-NLS
|
||||||
|
|
||||||
|
BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact_type_id);
|
||||||
|
|
||||||
|
waypoints.addAll(getWaypointForArtifact(skCase.getBlackboardArtifact(artifact_id), type));
|
||||||
|
|
||||||
|
}
|
||||||
|
queryCallBack.process(waypoints);
|
||||||
|
} catch (GeoLocationDataException | SQLException | TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to filter waypoint.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to filter waypoint.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the query for getting a list of waypoints that do not have time
|
||||||
|
* stamps.
|
||||||
|
*
|
||||||
|
* @param dataSources List of data Sources to filter by
|
||||||
|
*
|
||||||
|
* @return SQL SELECT statement
|
||||||
|
*/
|
||||||
|
static private String buildQueryForWaypointsWOTimeStamps(List<DataSource> dataSources) {
|
||||||
|
String query = "";
|
||||||
|
|
||||||
|
query = String.format(SELECT_WO_TIMESTAMP,
|
||||||
|
String.format(GEO_ARTIFACT_QUERY,
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()),
|
||||||
|
getWaypointListQuery(dataSources));
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the query to filter the list of waypoints.
|
||||||
|
*
|
||||||
|
* If showAll is true, the values of cntDaysFromRecent and noTimeStamp are
|
||||||
|
* ignored.
|
||||||
|
*
|
||||||
|
* @param dataSources This of data sources to filter the waypoints by.
|
||||||
|
* Pass a null or empty list to show way points for
|
||||||
|
* all dataSources.
|
||||||
|
*
|
||||||
|
* @param showAll True to get all waypoints.
|
||||||
|
*
|
||||||
|
* @param cntDaysFromRecent Number of days from the most recent time stamp
|
||||||
|
* to get waypoints for. This parameter will be
|
||||||
|
* ignored if showAll is true;
|
||||||
|
*
|
||||||
|
* @param noTimeStamp True to include waypoints without timestamp.
|
||||||
|
* This parameter will be ignored if showAll is
|
||||||
|
* true.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static private String buildQuery(List<DataSource> dataSources, boolean showAll, int cntDaysFromRecent, boolean noTimeStamp) {
|
||||||
|
String mostRecentQuery = "";
|
||||||
|
|
||||||
|
if (!showAll && cntDaysFromRecent > 0) {
|
||||||
|
mostRecentQuery = String.format("AND value_int64 > (%s)", //NON-NLS
|
||||||
|
String.format(MOST_RECENT_TIME,
|
||||||
|
cntDaysFromRecent,
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
|
||||||
|
getWaypointListQuery(dataSources)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This givens us all artifact_ID that have time stamp
|
||||||
|
String query = String.format(GEO_ARTIFACT_QUERY,
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID());
|
||||||
|
|
||||||
|
// That are in the list of artifacts for the given data Sources
|
||||||
|
query += String.format("AND artifact_id IN(%s)", getWaypointListQuery(dataSources)); //NON-NLS
|
||||||
|
query += mostRecentQuery;
|
||||||
|
|
||||||
|
if (noTimeStamp) {
|
||||||
|
query = String.format("%s UNION %s", buildQueryForWaypointsWOTimeStamps(dataSources), query); //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the query to get a list of waypoints filted by the given data
|
||||||
|
* sources.
|
||||||
|
*
|
||||||
|
* An artifact is assumed to be a "waypoint" if it has the attributes
|
||||||
|
* TSK_GEO_LATITUDE or TSK_GEO_LATITUDE_START
|
||||||
|
*
|
||||||
|
* @param dataSources A list of data sources to filter by. If the list is
|
||||||
|
* null or empty the data source list will be ignored.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static private String getWaypointListQuery(List<DataSource> dataSources) {
|
||||||
|
|
||||||
|
if (dataSources == null || dataSources.isEmpty()) {
|
||||||
|
return String.format(GEO_ARTIFACT_QUERY,
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID());
|
||||||
|
}
|
||||||
|
|
||||||
|
String dataSourceList = "";
|
||||||
|
for (DataSource source : dataSources) {
|
||||||
|
dataSourceList += Long.toString(source.getId()) + ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dataSourceList.isEmpty()) {
|
||||||
|
// Remove the last ,
|
||||||
|
dataSourceList = dataSourceList.substring(0, dataSourceList.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format(GEO_ARTIFACT_WITH_DATA_SOURCES_QUERY,
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(),
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID(),
|
||||||
|
dataSourceList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Waypoint object for the given Blackboard artifact.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact to create the waypoint from
|
||||||
|
* @param type The type of artifact
|
||||||
|
*
|
||||||
|
* @return A new waypoint object
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
static private List<Waypoint> getWaypointForArtifact(BlackboardArtifact artifact, BlackboardArtifact.ARTIFACT_TYPE type) throws GeoLocationDataException {
|
||||||
|
List<Waypoint> waypoints = new ArrayList<>();
|
||||||
|
switch (type) {
|
||||||
|
case TSK_METADATA_EXIF:
|
||||||
|
waypoints.add(new EXIFWaypoint(artifact));
|
||||||
|
break;
|
||||||
|
case TSK_GPS_BOOKMARK:
|
||||||
|
waypoints.add(new Waypoint(artifact));
|
||||||
|
break;
|
||||||
|
case TSK_GPS_TRACKPOINT:
|
||||||
|
waypoints.add(new TrackpointWaypoint(artifact));
|
||||||
|
break;
|
||||||
|
case TSK_GPS_SEARCH:
|
||||||
|
waypoints.add(new SearchWaypoint(artifact));
|
||||||
|
break;
|
||||||
|
case TSK_GPS_ROUTE:
|
||||||
|
Route route = new Route(artifact);
|
||||||
|
waypoints.addAll(route.getRoute());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
waypoints.add(new Waypoint(artifact));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return waypoints;
|
||||||
|
}
|
||||||
|
}
|
BIN
Core/src/org/sleuthkit/autopsy/geolocation/images/blueGeo16.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/geolocation/images/blueGeo16.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 741 B |
BIN
Core/src/org/sleuthkit/autopsy/geolocation/images/blueGeo64.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/geolocation/images/blueGeo64.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
Core/src/org/sleuthkit/autopsy/geolocation/images/funnel.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/geolocation/images/funnel.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 591 B |
BIN
Core/src/org/sleuthkit/autopsy/geolocation/images/tick.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/geolocation/images/tick.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 582 B |
@ -47,6 +47,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|||||||
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
|
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
|
||||||
import org.sleuthkit.autopsy.geolocation.datamodel.Waypoint;
|
import org.sleuthkit.autopsy.geolocation.datamodel.Waypoint;
|
||||||
import org.sleuthkit.autopsy.geolocation.datamodel.Route;
|
import org.sleuthkit.autopsy.geolocation.datamodel.Route;
|
||||||
|
import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder;
|
||||||
import org.sleuthkit.autopsy.report.ReportBranding;
|
import org.sleuthkit.autopsy.report.ReportBranding;
|
||||||
import org.sleuthkit.autopsy.report.ReportProgressPanel;
|
import org.sleuthkit.autopsy.report.ReportProgressPanel;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
@ -331,11 +332,11 @@ class KMLReport implements GeneralReportModule {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void addLocationsToReport(SleuthkitCase skCase, String baseReportDir) throws GeoLocationDataException, IOException {
|
void addLocationsToReport(SleuthkitCase skCase, String baseReportDir) throws GeoLocationDataException, IOException {
|
||||||
addExifMetadataContent(Waypoint.getEXIFWaypoints(skCase), baseReportDir);
|
addExifMetadataContent(WaypointBuilder.getEXIFWaypoints(skCase), baseReportDir);
|
||||||
addWaypoints(Waypoint.getBookmarkWaypoints(skCase), gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
|
addWaypoints(WaypointBuilder.getBookmarkWaypoints(skCase), gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
|
||||||
addWaypoints(Waypoint.getLastKnownWaypoints(skCase), gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_Display_String());
|
addWaypoints(WaypointBuilder.getLastKnownWaypoints(skCase), gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_Display_String());
|
||||||
addWaypoints(Waypoint.getSearchWaypoints(skCase), gpsSearchesFolder, FeatureColor.WHITE, Bundle.Waypoint_Search_Display_String());
|
addWaypoints(WaypointBuilder.getSearchWaypoints(skCase), gpsSearchesFolder, FeatureColor.WHITE, Bundle.Waypoint_Search_Display_String());
|
||||||
addWaypoints(Waypoint.getTrackpointWaypoints(skCase), gpsTrackpointsFolder, FeatureColor.WHITE, Bundle.Waypoint_Trackpoint_Display_String());
|
addWaypoints(WaypointBuilder.getTrackpointWaypoints(skCase), gpsTrackpointsFolder, FeatureColor.WHITE, Bundle.Waypoint_Trackpoint_Display_String());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user