Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
AddImageWizardSelectHostVisual.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2021 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.casemodule;
20 
21 import java.beans.PropertyChangeListener;
22 import java.beans.PropertyChangeSupport;
23 import java.util.Collection;
24 import java.util.Objects;
25 import java.util.Set;
26 import java.util.Vector;
27 import java.util.logging.Level;
28 import java.util.stream.Collectors;
29 import javax.swing.event.DocumentEvent;
30 import javax.swing.event.DocumentListener;
31 import org.apache.commons.lang.StringUtils;
32 import org.openide.util.NbBundle.Messages;
35 import org.sleuthkit.datamodel.Host;
36 import org.sleuthkit.datamodel.TskCoreException;
37 
42 @Messages({
43  "AddImageWizardSelectHostVisual_title=Select Host"
44 })
45 class AddImageWizardSelectHostVisual extends javax.swing.JPanel {
46 
50  private static class HostListItem {
51 
52  private final Host host;
53 
59  HostListItem(Host host) {
60  this.host = host;
61  }
62 
66  Host getHost() {
67  return host;
68  }
69 
70  @Override
71  public String toString() {
72  if (host == null || host.getName() == null) {
73  return "";
74  } else {
75  return host.getName();
76  }
77  }
78 
79  @Override
80  public int hashCode() {
81  int hash = 7;
82  hash = 41 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getHostId());
83  return hash;
84  }
85 
86  @Override
87  public boolean equals(Object obj) {
88  if (this == obj) {
89  return true;
90  }
91  if (obj == null) {
92  return false;
93  }
94  if (getClass() != obj.getClass()) {
95  return false;
96  }
97  final HostListItem other = (HostListItem) obj;
98  if (!Objects.equals(
99  this.host == null ? 0 : this.host.getHostId(),
100  other.host == null ? 0 : other.host.getHostId())) {
101 
102  return false;
103  }
104  return true;
105  }
106 
107  }
108 
109  private static final Logger logger = Logger.getLogger(AddImageWizardSelectHostVisual.class.getName());
110 
111  private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
112  private Set<String> sanitizedHostSet = null;
113 
117  AddImageWizardSelectHostVisual() {
118  initComponents();
119 
120  specifyNewHostTextField.getDocument().addDocumentListener(new DocumentListener() {
121  @Override
122  public void changedUpdate(DocumentEvent e) {
123  refresh();
124  }
125 
126  @Override
127  public void removeUpdate(DocumentEvent e) {
128  refresh();
129  }
130 
131  @Override
132  public void insertUpdate(DocumentEvent e) {
133  refresh();
134  }
135  });
136 
137  existingHostList.addListSelectionListener((evt) -> refresh());
138 
139  loadHostData();
140  refresh();
141  }
142 
148  void addListener(PropertyChangeListener pcl) {
149  changeSupport.addPropertyChangeListener(pcl);
150  }
151 
157  void removeListener(PropertyChangeListener pcl) {
158  changeSupport.removePropertyChangeListener(pcl);
159  }
160 
165  Host getSelectedHost() {
166  if (specifyNewHostRadio.isSelected() && StringUtils.isNotEmpty(specifyNewHostTextField.getText())) {
167  String newHostName = specifyNewHostTextField.getText();
168  try {
169  return Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().newHost(newHostName);
170  } catch (NoCurrentCaseException | TskCoreException ex) {
171  logger.log(Level.WARNING, String.format("Unable to create host '%s'.", newHostName), ex);
172  return null;
173  }
174  } else if (useExistingHostRadio.isSelected()
175  && existingHostList.getSelectedValue() != null
176  && existingHostList.getSelectedValue().getHost() != null) {
177 
178  return existingHostList.getSelectedValue().getHost();
179  } else {
180  return null;
181  }
182  }
183 
187  private void loadHostData() {
188  try {
189  Collection<Host> hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getAllHosts();
190  sanitizedHostSet = HostNameValidator.getSanitizedHostNames(hosts);
191 
192  Vector<HostListItem> hostListItems = hosts.stream()
193  .filter(h -> h != null)
194  .sorted((a, b) -> getNameOrEmpty(a).compareToIgnoreCase(getNameOrEmpty(b)))
195  .map((h) -> new HostListItem(h))
196  .collect(Collectors.toCollection(Vector::new));
197 
198  existingHostList.setListData(hostListItems);
199  } catch (NoCurrentCaseException | TskCoreException ex) {
200  logger.log(Level.WARNING, "Unable to display host items with no current case.", ex);
201  }
202  }
203 
211  private String getNameOrEmpty(Host host) {
212  return host == null || host.getName() == null ? "" : host.getName();
213  }
214 
215  private void refresh() {
216  specifyNewHostTextField.setEnabled(specifyNewHostRadio.isSelected());
217  existingHostList.setEnabled(useExistingHostRadio.isSelected());
218 
219  String prevValidationMessage = validationMessage.getText();
220  String newValidationMessage = getValidationMessage();
221  validationMessage.setText(newValidationMessage);
222  // if validation message changed (empty to non-empty or vice-versa) fire validation update
223  if (StringUtils.isBlank(prevValidationMessage) != StringUtils.isBlank(newValidationMessage)) {
224  changeSupport.firePropertyChange("validation", prevValidationMessage, newValidationMessage);
225  }
226  }
227 
228  @Messages({
229  "AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host.",})
230  private String getValidationMessage() {
231  if (specifyNewHostRadio.isSelected()) {
232  // if problematic new name for host
233  return HostNameValidator.getValidationMessage(specifyNewHostTextField.getText(), null, sanitizedHostSet);
234 
235  // or use existing host and no host is selected
236  } else if (useExistingHostRadio.isSelected()
237  && (existingHostList.getSelectedValue() == null
238  || existingHostList.getSelectedValue().getHost() == null)) {
239  return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected();
240  }
241 
242  return null;
243  }
244 
245  @Override
246  public String getName() {
247  return Bundle.AddImageWizardSelectHostVisual_title();
248  }
249 
250  boolean hasValidData() {
251  return StringUtils.isBlank(validationMessage.getText());
252  }
253 
259  @SuppressWarnings("unchecked")
260  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
261  private void initComponents() {
262 
263  javax.swing.ButtonGroup radioButtonGroup = new javax.swing.ButtonGroup();
264  generateNewRadio = new javax.swing.JRadioButton();
265  specifyNewHostRadio = new javax.swing.JRadioButton();
266  specifyNewHostTextField = new javax.swing.JTextField();
267  useExistingHostRadio = new javax.swing.JRadioButton();
268  javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
269  existingHostList = new javax.swing.JList<>();
270  hostDescription = new javax.swing.JLabel();
271  validationMessage = new javax.swing.JLabel();
272 
273  radioButtonGroup.add(generateNewRadio);
274  generateNewRadio.setSelected(true);
275  org.openide.awt.Mnemonics.setLocalizedText(generateNewRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.generateNewRadio.text")); // NOI18N
276  generateNewRadio.addActionListener(new java.awt.event.ActionListener() {
277  public void actionPerformed(java.awt.event.ActionEvent evt) {
278  generateNewRadioActionPerformed(evt);
279  }
280  });
281 
282  radioButtonGroup.add(specifyNewHostRadio);
283  org.openide.awt.Mnemonics.setLocalizedText(specifyNewHostRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.specifyNewHostRadio.text")); // NOI18N
284  specifyNewHostRadio.addActionListener(new java.awt.event.ActionListener() {
285  public void actionPerformed(java.awt.event.ActionEvent evt) {
286  specifyNewHostRadioActionPerformed(evt);
287  }
288  });
289 
290  specifyNewHostTextField.setText(org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.specifyNewHostTextField.text")); // NOI18N
291 
292  radioButtonGroup.add(useExistingHostRadio);
293  org.openide.awt.Mnemonics.setLocalizedText(useExistingHostRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.useExistingHostRadio.text")); // NOI18N
294  useExistingHostRadio.addActionListener(new java.awt.event.ActionListener() {
295  public void actionPerformed(java.awt.event.ActionEvent evt) {
296  useExistingHostRadioActionPerformed(evt);
297  }
298  });
299 
300  existingHostList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
301  jScrollPane1.setViewportView(existingHostList);
302 
303  org.openide.awt.Mnemonics.setLocalizedText(hostDescription, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.hostDescription.text")); // NOI18N
304 
305  validationMessage.setForeground(java.awt.Color.RED);
306  org.openide.awt.Mnemonics.setLocalizedText(validationMessage, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.validationMessage.text")); // NOI18N
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  .addGroup(layout.createSequentialGroup()
313  .addContainerGap()
314  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
315  .addComponent(validationMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
316  .addGroup(layout.createSequentialGroup()
317  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
318  .addComponent(generateNewRadio)
319  .addComponent(useExistingHostRadio)
320  .addComponent(hostDescription)
321  .addGroup(layout.createSequentialGroup()
322  .addGap(21, 21, 21)
323  .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE))
324  .addGroup(layout.createSequentialGroup()
325  .addComponent(specifyNewHostRadio)
326  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
327  .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE)))
328  .addGap(0, 13, Short.MAX_VALUE)))
329  .addContainerGap())
330  );
331  layout.setVerticalGroup(
332  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
333  .addGroup(layout.createSequentialGroup()
334  .addContainerGap()
335  .addComponent(hostDescription)
336  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
337  .addComponent(generateNewRadio)
338  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
339  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
340  .addComponent(specifyNewHostRadio)
341  .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
342  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
343  .addComponent(useExistingHostRadio)
344  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
345  .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
346  .addGap(10, 10, 10)
347  .addComponent(validationMessage)
348  .addContainerGap(18, Short.MAX_VALUE))
349  );
350  }// </editor-fold>//GEN-END:initComponents
351 
352  private void generateNewRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateNewRadioActionPerformed
353  refresh();
354  }//GEN-LAST:event_generateNewRadioActionPerformed
355 
356  private void specifyNewHostRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyNewHostRadioActionPerformed
357  refresh();
358  }//GEN-LAST:event_specifyNewHostRadioActionPerformed
359 
360  private void useExistingHostRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useExistingHostRadioActionPerformed
361  refresh();
362  }//GEN-LAST:event_useExistingHostRadioActionPerformed
363 
364 
365  // Variables declaration - do not modify//GEN-BEGIN:variables
366  private javax.swing.JList<HostListItem> existingHostList;
367  private javax.swing.JRadioButton generateNewRadio;
368  private javax.swing.JLabel hostDescription;
369  private javax.swing.JRadioButton specifyNewHostRadio;
370  private javax.swing.JTextField specifyNewHostTextField;
371  private javax.swing.JRadioButton useExistingHostRadio;
372  private javax.swing.JLabel validationMessage;
373  // End of variables declaration//GEN-END:variables
374 }
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

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