19 package org.sleuthkit.autopsy.casemodule;
21 import java.beans.PropertyChangeListener;
22 import java.beans.PropertyChangeSupport;
23 import java.util.Collection;
24 import java.util.Objects;
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;
43 "AddImageWizardSelectHostVisual_title=Select Host"
45 class AddImageWizardSelectHostVisual extends javax.swing.JPanel {
52 private final Host host;
72 if (host == null || host.getName() == null) {
75 return host.getName();
82 hash = 41 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getHostId());
94 if (getClass() != obj.getClass()) {
99 this.host == null ? 0 :
this.host.getHostId(),
100 other.
host == null ? 0 : other.
host.getHostId())) {
109 private static final Logger logger =
Logger.
getLogger(AddImageWizardSelectHostVisual.class.getName());
111 private final PropertyChangeSupport changeSupport =
new PropertyChangeSupport(
this);
112 private Set<String> sanitizedHostSet = null;
117 AddImageWizardSelectHostVisual() {
120 specifyNewHostTextField.getDocument().addDocumentListener(
new DocumentListener() {
122 public void changedUpdate(DocumentEvent e) {
127 public void removeUpdate(DocumentEvent e) {
132 public void insertUpdate(DocumentEvent e) {
137 existingHostList.addListSelectionListener((evt) -> refresh());
148 void addListener(PropertyChangeListener pcl) {
149 changeSupport.addPropertyChangeListener(pcl);
157 void removeListener(PropertyChangeListener pcl) {
158 changeSupport.removePropertyChangeListener(pcl);
165 Host getSelectedHost() {
166 if (specifyNewHostRadio.isSelected() && StringUtils.isNotEmpty(specifyNewHostTextField.getText())) {
167 String newHostName = specifyNewHostTextField.getText();
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);
174 }
else if (useExistingHostRadio.isSelected()
175 && existingHostList.getSelectedValue() != null
176 && existingHostList.getSelectedValue().getHost() != null) {
178 return existingHostList.getSelectedValue().getHost();
187 private void loadHostData() {
189 Collection<Host> hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getAllHosts();
190 sanitizedHostSet = HostNameValidator.getSanitizedHostNames(hosts);
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));
198 existingHostList.setListData(hostListItems);
199 }
catch (NoCurrentCaseException | TskCoreException ex) {
200 logger.log(Level.WARNING,
"Unable to display host items with no current case.", ex);
211 private String getNameOrEmpty(Host host) {
212 return host == null || host.getName() == null ?
"" : host.getName();
215 private void refresh() {
216 specifyNewHostTextField.setEnabled(specifyNewHostRadio.isSelected());
217 existingHostList.setEnabled(useExistingHostRadio.isSelected());
219 String prevValidationMessage = validationMessage.getText();
220 String newValidationMessage = getValidationMessage();
221 validationMessage.setText(newValidationMessage);
223 if (StringUtils.isBlank(prevValidationMessage) != StringUtils.isBlank(newValidationMessage)) {
224 changeSupport.firePropertyChange(
"validation", prevValidationMessage, newValidationMessage);
229 "AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host.",})
230 private String getValidationMessage() {
231 if (specifyNewHostRadio.isSelected()) {
233 return HostNameValidator.getValidationMessage(specifyNewHostTextField.getText(), null, sanitizedHostSet);
236 }
else if (useExistingHostRadio.isSelected()
237 && (existingHostList.getSelectedValue() == null
238 || existingHostList.getSelectedValue().getHost() == null)) {
239 return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected();
246 public String getName() {
247 return Bundle.AddImageWizardSelectHostVisual_title();
250 boolean hasValidData() {
251 return StringUtils.isBlank(validationMessage.getText());
259 @SuppressWarnings(
"unchecked")
261 private
void initComponents() {
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();
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"));
276 generateNewRadio.addActionListener(
new java.awt.event.ActionListener() {
277 public void actionPerformed(java.awt.event.ActionEvent evt) {
278 generateNewRadioActionPerformed(evt);
282 radioButtonGroup.add(specifyNewHostRadio);
283 org.openide.awt.Mnemonics.setLocalizedText(specifyNewHostRadio,
org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class,
"AddImageWizardSelectHostVisual.specifyNewHostRadio.text"));
284 specifyNewHostRadio.addActionListener(
new java.awt.event.ActionListener() {
285 public void actionPerformed(java.awt.event.ActionEvent evt) {
286 specifyNewHostRadioActionPerformed(evt);
290 specifyNewHostTextField.setText(
org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class,
"AddImageWizardSelectHostVisual.specifyNewHostTextField.text"));
292 radioButtonGroup.add(useExistingHostRadio);
293 org.openide.awt.Mnemonics.setLocalizedText(useExistingHostRadio,
org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class,
"AddImageWizardSelectHostVisual.useExistingHostRadio.text"));
294 useExistingHostRadio.addActionListener(
new java.awt.event.ActionListener() {
295 public void actionPerformed(java.awt.event.ActionEvent evt) {
296 useExistingHostRadioActionPerformed(evt);
300 existingHostList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
301 jScrollPane1.setViewportView(existingHostList);
303 org.openide.awt.Mnemonics.setLocalizedText(hostDescription,
org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class,
"AddImageWizardSelectHostVisual.hostDescription.text"));
305 validationMessage.setForeground(java.awt.Color.RED);
306 org.openide.awt.Mnemonics.setLocalizedText(validationMessage,
org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class,
"AddImageWizardSelectHostVisual.validationMessage.text"));
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()
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()
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)))
331 layout.setVerticalGroup(
332 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
333 .addGroup(layout.createSequentialGroup()
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)
347 .addComponent(validationMessage)
348 .addContainerGap(18, Short.MAX_VALUE))
352 private void generateNewRadioActionPerformed(java.awt.event.ActionEvent evt) {
356 private void specifyNewHostRadioActionPerformed(java.awt.event.ActionEvent evt) {
360 private void useExistingHostRadioActionPerformed(java.awt.event.ActionEvent evt) {
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;
boolean equals(Object obj)
synchronized static Logger getLogger(String name)