Autopsy  4.19.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.infrastructure;
20 
22 import java.awt.Component;
23 import java.awt.event.ItemEvent;
24 import java.awt.event.ItemListener;
25 import java.awt.event.MouseAdapter;
26 import java.awt.event.MouseEvent;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.LinkedHashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.logging.Level;
34 import javax.swing.JCheckBox;
35 import javax.swing.JLabel;
36 import javax.swing.JList;
37 import javax.swing.ListCellRenderer;
38 import javax.swing.ListModel;
39 import javax.swing.event.ListDataListener;
40 import org.openide.util.NbBundle;
45 import org.sleuthkit.datamodel.BlackboardArtifact;
46 import org.sleuthkit.datamodel.BlackboardAttribute;
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 PortableCaseReportModuleSettings settings;
63  private final boolean useCaseSpecificData;
64 
68  PortableCaseInterestingItemsListPanel(ReportWizardPortableCaseOptionsPanel wizPanel, PortableCaseReportModuleSettings options, boolean useCaseSpecificData) {
69  this.wizPanel = wizPanel;
70  this.useCaseSpecificData = useCaseSpecificData;
71  this.settings = options;
72  initComponents();
73  customizeComponents();
74 
75  // update tag selection
76  jAllSetsCheckBox.setSelected(settings.areAllSetsSelected());
77  setNamesListBox.setEnabled(!jAllSetsCheckBox.isSelected());
78  selectButton.setEnabled(!jAllSetsCheckBox.isSelected());
79  deselectButton.setEnabled(!jAllSetsCheckBox.isSelected());
80  selectAllSets(jAllSetsCheckBox.isSelected());
81 
82  this.jAllSetsCheckBox.addItemListener(new ItemListener() {
83  @Override
84  public void itemStateChanged(ItemEvent e) {
85  setNamesListBox.setEnabled(!jAllSetsCheckBox.isSelected());
86  selectButton.setEnabled(!jAllSetsCheckBox.isSelected());
87  deselectButton.setEnabled(!jAllSetsCheckBox.isSelected());
88  selectAllSets(jAllSetsCheckBox.isSelected());
89  }
90  });
91  }
92 
93  @NbBundle.Messages({
94  "PortableCaseInterestingItemsListPanel.error.errorTitle=Error getting intesting item set names for case",
95  "PortableCaseInterestingItemsListPanel.error.noOpenCase=There is no case open",
96  "PortableCaseInterestingItemsListPanel.error.errorLoadingTags=Error loading interesting item set names",
97  })
98  private void customizeComponents() {
99 
100  // Get the set names in use for the current case.
101  setNames = new ArrayList<>();
102  setCounts = new HashMap<>();
103 
104  // only try to load tag names if we are displaying case specific data, otherwise
105  // we will be displaying case specific data in command line wizard if there is
106  // a case open in the background
107  if (useCaseSpecificData) {
108  try {
109  // Get all SET_NAMEs from interesting item artifacts
110  String innerSelect = "SELECT (value_text) AS set_name FROM blackboard_attributes WHERE (artifact_type_id = '"
111  + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() + "' OR artifact_type_id = '"
112  + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() + "') AND attribute_type_id = '"
113  + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + "'"; // NON-NLS
114 
115  // Get the count of each SET_NAME
116  String query = "set_name, count(1) AS set_count FROM (" + innerSelect + ") set_names GROUP BY set_name"; // NON-NLS
117 
118  GetInterestingItemSetNamesCallback callback = new GetInterestingItemSetNamesCallback();
119  Case.getCurrentCaseThrows().getSleuthkitCase().getCaseDbAccessManager().select(query, callback);
120  setCounts = callback.getSetCountMap();
121  setNames.addAll(setCounts.keySet());
122  } catch (TskCoreException ex) {
123  Logger.getLogger(ReportWizardPortableCaseOptionsVisualPanel.class.getName()).log(Level.SEVERE, "Failed to get interesting item set names", ex); // NON-NLS
124  } catch (NoCurrentCaseException ex) {
125  // There may not be a case open when configuring report modules for Command Line execution
126  if (Case.isCaseOpen()) {
127  Logger.getLogger(ReportWizardPortableCaseOptionsVisualPanel.class.getName()).log(Level.SEVERE, "Exception while getting open case.", ex); // NON-NLS
128  }
129  }
130  }
131  Collections.sort(setNames);
132 
133  // Mark the set names as unselected. Note that setNameSelections is a
134  // LinkedHashMap so that order is preserved and the setNames and setNameSelections
135  // containers are "parallel" containers.
136  for (String setName : setNames) {
137  setNameSelections.put(setName, Boolean.FALSE);
138  }
139 
140  // Set up the tag names JList component to be a collection of check boxes
141  // for selecting tag names. The mouse click listener updates setNameSelections
142  // to reflect user choices.
143  setNamesListBox.setModel(setNamesListModel);
144  setNamesListBox.setCellRenderer(setNamesRenderer);
145  setNamesListBox.setVisibleRowCount(-1);
146  setNamesListBox.addMouseListener(new MouseAdapter() {
147  @Override
148  public void mousePressed(MouseEvent evt) {
149  JList<?> list = (JList) evt.getSource();
150  int index = list.locationToIndex(evt.getPoint());
151  if (index > -1) {
152  String value = setNamesListModel.getElementAt(index);
153  setNameSelections.put(value, !setNameSelections.get(value));
154  list.repaint();
155  updateSetNameList();
156  }
157  }
158  });
159  }
160 
164  private void updateSetNameList() {
165  settings.updateSetNames(getSelectedSetNames());
166  settings.setAllSetsSelected(jAllSetsCheckBox.isSelected());
167  wizPanel.setFinish(settings.isValid());
168  }
169 
173  private class SetNamesListModel implements ListModel<String> {
174 
175  @Override
176  public int getSize() {
177  return setNames.size();
178  }
179 
180  @Override
181  public String getElementAt(int index) {
182  return setNames.get(index);
183  }
184 
185  @Override
186  public void addListDataListener(ListDataListener l) {
187  // Nothing to do
188  }
189 
190  @Override
191  public void removeListDataListener(ListDataListener l) {
192  // Nothing to do
193  }
194  }
195 
199  private class SetNamesListCellRenderer extends JCheckBox implements ListCellRenderer<String> {
200  private static final long serialVersionUID = 1L;
201 
202  @Override
203  public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, boolean isSelected, boolean cellHasFocus) {
204  if (value != null) {
205  setEnabled(list.isEnabled());
206  setSelected(setNameSelections.get(value));
207  setFont(list.getFont());
208  setBackground(list.getBackground());
209  setForeground(list.getForeground());
210  String text = value + " (" + setCounts.get(value) + ")";
211  setText(text); // NON-NLS
212  setToolTipText(text);
213  return this;
214  }
215  return new JLabel();
216  }
217  }
218 
224  private List<String> getSelectedSetNames() {
225  List<String> selectedSetNames = new ArrayList<>();
226  for (String setName : setNames) {
227  if (setNameSelections.get(setName)) {
228  selectedSetNames.add(setName);
229  }
230  }
231  return selectedSetNames;
232  }
233 
239  @SuppressWarnings("unchecked")
240  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
241  private void initComponents() {
242 
243  jPanel1 = new javax.swing.JPanel();
244  jScrollPane1 = new javax.swing.JScrollPane();
245  setNamesListBox = new javax.swing.JList<>();
246  descLabel = new javax.swing.JLabel();
247  selectButton = new javax.swing.JButton();
248  deselectButton = new javax.swing.JButton();
249  jAllSetsCheckBox = new javax.swing.JCheckBox();
250 
251  jScrollPane1.setViewportView(setNamesListBox);
252 
253  org.openide.awt.Mnemonics.setLocalizedText(descLabel, org.openide.util.NbBundle.getMessage(PortableCaseInterestingItemsListPanel.class, "PortableCaseInterestingItemsListPanel.descLabel.text")); // NOI18N
254 
255  org.openide.awt.Mnemonics.setLocalizedText(selectButton, org.openide.util.NbBundle.getMessage(PortableCaseInterestingItemsListPanel.class, "PortableCaseInterestingItemsListPanel.selectButton.text")); // NOI18N
256  selectButton.setMaximumSize(new java.awt.Dimension(87, 23));
257  selectButton.setMinimumSize(new java.awt.Dimension(87, 23));
258  selectButton.addActionListener(new java.awt.event.ActionListener() {
259  public void actionPerformed(java.awt.event.ActionEvent evt) {
260  selectButtonActionPerformed(evt);
261  }
262  });
263 
264  org.openide.awt.Mnemonics.setLocalizedText(deselectButton, org.openide.util.NbBundle.getMessage(PortableCaseInterestingItemsListPanel.class, "PortableCaseInterestingItemsListPanel.deselectButton.text")); // NOI18N
265  deselectButton.addActionListener(new java.awt.event.ActionListener() {
266  public void actionPerformed(java.awt.event.ActionEvent evt) {
267  deselectButtonActionPerformed(evt);
268  }
269  });
270 
271  org.openide.awt.Mnemonics.setLocalizedText(jAllSetsCheckBox, org.openide.util.NbBundle.getMessage(PortableCaseInterestingItemsListPanel.class, "PortableCaseInterestingItemsListPanel.jAllSetsCheckBox.text")); // NOI18N
272  jAllSetsCheckBox.addActionListener(new java.awt.event.ActionListener() {
273  public void actionPerformed(java.awt.event.ActionEvent evt) {
274  jAllSetsCheckBoxActionPerformed(evt);
275  }
276  });
277 
278  javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
279  jPanel1.setLayout(jPanel1Layout);
280  jPanel1Layout.setHorizontalGroup(
281  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
282  .addGroup(jPanel1Layout.createSequentialGroup()
283  .addContainerGap()
284  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
285  .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
286  .addGroup(jPanel1Layout.createSequentialGroup()
287  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
288  .addComponent(descLabel)
289  .addGroup(jPanel1Layout.createSequentialGroup()
290  .addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)
291  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
292  .addComponent(deselectButton))
293  .addComponent(jAllSetsCheckBox))
294  .addGap(0, 8, Short.MAX_VALUE)))
295  .addContainerGap())
296  );
297  jPanel1Layout.setVerticalGroup(
298  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
299  .addGroup(jPanel1Layout.createSequentialGroup()
300  .addGap(6, 6, 6)
301  .addComponent(descLabel)
302  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
303  .addComponent(jAllSetsCheckBox)
304  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
305  .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 159, Short.MAX_VALUE)
306  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
307  .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
308  .addComponent(selectButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
309  .addComponent(deselectButton)))
310  );
311 
312  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
313  this.setLayout(layout);
314  layout.setHorizontalGroup(
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  layout.setVerticalGroup(
319  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
320  .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
321  );
322  }// </editor-fold>//GEN-END:initComponents
323 
324  private void deselectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectButtonActionPerformed
325  selectAllSets(false);
326  }//GEN-LAST:event_deselectButtonActionPerformed
327 
328  private void selectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectButtonActionPerformed
329  selectAllSets(true);
330  }//GEN-LAST:event_selectButtonActionPerformed
331 
332  private void jAllSetsCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jAllSetsCheckBoxActionPerformed
333  selectAllSets(true);
334  }//GEN-LAST:event_jAllSetsCheckBoxActionPerformed
335 
336  private void selectAllSets(boolean select) {
337  Boolean state = Boolean.TRUE;
338  if (!select) {
339  state = Boolean.FALSE;
340  }
341  for (String setName : setNames) {
342  setNameSelections.put(setName, state);
343  }
344  updateSetNameList();
345  setNamesListBox.repaint();
346  }
347 
348  // Variables declaration - do not modify//GEN-BEGIN:variables
349  private javax.swing.JLabel descLabel;
350  private javax.swing.JButton deselectButton;
351  private javax.swing.JCheckBox jAllSetsCheckBox;
352  private javax.swing.JPanel jPanel1;
353  private javax.swing.JScrollPane jScrollPane1;
354  private javax.swing.JButton selectButton;
355  private javax.swing.JList<String> setNamesListBox;
356  // End of variables declaration//GEN-END:variables
357 }
Component getListCellRendererComponent(JList<?extends String > list, String value, int index, boolean isSelected, boolean cellHasFocus)

Copyright © 2012-2021 Basis Technology. Generated on: Fri Aug 6 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.