Autopsy  4.12.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
PortableCaseInterestingItemsListPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.report;
20 
21 import java.awt.Component;
22 import java.awt.event.MouseAdapter;
23 import java.awt.event.MouseEvent;
24 import java.sql.ResultSet;
25 import java.sql.SQLException;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.logging.Level;
33 import javax.swing.JCheckBox;
34 import javax.swing.JLabel;
35 import javax.swing.JList;
36 import javax.swing.JOptionPane;
37 import javax.swing.ListCellRenderer;
38 import javax.swing.ListModel;
39 import javax.swing.event.ListDataListener;
40 import org.openide.util.NbBundle;
44 import org.sleuthkit.datamodel.BlackboardArtifact;
45 import org.sleuthkit.datamodel.BlackboardAttribute;
46 import org.sleuthkit.datamodel.CaseDbAccessManager;
47 import org.sleuthkit.datamodel.TskCoreException;
48 
52 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
53 class PortableCaseInterestingItemsListPanel extends javax.swing.JPanel {
54 
55  private List<String> setNames;
56  private final Map<String, Boolean> setNameSelections = new LinkedHashMap<>();
57  private final SetNamesListModel setNamesListModel = new SetNamesListModel();
58  private final SetNamesListCellRenderer setNamesRenderer = new SetNamesListCellRenderer();
59  private Map<String, Long> setCounts;
60 
61  private final ReportWizardPortableCaseOptionsPanel wizPanel;
62  private final PortableCaseReportModule.PortableCaseOptions options;
63 
67  PortableCaseInterestingItemsListPanel(ReportWizardPortableCaseOptionsPanel wizPanel, PortableCaseReportModule.PortableCaseOptions options) {
68  this.wizPanel = wizPanel;
69  this.options = options;
70  initComponents();
71  customizeComponents();
72  }
73 
74  @NbBundle.Messages({
75  "PortableCaseInterestingItemsListPanel.error.errorTitle=Error getting intesting item set names for case",
76  "PortableCaseInterestingItemsListPanel.error.noOpenCase=There is no case open",
77  "PortableCaseInterestingItemsListPanel.error.errorLoadingTags=Error loading interesting item set names",
78  })
79  private void customizeComponents() {
80 
81  // Get the set names in use for the current case.
82  setNames = new ArrayList<>();
83  try {
84  // Get all SET_NAMEs from interesting item artifacts
85  String innerSelect = "SELECT (value_text) AS set_name FROM blackboard_attributes WHERE (artifact_type_id = '" +
86  BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() + "' OR artifact_type_id = '" +
87  BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() + "') AND attribute_type_id = '" +
88  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + "'"; // NON-NLS
89 
90  // Get the count of each SET_NAME
91  String query = "set_name, count(1) AS set_count FROM (" + innerSelect + ") set_names GROUP BY set_name"; // NON-NLS
92 
93  GetInterestingItemSetNamesCallback callback = new GetInterestingItemSetNamesCallback();
94  Case.getCurrentCaseThrows().getSleuthkitCase().getCaseDbAccessManager().select(query, callback);
95  setCounts = callback.getSetCountMap();
96  setNames.addAll(setCounts.keySet());
97  } catch (TskCoreException ex) {
98  Logger.getLogger(ReportWizardPortableCaseOptionsVisualPanel.class.getName()).log(Level.SEVERE, "Failed to get interesting item set names", ex); // NON-NLS
99  JOptionPane.showMessageDialog(this, Bundle.PortableCaseInterestingItemsListPanel_error_errorLoadingTags(), Bundle.PortableCaseInterestingItemsListPanel_error_errorTitle(), JOptionPane.ERROR_MESSAGE);
100  } catch (NoCurrentCaseException ex) {
101  Logger.getLogger(ReportWizardPortableCaseOptionsVisualPanel.class.getName()).log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
102  JOptionPane.showMessageDialog(this, Bundle.PortableCaseInterestingItemsListPanel_error_noOpenCase(), Bundle.PortableCaseInterestingItemsListPanel_error_errorTitle(), JOptionPane.ERROR_MESSAGE);
103  }
104  Collections.sort(setNames);
105 
106  // Mark the set names as unselected. Note that setNameSelections is a
107  // LinkedHashMap so that order is preserved and the setNames and setNameSelections
108  // containers are "parallel" containers.
109  for (String setName : setNames) {
110  setNameSelections.put(setName, Boolean.FALSE);
111  }
112 
113  // Set up the tag names JList component to be a collection of check boxes
114  // for selecting tag names. The mouse click listener updates setNameSelections
115  // to reflect user choices.
116  setNamesListBox.setModel(setNamesListModel);
117  setNamesListBox.setCellRenderer(setNamesRenderer);
118  setNamesListBox.setVisibleRowCount(-1);
119  setNamesListBox.addMouseListener(new MouseAdapter() {
120  @Override
121  public void mousePressed(MouseEvent evt) {
122  JList<?> list = (JList) evt.getSource();
123  int index = list.locationToIndex(evt.getPoint());
124  if (index > -1) {
125  String value = setNamesListModel.getElementAt(index);
126  setNameSelections.put(value, !setNameSelections.get(value));
127  list.repaint();
128  updateSetNameList();
129  }
130  }
131  });
132  }
133 
137  private void updateSetNameList() {
138  options.updateSetNames(getSelectedSetNames());
139  wizPanel.setFinish(options.isValid());
140  }
141 
145  private class SetNamesListModel implements ListModel<String> {
146 
147  @Override
148  public int getSize() {
149  return setNames.size();
150  }
151 
152  @Override
153  public String getElementAt(int index) {
154  return setNames.get(index);
155  }
156 
157  @Override
158  public void addListDataListener(ListDataListener l) {
159  // Nothing to do
160  }
161 
162  @Override
163  public void removeListDataListener(ListDataListener l) {
164  // Nothing to do
165  }
166  }
167 
171  private class SetNamesListCellRenderer extends JCheckBox implements ListCellRenderer<String> {
172  private static final long serialVersionUID = 1L;
173 
174  @Override
175  public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, boolean isSelected, boolean cellHasFocus) {
176  if (value != null) {
177  setEnabled(list.isEnabled());
178  setSelected(setNameSelections.get(value));
179  setFont(list.getFont());
180  setBackground(list.getBackground());
181  setForeground(list.getForeground());
182  setText(value + " (" + setCounts.get(value) + ")"); // NON-NLS
183  return this;
184  }
185  return new JLabel();
186  }
187  }
188 
194  private List<String> getSelectedSetNames() {
195  List<String> selectedSetNames = new ArrayList<>();
196  for (String setName : setNames) {
197  if (setNameSelections.get(setName)) {
198  selectedSetNames.add(setName);
199  }
200  }
201  return selectedSetNames;
202  }
203 
207  private static class GetInterestingItemSetNamesCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
208 
209  private static final Logger logger = Logger.getLogger(GetInterestingItemSetNamesCallback.class.getName());
210  private final Map<String, Long> setCounts = new HashMap<>();
211 
212  @Override
213  public void process(ResultSet rs) {
214  try {
215  while (rs.next()) {
216  try {
217  Long setCount = rs.getLong("set_count"); // NON-NLS
218  String setName = rs.getString("set_name"); // NON-NLS
219 
220  setCounts.put(setName, setCount);
221 
222  } catch (SQLException ex) {
223  logger.log(Level.WARNING, "Unable to get data_source_obj_id or value from result set", ex); // NON-NLS
224  }
225  }
226  } catch (SQLException ex) {
227  logger.log(Level.WARNING, "Failed to get next result for values by datasource", ex); // NON-NLS
228  }
229  }
230 
236  Map<String, Long> getSetCountMap() {
237  return setCounts;
238  }
239  }
240 
246  @SuppressWarnings("unchecked")
247  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
248  private void initComponents() {
249 
250  jPanel1 = new javax.swing.JPanel();
251  jScrollPane1 = new javax.swing.JScrollPane();
252  setNamesListBox = new javax.swing.JList<>();
253  descLabel = new javax.swing.JLabel();
254  selectButton = new javax.swing.JButton();
255  deselectButton = new javax.swing.JButton();
256 
257  jScrollPane1.setViewportView(setNamesListBox);
258 
259  org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(PortableCaseInterestingItemsListPanel.class, "PortableCaseInterestingItemsListPanel.descLabel.text")); // NOI18N
260 
261  org.openide.awt.Mnemonics.setLocalizedText(selectButton, org.openide.util.NbBundle.getMessage(PortableCaseInterestingItemsListPanel.class, "PortableCaseInterestingItemsListPanel.selectButton.text")); // NOI18N
262  selectButton.setMaximumSize(new java.awt.Dimension(87, 23));
263  selectButton.setMinimumSize(new java.awt.Dimension(87, 23));
264  selectButton.addActionListener(new java.awt.event.ActionListener() {
265  public void actionPerformed(java.awt.event.ActionEvent evt) {
266  selectButtonActionPerformed(evt);
267  }
268  });
269 
270  org.openide.awt.Mnemonics.setLocalizedText(deselectButton, org.openide.util.NbBundle.getMessage(PortableCaseInterestingItemsListPanel.class, "PortableCaseInterestingItemsListPanel.deselectButton.text")); // NOI18N
271  deselectButton.addActionListener(new java.awt.event.ActionListener() {
272  public void actionPerformed(java.awt.event.ActionEvent evt) {
273  deselectButtonActionPerformed(evt);
274  }
275  });
276 
277  javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
278  jPanel1.setLayout(jPanel1Layout);
279  jPanel1Layout.setHorizontalGroup(
280  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
281  .addGroup(jPanel1Layout.createSequentialGroup()
282  .addContainerGap()
283  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
284  .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
285  .addGroup(jPanel1Layout.createSequentialGroup()
286  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
287  .addComponent(descLabel)
288  .addGroup(jPanel1Layout.createSequentialGroup()
289  .addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)
290  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
291  .addComponent(deselectButton)))
292  .addGap(0, 8, Short.MAX_VALUE)))
293  .addContainerGap())
294  );
295  jPanel1Layout.setVerticalGroup(
296  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
297  .addGroup(jPanel1Layout.createSequentialGroup()
298  .addContainerGap()
299  .addComponent(descLabel)
300  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
301  .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE)
302  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
303  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
304  .addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
305  .addComponent(deselectButton)))
306  );
307 
308  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
309  this.setLayout(layout);
310  layout.setHorizontalGroup(
311  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
312  .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
313  );
314  layout.setVerticalGroup(
315  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
316  .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
317  );
318  }// </editor-fold>//GEN-END:initComponents
319 
320  private void deselectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectButtonActionPerformed
321  for (String setName : setNames) {
322  setNameSelections.put(setName, Boolean.FALSE);
323  }
324  updateSetNameList();
325  setNamesListBox.repaint();
326  }//GEN-LAST:event_deselectButtonActionPerformed
327 
328  private void selectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectButtonActionPerformed
329  for (String setName : setNames) {
330  setNameSelections.put(setName, Boolean.TRUE);
331  }
332  updateSetNameList();
333  setNamesListBox.repaint();
334  }//GEN-LAST:event_selectButtonActionPerformed
335 
336 
337  // Variables declaration - do not modify//GEN-BEGIN:variables
338  private javax.swing.JLabel descLabel;
339  private javax.swing.JButton deselectButton;
340  private javax.swing.JPanel jPanel1;
341  private javax.swing.JScrollPane jScrollPane1;
342  private javax.swing.JButton selectButton;
343  private javax.swing.JList<String> setNamesListBox;
344  // End of variables declaration//GEN-END:variables
345 }
Component getListCellRendererComponent(JList<?extends String > list, String value, int index, boolean isSelected, boolean cellHasFocus)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2018 Basis Technology. Generated on: Wed Sep 18 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.