Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
PersonasTopComponent.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 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 */
19package org.sleuthkit.autopsy.centralrepository.persona;
20
21import java.awt.event.ActionEvent;
22import java.awt.event.ActionListener;
23import java.awt.event.ComponentAdapter;
24import java.awt.event.ComponentEvent;
25import java.util.ArrayList;
26import java.util.Collection;
27import java.util.List;
28import java.util.logging.Level;
29import javax.swing.JOptionPane;
30import javax.swing.JTable;
31import javax.swing.ListSelectionModel;
32import javax.swing.event.AncestorListener;
33import javax.swing.event.AncestorEvent;
34import javax.swing.event.ListSelectionEvent;
35import javax.swing.event.ListSelectionListener;
36import javax.swing.table.DefaultTableModel;
37import org.openide.DialogDisplayer;
38import org.openide.NotifyDescriptor;
39import org.openide.util.NbBundle.Messages;
40import org.openide.windows.RetainLocation;
41import org.openide.windows.TopComponent;
42import org.openide.windows.WindowManager;
43import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
44import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
45import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
46import org.sleuthkit.autopsy.coreutils.Logger;
47
52@TopComponent.Description(preferredID = "PersonasTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
53@TopComponent.Registration(mode = "personas", openAtStartup = false)
54@RetainLocation("personas")
55@SuppressWarnings("PMD.SingularField")
56public final class PersonasTopComponent extends TopComponent {
57
58 private static final long serialVersionUID = 1L;
59
60 private static final Logger logger = Logger.getLogger(PersonasTopComponent.class.getName());
61
62 private List<Persona> currentResults = null;
63 private Persona selectedPersona = null;
64
65 @Messages({
66 "PersonasTopComponent_Name=Personas",
67 "PersonasTopComponent_delete_exception_Title=Delete failure",
68 "PersonasTopComponent_delete_exception_msg=Failed to delete persona.",
69 "PersonasTopComponent_delete_confirmation_Title=Are you sure?",
70 "PersonasTopComponent_delete_confirmation_msg=Are you sure you want to delete this persona?",})
73 setName(Bundle.PersonasTopComponent_Name());
74
75 searchBtn.addActionListener(new ActionListener() {
76 @Override
77 public void actionPerformed(ActionEvent e) {
79 }
80 });
81
82 editBtn.addActionListener(new ActionListener() {
83 @Override
84 public void actionPerformed(ActionEvent e) {
86 PersonaDetailsMode.EDIT, selectedPersona, new CreateEditCallbackImpl());
87 }
88 });
89
90 createBtn.addActionListener(new ActionListener() {
91 @Override
92 public void actionPerformed(ActionEvent e) {
94 PersonaDetailsMode.CREATE, selectedPersona, new CreateEditCallbackImpl());
95 }
96 });
97
98 deleteBtn.addActionListener(new ActionListener() {
99 @Override
100 public void actionPerformed(ActionEvent e) {
101 NotifyDescriptor confirm = new NotifyDescriptor.Confirmation(
102 Bundle.PersonasTopComponent_delete_confirmation_msg(),
103 Bundle.PersonasTopComponent_delete_confirmation_Title(),
104 NotifyDescriptor.YES_NO_OPTION);
105 DialogDisplayer.getDefault().notify(confirm);
106 if (confirm.getValue().equals(NotifyDescriptor.YES_OPTION)) {
107 try {
108 if (selectedPersona != null) {
109 selectedPersona.delete();
110 }
111 } catch (CentralRepoException ex) {
112 logger.log(Level.SEVERE, "Failed to delete persona: " + selectedPersona.getName(), ex);
113 JOptionPane.showMessageDialog(PersonasTopComponent.this,
114 Bundle.PersonasTopComponent_delete_exception_msg(),
115 Bundle.PersonasTopComponent_delete_exception_Title(),
116 JOptionPane.ERROR_MESSAGE);
117 return;
118 }
120 }
121 }
122 });
123
124 // Results table
125 resultsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
126 resultsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
127 @Override
128 public void valueChanged(ListSelectionEvent e) {
130 }
131 });
132
133 createAccountBtn.addActionListener(new ActionListener() {
134 @Override
135 public void actionPerformed(ActionEvent e) {
137 }
138 });
139
144 addComponentListener(new ComponentAdapter() {
145 @Override
146 public void componentShown(ComponentEvent e) {
148 setKeywordSearchEnabled(false, true);
149 }
150 });
151 }
152
156 class CreateEditCallbackImpl implements PersonaDetailsDialogCallback {
157
158 @Override
159 public void callback(Persona persona) {
160 if (persona != null) {
161 searchField.setText("");
162 executeSearch();
163 int personaRow = currentResults.indexOf(persona);
164 resultsTable.getSelectionModel().setSelectionInterval(personaRow, personaRow);
165 handleSelectionChange();
166 }
167 createBtn.setEnabled(true);
168 }
169 }
170
174 private void resetSearchControls() {
175 searchField.setText("");
176 searchNameRadio.setSelected(true);
177 searchAccountRadio.setSelected(false);
178 }
179
187 private void setKeywordSearchEnabled(boolean selected, boolean setFilterCb) {
188 if (setFilterCb && cbFilterByKeyword.isSelected() != selected) {
189 cbFilterByKeyword.setSelected(selected);
190 }
191
192 searchField.setEnabled(selected);
193 searchNameRadio.setEnabled(selected);
194 searchAccountRadio.setEnabled(selected);
195
197 }
198
199 void setPersona(int index) {
200 Persona persona = currentResults.get(index);
201 selectedPersona = persona;
202 editBtn.setEnabled(true);
203 deleteBtn.setEnabled(true);
204 }
205
209 final class PersonaFilterTableModel extends DefaultTableModel {
210
211 private static final long serialVersionUID = 1L;
212
213 PersonaFilterTableModel(Object[][] rows, String[] colNames) {
214 super(rows, colNames);
215 }
216
217 @Override
218 public boolean isCellEditable(int row, int column) {
219 return false;
220 }
221 }
222
223 private void handleSelectionChange(ListSelectionEvent e) {
224 if (e.getValueIsAdjusting()) {
225 return;
226 }
228 }
229
230 private void handleSelectionChange() {
231 int selectedRow = resultsTable.getSelectedRow();
232 if (selectedRow != -1) {
233 setPersona(resultsTable.getSelectedRow());
235 } else {
236 detailsPanel.clear();
237 }
238 }
239
240 private void updateResultsTable(Collection<Persona> results) {
241 Object[][] rows = new Object[results.size()][2];
242 int i = 0;
243 for (Persona result : results) {
244 rows[i] = new Object[]{result.getId(), result.getName()};
245 i++;
246 }
247 PersonaFilterTableModel updatedTableModel = new PersonaFilterTableModel(
248 rows,
249 new String[]{"ID", "Name"}
250 );
251
252 resultsTable.setModel(updatedTableModel);
253 currentResults = new ArrayList<>(results);
254
255 // Formatting
256 resultsTable.getColumnModel().getColumn(0).setMaxWidth(100);
257 resultsTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
258 }
259
260 @Messages({
261 "PersonasTopComponent_search_exception_Title=There was a failure during the search. Try opening a case to fully initialize the central repository database.",
262 "PersonasTopComponent_search_exception_msg=Failed to search personas.",
263 "PersonasTopComponent_noCR_msg=Central Repository is not enabled.",})
264 private void executeSearch() {
265 // To prevent downstream failures, only execute search if central repository is enabled
267 logger.log(Level.SEVERE, "Central Repository is not enabled, but execute search was called.");
268 JOptionPane.showMessageDialog(this,
269 Bundle.PersonasTopComponent_search_exception_Title(),
270 Bundle.PersonasTopComponent_noCR_msg(),
271 JOptionPane.ERROR_MESSAGE);
272 return;
273 }
274
275 Collection<Persona> results;
276 try {
277 if (cbFilterByKeyword.isSelected()) {
278 if (searchNameRadio.isSelected()) {
279 results = Persona.getPersonaByName(searchField.getText());
280 } else {
282 }
283 } else {
284 results = Persona.getPersonaByName("");
285 }
286 } catch (CentralRepoException ex) {
287 logger.log(Level.SEVERE, "Failed to search personas", ex);
288 JOptionPane.showMessageDialog(this,
289 Bundle.PersonasTopComponent_search_exception_Title(),
290 Bundle.PersonasTopComponent_search_exception_msg(),
291 JOptionPane.ERROR_MESSAGE);
292 return;
293 }
294
295 resultsTable.clearSelection();
296 updateResultsTable(results);
297 editBtn.setEnabled(false);
298 deleteBtn.setEnabled(false);
299 }
300
301 @Override
302 public void componentOpened() {
303 super.componentOpened();
304 WindowManager.getDefault().setTopComponentFloating(this, true);
305 }
306
312 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
313 private void initComponents() {
314
315 searchButtonGroup = new javax.swing.ButtonGroup();
316 introTextScrollPane = new javax.swing.JScrollPane();
317 introText = new javax.swing.JTextArea();
318 mainSplitPane = new javax.swing.JSplitPane();
319 searchPanel = new javax.swing.JPanel();
320 searchField = new javax.swing.JTextField();
321 searchNameRadio = new javax.swing.JRadioButton();
322 searchAccountRadio = new javax.swing.JRadioButton();
323 searchBtn = new javax.swing.JButton();
324 resultsPane = new javax.swing.JScrollPane();
325 resultsTable = new javax.swing.JTable();
326 createAccountBtn = new javax.swing.JButton();
327 editBtn = new javax.swing.JButton();
328 deleteBtn = new javax.swing.JButton();
329 createButtonSeparator = new javax.swing.JSeparator();
330 createBtn = new javax.swing.JButton();
331 cbFilterByKeyword = new javax.swing.JCheckBox();
332 detailsScrollPane = new javax.swing.JScrollPane();
333 detailsPanel = new org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel();
334
335 setName(""); // NOI18N
336
337 introTextScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
338
339 introText.setBackground(getBackground());
340 introText.setColumns(20);
341 introText.setLineWrap(true);
342 introText.setRows(5);
343 introText.setText(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.introText.text")); // NOI18N
344 introText.setWrapStyleWord(true);
345 introText.setFocusable(false);
346 introTextScrollPane.setViewportView(introText);
347
348 mainSplitPane.setDividerLocation(400);
349
350 searchField.setText(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.searchField.text")); // NOI18N
351
353 searchNameRadio.setSelected(true);
354 org.openide.awt.Mnemonics.setLocalizedText(searchNameRadio, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.searchNameRadio.text")); // NOI18N
355
357 org.openide.awt.Mnemonics.setLocalizedText(searchAccountRadio, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.searchAccountRadio.text")); // NOI18N
358
359 org.openide.awt.Mnemonics.setLocalizedText(searchBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.searchBtn.text")); // NOI18N
360
361 resultsTable.setToolTipText(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.resultsTable.toolTipText")); // NOI18N
362 resultsTable.getTableHeader().setReorderingAllowed(false);
363 resultsPane.setViewportView(resultsTable);
364 if (resultsTable.getColumnModel().getColumnCount() > 0) {
365 resultsTable.getColumnModel().getColumn(0).setMaxWidth(25);
366 resultsTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.resultsTable.columnModel.title0")); // NOI18N
367 resultsTable.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.resultsTable.columnModel.title1")); // NOI18N
368 }
369
370 org.openide.awt.Mnemonics.setLocalizedText(createAccountBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.createAccountBtn.text")); // NOI18N
371
372 org.openide.awt.Mnemonics.setLocalizedText(editBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.editBtn.text")); // NOI18N
373 editBtn.setEnabled(false);
374
375 org.openide.awt.Mnemonics.setLocalizedText(deleteBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.deleteBtn.text")); // NOI18N
376 deleteBtn.setEnabled(false);
377
378 org.openide.awt.Mnemonics.setLocalizedText(createBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.createBtn.text")); // NOI18N
379
380 org.openide.awt.Mnemonics.setLocalizedText(cbFilterByKeyword, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.cbFilterByKeyword.text")); // NOI18N
381 cbFilterByKeyword.addActionListener(new java.awt.event.ActionListener() {
382 public void actionPerformed(java.awt.event.ActionEvent evt) {
383 cbFilterByKeywordActionPerformed(evt);
384 }
385 });
386
387 javax.swing.GroupLayout searchPanelLayout = new javax.swing.GroupLayout(searchPanel);
388 searchPanel.setLayout(searchPanelLayout);
389 searchPanelLayout.setHorizontalGroup(
390 searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
391 .addGroup(searchPanelLayout.createSequentialGroup()
392 .addContainerGap()
393 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
394 .addComponent(createButtonSeparator)
395 .addComponent(resultsPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
396 .addComponent(searchField)
397 .addGroup(searchPanelLayout.createSequentialGroup()
398 .addComponent(searchNameRadio)
399 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
400 .addComponent(searchAccountRadio)
401 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
402 .addComponent(searchBtn))
403 .addGroup(searchPanelLayout.createSequentialGroup()
404 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
405 .addComponent(createAccountBtn)
406 .addGroup(searchPanelLayout.createSequentialGroup()
407 .addComponent(createBtn)
408 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
409 .addComponent(editBtn)
410 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
411 .addComponent(deleteBtn))
412 .addComponent(cbFilterByKeyword))
413 .addGap(0, 50, Short.MAX_VALUE)))
414 .addContainerGap())
415 );
416 searchPanelLayout.setVerticalGroup(
417 searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
418 .addGroup(searchPanelLayout.createSequentialGroup()
419 .addComponent(cbFilterByKeyword)
420 .addGap(1, 1, 1)
421 .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
422 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
423 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
424 .addComponent(searchNameRadio)
425 .addComponent(searchAccountRadio)
426 .addComponent(searchBtn))
427 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
428 .addComponent(resultsPane, javax.swing.GroupLayout.PREFERRED_SIZE, 302, javax.swing.GroupLayout.PREFERRED_SIZE)
429 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
430 .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
431 .addComponent(editBtn)
432 .addComponent(createBtn)
433 .addComponent(deleteBtn))
434 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
435 .addComponent(createButtonSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 4, javax.swing.GroupLayout.PREFERRED_SIZE)
436 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
437 .addComponent(createAccountBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
438 .addContainerGap())
439 );
440
441 mainSplitPane.setLeftComponent(searchPanel);
442
443 detailsScrollPane.setViewportView(detailsPanel);
444
445 mainSplitPane.setRightComponent(detailsScrollPane);
446
447 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
448 this.setLayout(layout);
449 layout.setHorizontalGroup(
450 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
451 .addComponent(introTextScrollPane)
452 .addComponent(mainSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 724, Short.MAX_VALUE)
453 );
454 layout.setVerticalGroup(
455 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
456 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
457 .addComponent(introTextScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
458 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
459 .addComponent(mainSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 489, Short.MAX_VALUE))
460 );
461 }// </editor-fold>//GEN-END:initComponents
462
463 private void cbFilterByKeywordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbFilterByKeywordActionPerformed
464 setKeywordSearchEnabled(cbFilterByKeyword.isSelected(), false);
465 }//GEN-LAST:event_cbFilterByKeywordActionPerformed
466
467 // Variables declaration - do not modify//GEN-BEGIN:variables
468 private javax.swing.JCheckBox cbFilterByKeyword;
469 private javax.swing.JButton createAccountBtn;
470 private javax.swing.JButton createBtn;
471 private javax.swing.JSeparator createButtonSeparator;
472 private javax.swing.JButton deleteBtn;
474 private javax.swing.JScrollPane detailsScrollPane;
475 private javax.swing.JButton editBtn;
476 private javax.swing.JTextArea introText;
477 private javax.swing.JScrollPane introTextScrollPane;
478 private javax.swing.JSplitPane mainSplitPane;
479 private javax.swing.JScrollPane resultsPane;
480 private javax.swing.JTable resultsTable;
481 private javax.swing.JRadioButton searchAccountRadio;
482 private javax.swing.JButton searchBtn;
483 private javax.swing.ButtonGroup searchButtonGroup;
484 private javax.swing.JTextField searchField;
485 private javax.swing.JRadioButton searchNameRadio;
486 private javax.swing.JPanel searchPanel;
487 // End of variables declaration//GEN-END:variables
488
489}
static Collection< Persona > getPersonaByAccountIdentifierLike(String partialName)
Definition Persona.java:489
static Collection< Persona > getPersonaByName(String partialName)
Definition Persona.java:438
org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel detailsPanel
synchronized static Logger getLogger(String name)
Definition Logger.java:124

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.