Autopsy 4.22.1
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 */
19package org.sleuthkit.autopsy.contentviewers.textcontentviewer;
20
21import java.awt.Cursor;
22import java.awt.event.ActionEvent;
23import java.awt.event.ActionListener;
24import java.util.Arrays;
25import java.util.List;
26import java.util.concurrent.ExecutionException;
27import java.util.logging.Level;
28import org.openide.util.NbBundle;
29import org.sleuthkit.autopsy.coreutils.Logger;
30import javax.swing.JMenuItem;
31import javax.swing.JOptionPane;
32import javax.swing.SwingWorker;
33import org.apache.commons.lang3.StringUtils;
34import org.openide.util.NbBundle.Messages;
35import org.sleuthkit.autopsy.coreutils.StringExtract;
36import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractResult;
37import org.sleuthkit.autopsy.coreutils.StringExtract.StringExtractUnicodeTable.SCRIPT;
38import org.sleuthkit.autopsy.datamodel.StringContent;
39import org.sleuthkit.autopsy.guiutils.WrapLayout;
40import org.sleuthkit.datamodel.Content;
41import org.sleuthkit.datamodel.TskCoreException;
42
46@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
47public 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
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
147
148 selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(StringsContentPanel.class, "StringsContentPanel.selectAllMenuItem.text")); // NOI18N
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
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
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,
452 }
453 } else {
454 text = NbBundle.getMessage(this.getClass(), "StringsTextViewer.setDataView.errorText", currentOffset,
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();
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
513 StringContentWorker(StringContent content) {
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}
synchronized static Logger getLogger(String name)
Definition Logger.java:124
StringExtractResult extract(byte[] buff, int len, int offset)

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