Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
StringsContentPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-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.contentviewers.textcontentviewer;
20 
21 import java.awt.Cursor;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.concurrent.ExecutionException;
27 import java.util.logging.Level;
28 import org.openide.util.NbBundle;
30 import javax.swing.JMenuItem;
31 import javax.swing.JOptionPane;
32 import javax.swing.SwingWorker;
33 import org.apache.commons.lang3.StringUtils;
34 import org.openide.util.NbBundle.Messages;
40 import org.sleuthkit.datamodel.Content;
41 import org.sleuthkit.datamodel.TskCoreException;
42 
46 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
47 public class StringsContentPanel extends javax.swing.JPanel {
48 
49  private static long currentOffset = 0;
50  private static final long PAGE_LENGTH = 16384;
51  private static final long serialVersionUID = 1L;
52  private final byte[] data = new byte[(int) PAGE_LENGTH];
53  private static int currentPage = 1;
54  private Content dataSource;
55  private static final Logger logger = Logger.getLogger(StringsContentPanel.class.getName());
56 
57  private SwingWorker<String, Void> worker;
58 
63  initComponents();
64  customizeComponents();
65  this.resetDisplay();
66  }
67 
68  private void customizeComponents() {
69  outputViewPane.setComponentPopupMenu(rightClickMenu);
70  ActionListener actList = (ActionEvent e) -> {
71  JMenuItem jmi = (JMenuItem) e.getSource();
72  if (jmi.equals(copyMenuItem)) {
73  outputViewPane.copy();
74  } else if (jmi.equals(selectAllMenuItem)) {
75  outputViewPane.selectAll();
76  }
77  };
78  copyMenuItem.addActionListener(actList);
79  selectAllMenuItem.addActionListener(actList);
80 
81  List<SCRIPT> supportedScripts = StringExtract.getSupportedScripts();
82  supportedScripts.forEach((s) -> {
83  languageCombo.addItem(s);
84  });
85 
86  // use wrap layout for better component wrapping
87  WrapLayout layout = new WrapLayout(0, 5);
88  layout.setOppositeAligned(Arrays.asList(panelScriptSelect));
89  controlPanel.setLayout(layout);
90 
91  }
92 
93  final void resetDisplay() {
94  // clear / reset the fields
95  currentPage = 1;
96  currentOffset = 0;
97  this.dataSource = null;
98  currentPageLabel.setText("1");
99  totalPageLabel.setText("");
100  prevPageButton.setEnabled(false);
101  nextPageButton.setEnabled(false);
102  outputViewPane.setText(""); // reset the output view
103  }
104 
110  @SuppressWarnings("unchecked")
111  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
112  private void initComponents() {
113 
114  rightClickMenu = new javax.swing.JPopupMenu();
115  copyMenuItem = new javax.swing.JMenuItem();
116  selectAllMenuItem = new javax.swing.JMenuItem();
117  controlPanel = new javax.swing.JPanel();
118  javax.swing.JPanel panelPageOfCount = new javax.swing.JPanel();
119  pageLabel = new javax.swing.JLabel();
120  javax.swing.JSeparator jSepMed1 = new javax.swing.JSeparator();
121  currentPageLabel = new javax.swing.JLabel();
122  javax.swing.JSeparator jSepMed2 = new javax.swing.JSeparator();
123  ofLabel = new javax.swing.JLabel();
124  javax.swing.JSeparator jSepMed3 = new javax.swing.JSeparator();
125  totalPageLabel = new javax.swing.JLabel();
126  javax.swing.JSeparator jSepMed4 = new javax.swing.JSeparator();
127  javax.swing.JPanel panelPageNextPrevButton = new javax.swing.JPanel();
128  pageLabel2 = new javax.swing.JLabel();
129  javax.swing.JSeparator jSepMed5 = new javax.swing.JSeparator();
130  prevPageButton = new javax.swing.JButton();
131  nextPageButton = new javax.swing.JButton();
132  javax.swing.JSeparator jSepMed6 = new javax.swing.JSeparator();
133  javax.swing.JPanel panelGoToPage = new javax.swing.JPanel();
134  goToPageLabel = new javax.swing.JLabel();
135  javax.swing.JSeparator jSepSm1 = new javax.swing.JSeparator();
136  goToPageTextField = new javax.swing.JTextField();
137  javax.swing.JSeparator jSepMed7 = new javax.swing.JSeparator();
138  panelScriptSelect = new javax.swing.JPanel();
139  languageLabel = new javax.swing.JLabel();
140  javax.swing.JSeparator jSepSm2 = new javax.swing.JSeparator();
141  languageCombo = new javax.swing.JComboBox<>();
142  outputScrollPane = new javax.swing.JScrollPane();
143  outputViewPane = new javax.swing.JTextPane();
144 
145  copyMenuItem.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.copyMenuItem.text")); // NOI18N
146  rightClickMenu.add(copyMenuItem);
147 
148  selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.selectAllMenuItem.text")); // NOI18N
149  rightClickMenu.add(selectAllMenuItem);
150 
151  setMinimumSize(new java.awt.Dimension(250, 5));
152  setPreferredSize(new java.awt.Dimension(250, 58));
153  setLayout(new java.awt.BorderLayout());
154 
155  controlPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 5, 0));
156 
157  panelPageOfCount.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0));
158 
159  pageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.pageLabel.text_1")); // NOI18N
160  pageLabel.setMaximumSize(new java.awt.Dimension(33, 25));
161  pageLabel.setMinimumSize(new java.awt.Dimension(33, 25));
162  pageLabel.setPreferredSize(new java.awt.Dimension(32, 25));
163  panelPageOfCount.add(pageLabel);
164 
165  jSepMed1.setPreferredSize(new java.awt.Dimension(5, 0));
166  panelPageOfCount.add(jSepMed1);
167 
168  currentPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.currentPageLabel.text_1")); // NOI18N
169  panelPageOfCount.add(currentPageLabel);
170 
171  jSepMed2.setPreferredSize(new java.awt.Dimension(5, 0));
172  panelPageOfCount.add(jSepMed2);
173 
174  ofLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.ofLabel.text_1")); // NOI18N
175  ofLabel.setMaximumSize(new java.awt.Dimension(11, 25));
176  ofLabel.setMinimumSize(new java.awt.Dimension(11, 25));
177  ofLabel.setPreferredSize(new java.awt.Dimension(11, 25));
178  panelPageOfCount.add(ofLabel);
179 
180  jSepMed3.setPreferredSize(new java.awt.Dimension(5, 0));
181  panelPageOfCount.add(jSepMed3);
182 
183  totalPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.totalPageLabel.text_1")); // NOI18N
184  totalPageLabel.setMaximumSize(new java.awt.Dimension(25, 25));
185  totalPageLabel.setMinimumSize(new java.awt.Dimension(25, 25));
186  totalPageLabel.setPreferredSize(new java.awt.Dimension(25, 25));
187  panelPageOfCount.add(totalPageLabel);
188 
189  jSepMed4.setPreferredSize(new java.awt.Dimension(5, 0));
190  panelPageOfCount.add(jSepMed4);
191 
192  controlPanel.add(panelPageOfCount);
193 
194  panelPageNextPrevButton.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0));
195 
196  pageLabel2.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.pageLabel2.text")); // NOI18N
197  pageLabel2.setMaximumSize(new java.awt.Dimension(29, 25));
198  pageLabel2.setMinimumSize(new java.awt.Dimension(29, 25));
199  pageLabel2.setPreferredSize(new java.awt.Dimension(29, 25));
200  panelPageNextPrevButton.add(pageLabel2);
201 
202  jSepMed5.setPreferredSize(new java.awt.Dimension(5, 0));
203  panelPageNextPrevButton.add(jSepMed5);
204 
205  prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
206  prevPageButton.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.prevPageButton.text")); // NOI18N
207  prevPageButton.setBorderPainted(false);
208  prevPageButton.setContentAreaFilled(false);
209  prevPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
210  prevPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
211  prevPageButton.setMaximumSize(new java.awt.Dimension(25, 25));
212  prevPageButton.setMinimumSize(new java.awt.Dimension(20, 25));
213  prevPageButton.setPreferredSize(new java.awt.Dimension(25, 25));
214  prevPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N
215  prevPageButton.addActionListener(new java.awt.event.ActionListener() {
216  public void actionPerformed(java.awt.event.ActionEvent evt) {
217  prevPageButtonActionPerformed(evt);
218  }
219  });
220  panelPageNextPrevButton.add(prevPageButton);
221 
222  nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N
223  nextPageButton.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.nextPageButton.text")); // NOI18N
224  nextPageButton.setBorderPainted(false);
225  nextPageButton.setContentAreaFilled(false);
226  nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
227  nextPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
228  nextPageButton.setMaximumSize(new java.awt.Dimension(25, 25));
229  nextPageButton.setMinimumSize(new java.awt.Dimension(20, 25));
230  nextPageButton.setPreferredSize(new java.awt.Dimension(25, 25));
231  nextPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N
232  nextPageButton.addActionListener(new java.awt.event.ActionListener() {
233  public void actionPerformed(java.awt.event.ActionEvent evt) {
234  nextPageButtonActionPerformed(evt);
235  }
236  });
237  panelPageNextPrevButton.add(nextPageButton);
238 
239  jSepMed6.setPreferredSize(new java.awt.Dimension(5, 0));
240  panelPageNextPrevButton.add(jSepMed6);
241 
242  controlPanel.add(panelPageNextPrevButton);
243 
244  panelGoToPage.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0));
245 
246  goToPageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.goToPageLabel.text")); // NOI18N
247  panelGoToPage.add(goToPageLabel);
248 
249  jSepSm1.setPreferredSize(new java.awt.Dimension(2, 0));
250  panelGoToPage.add(jSepSm1);
251 
252  goToPageTextField.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.goToPageTextField.text")); // NOI18N
253  goToPageTextField.setMaximumSize(new java.awt.Dimension(2147483647, 25));
254  goToPageTextField.setMinimumSize(new java.awt.Dimension(50, 25));
255  goToPageTextField.setPreferredSize(new java.awt.Dimension(70, 25));
256  goToPageTextField.addActionListener(new java.awt.event.ActionListener() {
257  public void actionPerformed(java.awt.event.ActionEvent evt) {
258  goToPageTextFieldActionPerformed(evt);
259  }
260  });
261  panelGoToPage.add(goToPageTextField);
262 
263  jSepMed7.setPreferredSize(new java.awt.Dimension(5, 0));
264  panelGoToPage.add(jSepMed7);
265 
266  controlPanel.add(panelGoToPage);
267 
268  panelScriptSelect.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 0));
269 
270  languageLabel.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.languageLabel.text")); // NOI18N
271  languageLabel.setToolTipText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.languageLabel.toolTipText")); // NOI18N
272  panelScriptSelect.add(languageLabel);
273 
274  jSepSm2.setPreferredSize(new java.awt.Dimension(2, 0));
275  panelScriptSelect.add(jSepSm2);
276 
277  languageCombo.setToolTipText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.languageCombo.toolTipText")); // NOI18N
278  languageCombo.setMinimumSize(new java.awt.Dimension(150, 25));
279  languageCombo.setPreferredSize(new java.awt.Dimension(150, 25));
280  languageCombo.addActionListener(new java.awt.event.ActionListener() {
281  public void actionPerformed(java.awt.event.ActionEvent evt) {
282  languageComboActionPerformed(evt);
283  }
284  });
285  panelScriptSelect.add(languageCombo);
286 
287  controlPanel.add(panelScriptSelect);
288 
289  add(controlPanel, java.awt.BorderLayout.NORTH);
290 
291  outputViewPane.setEditable(false);
292  outputScrollPane.setViewportView(outputViewPane);
293 
294  add(outputScrollPane, java.awt.BorderLayout.CENTER);
295  }// </editor-fold>//GEN-END:initComponents
296 
297  private void languageComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_languageComboActionPerformed
298  if (dataSource != null) {
299  setDataView(dataSource, currentOffset);
300  }
301  }//GEN-LAST:event_languageComboActionPerformed
302 
303  private void goToPageTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToPageTextFieldActionPerformed
304  String pageNumberStr = goToPageTextField.getText();
305  int pageNumber;
306  int maxPage = Math.round((dataSource.getSize() - 1) / PAGE_LENGTH) + 1;
307  try {
308  pageNumber = Integer.parseInt(pageNumberStr);
309  } catch (NumberFormatException ex) {
310  pageNumber = maxPage + 1;
311  }
312  if (pageNumber > maxPage || pageNumber < 1) {
313  JOptionPane.showMessageDialog(this,
314  NbBundle.getMessage(this.getClass(),
315  "StringsTextViewer.goToPageTextField.msgDlg",
316  maxPage),
317  NbBundle.getMessage(this.getClass(),
318  "StringsTextViewer.goToPageTextField.err"),
319  JOptionPane.WARNING_MESSAGE);
320  return;
321  }
322  currentOffset = (pageNumber - 1) * PAGE_LENGTH;
323  currentPage = pageNumber;
324  currentPageLabel.setText(Integer.toString(currentPage));
325  setDataView(dataSource, currentOffset);
326  }//GEN-LAST:event_goToPageTextFieldActionPerformed
327 
328  private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
329  //@@@ this is part of the code dealing with the data viewer. could be copied/removed to implement the scrollbar
330  currentOffset -= PAGE_LENGTH;
331  currentPage -= 1;
332  currentPageLabel.setText(Integer.toString(currentPage));
333  setDataView(dataSource, currentOffset);
334  }//GEN-LAST:event_prevPageButtonActionPerformed
335 
336  private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
337  //@@@ this is part of the code dealing with the data viewer. could be copied/removed to implement the scrollbar
338  currentOffset += PAGE_LENGTH;
339  currentPage += 1;
340  currentPageLabel.setText(Integer.toString(currentPage));
341  setDataView(dataSource, currentOffset);
342  }//GEN-LAST:event_nextPageButtonActionPerformed
343 
344  // Variables declaration - do not modify//GEN-BEGIN:variables
345  private javax.swing.JPanel controlPanel;
346  private javax.swing.JMenuItem copyMenuItem;
347  private javax.swing.JLabel currentPageLabel;
348  private javax.swing.JLabel goToPageLabel;
349  private javax.swing.JTextField goToPageTextField;
350  private javax.swing.JComboBox<SCRIPT> languageCombo;
351  private javax.swing.JLabel languageLabel;
352  private javax.swing.JButton nextPageButton;
353  private javax.swing.JLabel ofLabel;
354  private javax.swing.JScrollPane outputScrollPane;
355  private javax.swing.JTextPane outputViewPane;
356  private javax.swing.JLabel pageLabel;
357  private javax.swing.JLabel pageLabel2;
358  private javax.swing.JPanel panelScriptSelect;
359  private javax.swing.JButton prevPageButton;
360  private javax.swing.JPopupMenu rightClickMenu;
361  private javax.swing.JMenuItem selectAllMenuItem;
362  private javax.swing.JLabel totalPageLabel;
363  // End of variables declaration//GEN-END:variables
364 
365  @Messages({
366  "StringContentPanel_Loading_String=Loading text..."
367  })
368 
375  void setDataView(Content dataSource, long offset) {
376 
377  if (worker != null) {
378  worker.cancel(true);
379  worker = null;
380  }
381 
382  if (dataSource == null) {
383  return;
384  }
385 
386  worker = new ContentWorker(dataSource, offset);
387  outputViewPane.setText(Bundle.StringContentPanel_Loading_String());
388  setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
389  worker.execute();
390  }
391 
392  void setDataView(StringContent dataSource) {
393  if (worker != null) {
394  worker.cancel(true);
395  worker = null;
396  }
397 
398  if (dataSource == null) {
399  return;
400  }
401 
402  worker = new StringContentWorker(dataSource);
403  outputViewPane.setText(Bundle.StringContentPanel_Loading_String());
404  setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
405  worker.execute();
406  }
407 
408 
412  private final class ContentWorker extends SwingWorker<String, Void> {
413 
414  private final Content content;
415  private final long offset;
416 
423  ContentWorker(Content content, long offset) {
424  this.content = content;
425  this.offset = offset;
426  }
427 
428  @Override
429  protected String doInBackground() throws Exception {
430  int bytesRead = 0;
431  // set the data on the bottom and show it
432 
433  if (content.getSize() > 0) {
434  try {
435  bytesRead = content.read(data, offset, PAGE_LENGTH); // read the data
436  } catch (TskCoreException ex) {
437  logger.log(Level.WARNING, "Error while trying to show the String content.", ex); //NON-NLS
438  }
439  }
440  String text;
441  if (bytesRead > 0) {
442  //text = DataConversion.getString(data, bytesRead, 4);
443  final SCRIPT selScript = (SCRIPT) languageCombo.getSelectedItem();
444  StringExtract stringExtract = new StringExtract();
445  stringExtract.setEnabledScript(selScript);
446  StringExtractResult res = stringExtract.extract(data, bytesRead, 0);
447  text = res.getText();
448  if (StringUtils.isBlank(text)) {
449  text = NbBundle.getMessage(this.getClass(),
450  "StringsTextViewer.setDataView.errorNoText", currentOffset,
451  currentOffset + PAGE_LENGTH);
452  }
453  } else {
454  text = NbBundle.getMessage(this.getClass(), "StringsTextViewer.setDataView.errorText", currentOffset,
455  currentOffset + PAGE_LENGTH);
456  }
457 
458  return text;
459  }
460 
461  @Override
462  public void done() {
463  if (isCancelled()) {
464  return;
465  }
466 
467  try {
468  if (isCancelled()) {
469  return;
470  }
471  String text = get();
472  dataSource = content;
473 
474  // disable or enable the next button
475  if (offset + PAGE_LENGTH < dataSource.getSize()) {
476  nextPageButton.setEnabled(true);
477  } else {
478  nextPageButton.setEnabled(false);
479  }
480 
481  if (offset == 0) {
482  prevPageButton.setEnabled(false);
483  currentPage = 1; // reset the page number
484  } else {
485  prevPageButton.setEnabled(true);
486  }
487 
488  int totalPage = Math.round((dataSource.getSize() - 1) / PAGE_LENGTH) + 1;
489  totalPageLabel.setText(Integer.toString(totalPage));
490  outputViewPane.setText(text); // set the output view
491  outputViewPane.moveCaretPosition(0);
492 
493  setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
494 
495  } catch (InterruptedException | ExecutionException ex) {
496  logger.log(Level.SEVERE, String.format("Failed to get text from content (id=%d)", content.getId()), ex);
497  }
498  }
499  }
500 
504  private final class StringContentWorker extends SwingWorker<String, Void> {
505 
506  private final StringContent content;
507 
514  this.content = content;
515  }
516 
517  @Override
518  protected String doInBackground() throws Exception {
519  return content.getString();
520  }
521 
522  @Override
523  public void done() {
524  if (isCancelled()) {
525  return;
526  }
527 
528  try {
529  String text = get();
530 
531  dataSource = null;
532  nextPageButton.setEnabled(false);
533  prevPageButton.setEnabled(false);
534  currentPage = 1;
535 
536  outputViewPane.setText(text); // set the output view
537  outputViewPane.moveCaretPosition(0);
538  setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
539 
540  } catch (InterruptedException | ExecutionException ex) {
541  logger.log(Level.SEVERE, String.format("Failed to get text from StringContent"), ex);
542  }
543  }
544  }
545 }
StringExtractResult extract(byte[] buff, int len, int offset)
void setOppositeAligned(Collection< Component > oppAlignedComponents)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

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