19 package org.sleuthkit.autopsy.corecomponents;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.concurrent.ExecutionException;
27 import java.util.logging.Level;
28 import javax.swing.JMenuItem;
29 import javax.swing.JTextPane;
30 import javax.swing.SwingWorker;
31 import org.openide.nodes.Node;
32 import org.openide.util.Lookup;
33 import org.openide.util.NbBundle;
34 import org.openide.util.lookup.ServiceProvider;
41 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
53 @ServiceProvider(service = DataContentViewer.class, position = 3)
58 private final static String ERROR_TEXT = NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.errorText");
60 private int currentPage = 1;
61 private final Object lock =
new Object();
63 SwingWorker<ViewUpdate, Void> currentTask;
67 customizeComponents();
76 @SuppressWarnings(
"unchecked")
78 private
void initComponents() {
80 rightClickMenu =
new javax.swing.JPopupMenu();
81 copyMenuItem =
new javax.swing.JMenuItem();
82 selectAllMenuItem =
new javax.swing.JMenuItem();
83 jPanel1 =
new javax.swing.JPanel();
84 jScrollPane1 =
new javax.swing.JScrollPane();
85 outputViewPane =
new JTextPane(){
86 public boolean getScrollableTracksViewportWidth() {
87 return (getSize().width < 400);
89 totalPageLabel =
new javax.swing.JLabel();
90 ofLabel =
new javax.swing.JLabel();
91 currentPageLabel =
new javax.swing.JLabel();
92 pageLabel =
new javax.swing.JLabel();
93 nextPageButton =
new javax.swing.JButton();
94 pageLabel2 =
new javax.swing.JLabel();
95 prevPageButton =
new javax.swing.JButton();
97 copyMenuItem.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.copyMenuItem.text"));
98 rightClickMenu.add(copyMenuItem);
100 selectAllMenuItem.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.selectAllMenuItem.text"));
101 rightClickMenu.add(selectAllMenuItem);
103 setPreferredSize(
new java.awt.Dimension(622, 424));
105 jPanel1.setPreferredSize(
new java.awt.Dimension(622, 424));
107 outputViewPane.setEditable(
false);
108 outputViewPane.setPreferredSize(
new java.awt.Dimension(700, 400));
109 jScrollPane1.setViewportView(outputViewPane);
111 totalPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.totalPageLabel.text"));
115 currentPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.currentPageLabel.text"));
116 currentPageLabel.setMaximumSize(
new java.awt.Dimension(18, 14));
117 currentPageLabel.setMinimumSize(
new java.awt.Dimension(18, 14));
118 currentPageLabel.setPreferredSize(
new java.awt.Dimension(18, 14));
121 pageLabel.setMaximumSize(
new java.awt.Dimension(33, 14));
122 pageLabel.setMinimumSize(
new java.awt.Dimension(33, 14));
123 pageLabel.setPreferredSize(
new java.awt.Dimension(33, 14));
125 nextPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png")));
126 nextPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.nextPageButton.text"));
127 nextPageButton.setBorderPainted(
false);
128 nextPageButton.setContentAreaFilled(
false);
129 nextPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png")));
130 nextPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
131 nextPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
132 nextPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png")));
133 nextPageButton.addActionListener(
new java.awt.event.ActionListener() {
134 public void actionPerformed(java.awt.event.ActionEvent evt) {
135 nextPageButtonActionPerformed(evt);
140 pageLabel2.setMaximumSize(
new java.awt.Dimension(29, 14));
141 pageLabel2.setMinimumSize(
new java.awt.Dimension(29, 14));
142 pageLabel2.setPreferredSize(
new java.awt.Dimension(29, 14));
144 prevPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back.png")));
145 prevPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerArtifact.class,
"DataContentViewerArtifact.prevPageButton.text"));
146 prevPageButton.setBorderPainted(
false);
147 prevPageButton.setContentAreaFilled(
false);
148 prevPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png")));
149 prevPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
150 prevPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
151 prevPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png")));
152 prevPageButton.addActionListener(
new java.awt.event.ActionListener() {
153 public void actionPerformed(java.awt.event.ActionEvent evt) {
154 prevPageButtonActionPerformed(evt);
158 javax.swing.GroupLayout jPanel1Layout =
new javax.swing.GroupLayout(jPanel1);
159 jPanel1.setLayout(jPanel1Layout);
160 jPanel1Layout.setHorizontalGroup(
161 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
162 .addGroup(jPanel1Layout.createSequentialGroup()
164 .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
165 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
166 .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
167 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
168 .addComponent(ofLabel)
169 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
170 .addComponent(totalPageLabel)
172 .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
173 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
174 .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
176 .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
177 .addContainerGap(366, Short.MAX_VALUE))
178 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 622, Short.MAX_VALUE)
180 jPanel1Layout.setVerticalGroup(
181 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
182 .addGroup(jPanel1Layout.createSequentialGroup()
183 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
184 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
185 .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
186 .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
187 .addComponent(ofLabel)
188 .addComponent(totalPageLabel))
189 .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
190 .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
191 .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
193 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE))
196 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
197 this.setLayout(layout);
198 layout.setHorizontalGroup(
199 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
200 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
202 layout.setVerticalGroup(
203 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
204 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
209 currentPage = currentPage + 1;
210 currentPageLabel.setText(Integer.toString(currentPage));
215 currentPage = currentPage - 1;
216 currentPageLabel.setText(Integer.toString(currentPage));
237 outputViewPane.setComponentPopupMenu(rightClickMenu);
238 ActionListener actList =
new ActionListener() {
240 public void actionPerformed(ActionEvent e) {
241 JMenuItem jmi = (JMenuItem) e.getSource();
242 if (jmi.equals(copyMenuItem)) {
243 outputViewPane.copy();
244 }
else if (jmi.equals(selectAllMenuItem)) {
245 outputViewPane.selectAll();
249 copyMenuItem.addActionListener(actList);
250 selectAllMenuItem.addActionListener(actList);
260 currentPageLabel.setText(
"");
261 totalPageLabel.setText(
"");
262 outputViewPane.setText(
"");
263 prevPageButton.setEnabled(
false);
264 nextPageButton.setEnabled(
false);
270 if (currentNode == selectedNode) {
273 currentNode = selectedNode;
276 if (selectedNode == null) {
281 Lookup lookup = selectedNode.getLookup();
282 Content content = lookup.lookup(Content.class);
283 if (content == null) {
292 return NbBundle.getMessage(this.getClass(),
"DataContentViewerArtifact.title");
297 return NbBundle.getMessage(this.getClass(),
"DataContentViewerArtifact.toolTip");
321 Content content = node.getLookup().lookup(Content.class);
322 if (content != null) {
324 return content.getAllArtifactsCount() > 0;
325 }
catch (TskException ex) {
326 logger.log(Level.WARNING,
"Couldn't get count of BlackboardArtifacts for content", ex);
334 BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class);
338 if ((artifact == null)
339 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID())
340 || (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID())) {
357 ViewUpdate(
int numberOfPages,
int currentPage, String text) {
358 this.currentPage = currentPage;
359 this.numberOfPages = numberOfPages;
372 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
374 nextPageButton.setEnabled(viewUpdate.currentPage < viewUpdate.numberOfPages);
375 prevPageButton.setEnabled(viewUpdate.currentPage > 1);
376 currentPage = viewUpdate.currentPage;
377 totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
378 currentPageLabel.setText(Integer.toString(currentPage));
384 outputViewPane.setText(viewUpdate.text);
385 outputViewPane.moveCaretPosition(0);
387 this.setCursor(null);
396 private synchronized void startNewTask(SwingWorker<ViewUpdate, Void> task) {
397 outputViewPane.setText(WAIT_TEXT);
398 outputViewPane.moveCaretPosition(0);
401 if (currentTask != null) {
404 currentTask.cancel(
false);
409 currentTask.execute();
418 synchronized (lock) {
419 this.artifactContentStrings = artifactStrings;
429 synchronized (lock) {
430 return artifactContentStrings;
444 this.selectedNode = selectedNode;
451 Lookup lookup = selectedNode.getLookup();
454 Content content = lookup.lookup(Content.class);
455 if (content == null) {
456 return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
461 ArrayList<BlackboardArtifact> artifacts;
463 artifacts = content.getAllArtifacts();
464 }
catch (TskException ex) {
465 logger.log(Level.WARNING,
"Couldn't get artifacts", ex);
466 return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
474 ArrayList<ArtifactStringContent> artifactStrings =
new ArrayList<>();
475 for (BlackboardArtifact artifact : artifacts) {
482 BlackboardArtifact artifact = lookup.lookup(BlackboardArtifact.class);
483 if (artifact != null) {
484 index = artifacts.indexOf(artifact);
490 for (BlackboardAttribute attr : artifact.getAttributes()) {
491 if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
492 long assocArtifactId = attr.getValueLong();
493 int assocArtifactIndex = -1;
494 for (BlackboardArtifact art : artifacts) {
495 if (assocArtifactId == art.getArtifactID()) {
496 assocArtifactIndex = artifacts.indexOf(art);
500 if (assocArtifactIndex >= 0) {
501 index = assocArtifactIndex;
506 }
catch (TskCoreException ex) {
507 logger.log(Level.WARNING,
"Couldn't get associated artifact to display in Content Viewer.", ex);
520 ViewUpdate viewUpdate =
new ViewUpdate(artifactStrings.size(), index + 1, artifactStrings.get(index).getString());
529 setArtifactContentStrings(artifactStrings);
536 if (!isCancelled()) {
539 if (viewUpdate != null) {
540 updateView(viewUpdate);
542 }
catch (InterruptedException | ExecutionException ex) {
543 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
559 this.pageIndex = pageIndex;
566 List<ArtifactStringContent> artifactStrings = getArtifactContentStrings();
571 String artifactString = artifactStringContent.
getString();
579 return new ViewUpdate(artifactStrings.size(), pageIndex, artifactString);
584 if (!isCancelled()) {
587 if (viewUpdate != null) {
588 updateView(viewUpdate);
590 }
catch (InterruptedException | ExecutionException ex) {
591 logger.log(Level.WARNING,
"Artifact display task unexpectedly interrupted or failed", ex);
javax.swing.JPopupMenu rightClickMenu
void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JScrollPane jScrollPane1
List< ArtifactStringContent > artifactContentStrings
void setArtifactContentStrings(List< ArtifactStringContent > artifactStrings)
javax.swing.JLabel pageLabel
List< ArtifactStringContent > getArtifactContentStrings()
javax.swing.JTextPane outputViewPane
synchronized void startNewTask(SwingWorker< ViewUpdate, Void > task)
javax.swing.JPanel jPanel1
javax.swing.JButton nextPageButton
void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt)
DataContentViewerArtifact()
ViewUpdate doInBackground()
void updateView(ViewUpdate viewUpdate)
void setNode(Node selectedNode)
static void configureTextPaneAsHtml(JTextPane pane)
javax.swing.JMenuItem copyMenuItem
javax.swing.JLabel totalPageLabel
javax.swing.JButton prevPageButton
javax.swing.JMenuItem selectAllMenuItem
javax.swing.JLabel pageLabel2
javax.swing.JLabel ofLabel
DataContentViewer createInstance()
synchronized static Logger getLogger(String name)
ViewUpdate doInBackground()
boolean isSupported(Node node)
int isPreferred(Node node)
void customizeComponents()
javax.swing.JLabel currentPageLabel