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

Copyright © 2012-2022 Basis Technology. Generated on: Tue Feb 6 2024
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.