Autopsy  4.19.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ReportVisualPanel1.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2012-2020 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 
26 import java.awt.BorderLayout;
27 import java.awt.Component;
28 import java.util.ArrayList;
29 import static java.util.Collections.swap;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.logging.Level;
34 import javax.swing.JList;
35 import javax.swing.JPanel;
36 import javax.swing.JRadioButton;
37 import javax.swing.ListCellRenderer;
38 import javax.swing.ListSelectionModel;
39 import javax.swing.border.Border;
40 import javax.swing.event.ListSelectionEvent;
41 import javax.swing.event.ListSelectionListener;
42 import org.openide.DialogDisplayer;
43 import org.openide.NotifyDescriptor;
44 import org.openide.util.NbBundle;
47 
51 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
52 final class ReportVisualPanel1 extends JPanel implements ListSelectionListener {
53 
54  private static final Logger logger = Logger.getLogger(ReportVisualPanel1.class.getName());
55  private final ReportWizardPanel1 wizPanel;
56  private final List<ReportModule> modules = new ArrayList<>();
57  private List<GeneralReportModule> generalModules = new ArrayList<>();
58  private List<TableReportModule> tableModules = new ArrayList<>();
59  private List<FileReportModule> fileModules = new ArrayList<>();
60  private PortableCaseReportModule portableCaseModule;
61  private Map<String, ReportModuleConfig> moduleConfigs;
62  private Integer selectedIndex;
63  private final boolean displayCaseSpecificData;
64 
68  ReportVisualPanel1(ReportWizardPanel1 wizPanel, Map<String, ReportModuleConfig> moduleConfigs, boolean displayCaseSpecificData) {
69  this.displayCaseSpecificData = displayCaseSpecificData;
70  this.wizPanel = wizPanel;
71  this.moduleConfigs = moduleConfigs;
72  initComponents();
73  configurationPanel.setLayout(new BorderLayout());
74  descriptionTextPane.setEditable(false);
75  initModules();
76  }
77 
78  // Initialize the list of ReportModules
79  private void initModules() {
80 
81  tableModules = ReportModuleLoader.getTableReportModules();
82  generalModules = ReportModuleLoader.getGeneralReportModules();
83  fileModules = ReportModuleLoader.getFileReportModules();
84 
85  for (TableReportModule module : tableModules) {
86  if (!moduleIsValid(module)) {
87  popupWarning(module);
88  tableModules.remove(module);
89  }
90  }
91 
92  for (GeneralReportModule module : generalModules) {
93  if (!moduleIsValid(module)) {
94  popupWarning(module);
95  generalModules.remove(module);
96  }
97  }
98 
99  for (FileReportModule module : fileModules) {
100  if (!moduleIsValid(module)) {
101  popupWarning(module);
102  fileModules.remove(module);
103  }
104  }
105 
106  // our theory is that the report table modules are more common, so they go on top
107  modules.addAll(tableModules);
108  modules.addAll(fileModules);
109  modules.addAll(generalModules);
110 
111  portableCaseModule = new PortableCaseReportModule();
112  if (moduleIsValid(portableCaseModule)) {
113  modules.add(portableCaseModule);
114  } else {
115  popupWarning(portableCaseModule);
116  }
117 
118  // Results-HTML should always be first in the list of Report Modules.
119  int indexOfHTMLReportModule = 0;
120  for (ReportModule module : modules) {
121  if (module instanceof HTMLReport) {
122  break;
123  }
124  indexOfHTMLReportModule++;
125  }
126  swap(modules, indexOfHTMLReportModule, 0);
127 
128  // set module configurations
129  selectedIndex = 0;
130  int indx = 0;
131  for (ReportModule module : modules) {
132  ReportModuleSettings settings = null;
133  if (moduleConfigs != null) {
134  // get configuration for this module
135  ReportModuleConfig config = moduleConfigs.get(FactoryClassNameNormalizer.normalize(module.getClass().getCanonicalName()));
136  if (config != null) {
137  // there is an existing configuration for this module
138  settings = config.getModuleSettings();
139 
140  // check if this module is enabled
141  if (config.isEnabled()) {
142  // make sure this module is the selected module in the UI panel
143  selectedIndex = indx;
144  }
145  }
146  }
147  if (settings == null) {
148  // get default module configuration
149  settings = module.getDefaultConfiguration();
150  }
151  // set module configuration
152  module.setConfiguration(settings);
153  indx++;
154  }
155 
156  modulesJList.getSelectionModel().addListSelectionListener(this);
157  modulesJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
158  modulesJList.setCellRenderer(new ModuleCellRenderer());
159  modulesJList.setListData(modules.toArray(new ReportModule[modules.size()]));
160  modulesJList.setSelectedIndex(selectedIndex);
161  }
162 
163  // Make sure that the report module has a valid non-null name.
164  private boolean moduleIsValid(ReportModule module) {
165  return module.getName() != null && !module.getName().isEmpty();
166  }
167 
168  private void popupWarning(ReportModule module) {
169  String moduleClassName = module.getClass().getSimpleName();
170  logger.log(Level.WARNING, "Invalid ReportModule: {0}", moduleClassName); // NON_NLS NON-NLS
171  DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
172  NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.invalidModuleWarning", moduleClassName),
173  NotifyDescriptor.ERROR_MESSAGE));
174  }
175 
176  @Override
177  public String getName() {
178  return NbBundle.getMessage(this.getClass(), "ReportVisualPanel1.getName.text");
179  }
180 
181  public ReportModule getSelectedModule() {
182  return modules.get(selectedIndex);
183  }
184 
190  TableReportModule getTableModule() {
191  ReportModule mod = getSelectedModule();
192  if (tableModules.contains(mod)) {
193  return (TableReportModule) mod;
194  }
195  return null;
196  }
197 
203  GeneralReportModule getGeneralModule() {
204  ReportModule mod = getSelectedModule();
205  if (generalModules.contains(mod)) {
206  return (GeneralReportModule) mod;
207  }
208  return null;
209  }
210 
216  FileReportModule getFileModule() {
217  ReportModule mod = getSelectedModule();
218  if (fileModules.contains(mod)) {
219  return (FileReportModule) mod;
220  }
221  return null;
222  }
223 
229  PortableCaseReportModule getPortableCaseModule() {
230  ReportModule mod = getSelectedModule();
231  if (portableCaseModule.equals(mod)) {
232  return (PortableCaseReportModule) mod;
233  }
234  return null;
235  }
236 
242  Map<String, ReportModuleConfig> getUpdatedModuleConfigs() {
243  moduleConfigs = new HashMap<>();
244  for (ReportModule module : modules) {
245  // get updated module configuration
246  ReportModuleSettings settings = module.getConfiguration();
247  moduleConfigs.put(FactoryClassNameNormalizer.normalize(module.getClass().getCanonicalName()), new ReportModuleConfig(module, false, settings));
248  }
249 
250  // set "enabled" flag for the selected module
251  ReportModule mod = getSelectedModule();
252  ReportModuleConfig config = moduleConfigs.get(FactoryClassNameNormalizer.normalize(mod.getClass().getCanonicalName()));
253  config.setEnabled(true);
254 
255  return moduleConfigs;
256  }
257 
258  Map<String, ReportModule> getReportModules() {
259  Map<String, ReportModule> modulesMap = new HashMap<>();
260  for (ReportModule module : modules) {
261  modulesMap.put(FactoryClassNameNormalizer.normalize(module.getClass().getCanonicalName()), module);
262  }
263  return modulesMap;
264  }
265 
271  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
272  private void initComponents() {
273 
274  reportModulesLabel = new javax.swing.JLabel();
275  javax.swing.JSplitPane modulesSplitPane = new javax.swing.JSplitPane();
276  javax.swing.JPanel detailsPanel = new javax.swing.JPanel();
277  configurationPanel = new javax.swing.JPanel();
278  descriptionScrollPane = new javax.swing.JScrollPane();
279  descriptionTextPane = new javax.swing.JTextPane();
280  modulesScrollPane = new javax.swing.JScrollPane();
281  modulesJList = new javax.swing.JList<>();
282 
283  setPreferredSize(new java.awt.Dimension(834, 374));
284 
285  org.openide.awt.Mnemonics.setLocalizedText(reportModulesLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.reportModulesLabel.text")); // NOI18N
286 
287  //Make border on split pane invisible to maintain previous style
288  modulesSplitPane.setUI(new javax.swing.plaf.basic.BasicSplitPaneUI() {
289  @Override
290  public javax.swing.plaf.basic.BasicSplitPaneDivider createDefaultDivider() {
291  javax.swing.plaf.basic.BasicSplitPaneDivider divider = new javax.swing.plaf.basic.BasicSplitPaneDivider(this) {
292  @Override
293  public void setBorder(Border border){
294  //do nothing so border is not visible
295  }
296  };
297  return divider;
298  }
299  });
300  modulesSplitPane.setBorder(null);
301  modulesSplitPane.setDividerSize(8);
302  modulesSplitPane.setResizeWeight(0.5);
303 
304  configurationPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(125, 125, 125)));
305  configurationPanel.setOpaque(false);
306 
307  javax.swing.GroupLayout configurationPanelLayout = new javax.swing.GroupLayout(configurationPanel);
308  configurationPanel.setLayout(configurationPanelLayout);
309  configurationPanelLayout.setHorizontalGroup(
310  configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
311  .addGap(0, 546, Short.MAX_VALUE)
312  );
313  configurationPanelLayout.setVerticalGroup(
314  configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
315  .addGap(0, 290, Short.MAX_VALUE)
316  );
317 
318  descriptionScrollPane.setBorder(null);
319 
320  descriptionTextPane.setBackground(new java.awt.Color(240, 240, 240));
321  descriptionTextPane.setBorder(null);
322  descriptionTextPane.setOpaque(false);
323  descriptionScrollPane.setViewportView(descriptionTextPane);
324 
325  javax.swing.GroupLayout detailsPanelLayout = new javax.swing.GroupLayout(detailsPanel);
326  detailsPanel.setLayout(detailsPanelLayout);
327  detailsPanelLayout.setHorizontalGroup(
328  detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
329  .addGroup(detailsPanelLayout.createSequentialGroup()
330  .addGap(0, 0, 0)
331  .addGroup(detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
332  .addComponent(descriptionScrollPane)
333  .addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
334  .addGap(0, 0, 0))
335  );
336  detailsPanelLayout.setVerticalGroup(
337  detailsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
338  .addGroup(detailsPanelLayout.createSequentialGroup()
339  .addGap(0, 0, 0)
340  .addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
341  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
342  .addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
343  .addGap(0, 0, 0))
344  );
345 
346  modulesSplitPane.setRightComponent(detailsPanel);
347 
348  modulesJList.setBackground(new java.awt.Color(240, 240, 240));
349  modulesJList.setModel(new javax.swing.AbstractListModel<ReportModule>() {
350  ReportModule[] modules = {};
351  public int getSize() { return modules.length; }
352  public ReportModule getElementAt(int i) { return modules[i]; }
353  });
354  modulesJList.setOpaque(false);
355  modulesScrollPane.setViewportView(modulesJList);
356 
357  modulesSplitPane.setLeftComponent(modulesScrollPane);
358 
359  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
360  this.setLayout(layout);
361  layout.setHorizontalGroup(
362  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
363  .addGroup(layout.createSequentialGroup()
364  .addContainerGap()
365  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
366  .addGroup(layout.createSequentialGroup()
367  .addComponent(reportModulesLabel)
368  .addGap(0, 0, Short.MAX_VALUE))
369  .addComponent(modulesSplitPane))
370  .addContainerGap())
371  );
372  layout.setVerticalGroup(
373  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
374  .addGroup(layout.createSequentialGroup()
375  .addContainerGap()
376  .addComponent(reportModulesLabel)
377  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
378  .addComponent(modulesSplitPane)
379  .addContainerGap())
380  );
381  }// </editor-fold>//GEN-END:initComponents
382  // Variables declaration - do not modify//GEN-BEGIN:variables
383  private javax.swing.JPanel configurationPanel;
384  private javax.swing.JScrollPane descriptionScrollPane;
385  private javax.swing.JTextPane descriptionTextPane;
386  private javax.swing.JList<ReportModule> modulesJList;
387  private javax.swing.JScrollPane modulesScrollPane;
388  private javax.swing.JLabel reportModulesLabel;
389  // End of variables declaration//GEN-END:variables
390 
391  @Override
392  public void valueChanged(ListSelectionEvent e) {
393  if (e.getValueIsAdjusting()) {
394  return;
395  }
396  configurationPanel.removeAll();
397  ListSelectionModel m = (ListSelectionModel) e.getSource();
398  // single selection, so max selection index is the only one selected.
399  selectedIndex = m.getMaxSelectionIndex();
400 
401  ReportModule module = modules.get(selectedIndex);
402  JPanel panel = module.getConfigurationPanel();
403  if (panel == null) {
404  panel = new JPanel();
405  }
406 
407  descriptionTextPane.setText(module.getDescription());
408  configurationPanel.add(panel, BorderLayout.CENTER);
409  configurationPanel.revalidate();
410  configurationPanel.repaint();
411 
412  // General modules that support data source selection will be presented
413  // a data source selection panel, so they should not be finished immediately.
414  boolean generalModuleSelected = (module instanceof GeneralReportModule) && (!((GeneralReportModule)module).supportsDataSourceSelection() || !displayCaseSpecificData);
415 
416  wizPanel.setNext(!generalModuleSelected);
417  wizPanel.setFinish(generalModuleSelected);
418  }
419 
420  private class ModuleCellRenderer extends JRadioButton implements ListCellRenderer<ReportModule> {
421 
422  @Override
423  public Component getListCellRendererComponent(JList<? extends ReportModule> list, ReportModule value, int index, boolean isSelected, boolean cellHasFocus) {
424  this.setText(value.getName());
425  this.setEnabled(true);
426  this.setSelected(isSelected);
427  return this;
428  }
429 
430  }
431 }
Component getListCellRendererComponent(JList<?extends ReportModule > list, ReportModule value, int index, boolean isSelected, boolean cellHasFocus)

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