Autopsy  4.19.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
AnalysisResultsContentPanel.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.contentviewers.analysisresults;
20 
21 import java.text.MessageFormat;
22 import java.util.List;
23 import java.util.Optional;
24 import org.apache.commons.lang3.tuple.Pair;
25 import org.jsoup.Jsoup;
26 import org.jsoup.nodes.Document;
27 import org.jsoup.nodes.Element;
28 import org.openide.util.NbBundle;
29 import org.openide.util.NbBundle.Messages;
34 import org.sleuthkit.datamodel.AnalysisResult;
35 import org.sleuthkit.datamodel.Content;
36 import org.sleuthkit.datamodel.Score;
37 
41 public class AnalysisResultsContentPanel extends javax.swing.JPanel {
42 
43  private static final long serialVersionUID = 1L;
44 
45  private static final String EMPTY_HTML = "<html><head></head><body></body></html>";
46 
47  // Anchors are inserted into the navigation so that the viewer can navigate to a selection.
48  // This is the prefix of those anchors.
49  private static final String RESULT_ANCHOR_PREFIX = "AnalysisResult_";
50 
57  }
58 
64  void showMessage(String message) {
66  textPanel.setText("<html><head></head><body>"
67  + MessageFormat.format("<p class=\"{0}\">{1}</p>",
69  message == null ? "" : EscapeUtil.escapeHtml(message))
70  + "</body></html>");
71  }
72 
76  void reset() {
77  textPanel.setText(EMPTY_HTML);
78  }
79 
85  void displayResults(NodeResults nodeResults) {
86  Document document = Jsoup.parse(EMPTY_HTML);
87  Element body = document.getElementsByTag("body").first();
88 
89  Optional<Element> panelHeader = appendPanelHeader(body, nodeResults.getContent(), nodeResults.getAggregateScore());
90 
91  // for each analysis result item, display the data.
92  List<ResultDisplayAttributes> displayAttributes = nodeResults.getAnalysisResults();
93  for (int idx = 0; idx < displayAttributes.size(); idx++) {
94  AnalysisResultsViewModel.ResultDisplayAttributes resultAttrs = displayAttributes.get(idx);
95  Element sectionDiv = appendResult(body, idx, resultAttrs);
96  if (idx > 0 || panelHeader.isPresent()) {
97  sectionDiv.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName());
98  }
99  }
100 
101  // set the body html
102  ContentViewerHtmlStyles.setStyles(textPanel);
103  textPanel.setText(document.html());
104 
105  // if there is a selected result scroll to it
106  Optional<AnalysisResult> selectedResult = nodeResults.getSelectedResult();
107  if (selectedResult.isPresent()) {
108  textPanel.scrollToReference(getAnchor(selectedResult.get()));
109  } else {
110  // otherwise, scroll to the beginning.
111  textPanel.setCaretPosition(0);
112  }
113  }
114 
125  @Messages({
126  "AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score",
127  "AnalysisResultsContentPanel_content_displayKey=Item"
128  })
129  private Optional<Element> appendPanelHeader(Element parent, Optional<Content> content, Optional<Score> score) {
130  if (!content.isPresent() || !score.isPresent()) {
131  return Optional.empty();
132  }
133 
134  Element container = parent.appendElement("div");
135 
136  // if there is content append the name
137  content.ifPresent((c) -> {
138  container.appendElement("p")
139  .attr("class", ContentViewerHtmlStyles.getTextClassName())
140  .text(MessageFormat.format("{0}: {1}",
141  Bundle.AnalysisResultsContentPanel_content_displayKey(),
142  c.getName()));
143  });
144 
145  // if there is an aggregate score, append the value
146  score.ifPresent((s) -> {
147  container.appendElement("p")
148  .attr("class", ContentViewerHtmlStyles.getTextClassName())
149  .text(MessageFormat.format("{0}: {1}",
150  Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(),
151  s.getSignificance().getDisplayName()));
152  });
153 
154  return Optional.ofNullable(container);
155  }
156 
164  private String getAnchor(AnalysisResult analysisResult) {
165  return RESULT_ANCHOR_PREFIX + analysisResult.getId();
166  }
167 
177  @NbBundle.Messages({"# {0} - analysisResultsNumber",
178  "AnalysisResultsContentPanel_result_headerKey=Analysis Result {0}"
179  })
180  private Element appendResult(Element parent, int index, AnalysisResultsViewModel.ResultDisplayAttributes attrs) {
181  // create a new section with appropriate header
182  Element sectionDiv = appendSection(parent,
183  Bundle.AnalysisResultsContentPanel_result_headerKey(index + 1),
184  Optional.ofNullable(getAnchor(attrs.getAnalysisResult())));
185 
186  // create a table
187  Element table = sectionDiv.appendElement("table")
188  .attr("valign", "top")
189  .attr("align", "left");
190 
191  table.attr("class", ContentViewerHtmlStyles.getIndentedClassName());
192 
193  Element tableBody = table.appendElement("tbody");
194 
195  // append a row for each item
196  for (Pair<String, String> keyVal : attrs.getAttributesToDisplay()) {
197  Element row = tableBody.appendElement("tr");
198  String keyString = keyVal.getKey() == null ? "" : keyVal.getKey() + ":";
199  Element keyTd = row.appendElement("td")
201 
202  keyTd.appendElement("span")
203  .text(keyString)
204  .attr("class", ContentViewerHtmlStyles.getTextClassName());
205 
206  String valueString = keyVal.getValue() == null ? "" : keyVal.getValue();
207  row.appendElement("td")
208  .text(valueString)
209  .attr("class", ContentViewerHtmlStyles.getTextClassName());
210  }
211 
212  return sectionDiv;
213  }
214 
224  private Element appendSection(Element parent, String headerText, Optional<String> anchorId) {
225  Element sectionDiv = parent.appendElement("div");
226 
227  // append an anchor tag if there is one
228  Element anchorEl = null;
229  if (anchorId.isPresent()) {
230  anchorEl = sectionDiv.appendElement("a");
231  anchorEl.attr("name", anchorId.get());
232  anchorEl.attr("style", "padding: 0px; margin: 0px; display: inline-block;");
233  }
234 
235  // append the header
236  Element header = null;
237  header = (anchorEl == null)
238  ? sectionDiv.appendElement("h1")
239  : anchorEl.appendElement("h1");
240 
241  header.text(headerText);
242  header.attr("class", ContentViewerHtmlStyles.getHeaderClassName());
243  header.attr("style", "display: inline-block");
244 
245  // return the section element
246  return sectionDiv;
247  }
248 
254  @SuppressWarnings("unchecked")
255  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
256  private void initComponents() {
257 
258  javax.swing.JScrollPane scrollPane = new javax.swing.JScrollPane();
259  textPanel = new javax.swing.JTextPane();
260 
261  setPreferredSize(new java.awt.Dimension(100, 58));
262 
263  textPanel.setEditable(false);
264  textPanel.setName(""); // NOI18N
265  textPanel.setPreferredSize(new java.awt.Dimension(600, 52));
266  scrollPane.setViewportView(textPanel);
267 
268  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
269  this.setLayout(layout);
270  layout.setHorizontalGroup(
271  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
272  .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 907, Short.MAX_VALUE)
273  );
274  layout.setVerticalGroup(
275  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
276  .addComponent(scrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 435, Short.MAX_VALUE)
277  );
278  }// </editor-fold>//GEN-END:initComponents
279 
280 
281  // Variables declaration - do not modify//GEN-BEGIN:variables
282  private javax.swing.JTextPane textPanel;
283  // End of variables declaration//GEN-END:variables
284 
285 }
static String escapeHtml(String toEscape)
Definition: EscapeUtil.java:75
Optional< Element > appendPanelHeader(Element parent, Optional< Content > content, Optional< Score > score)
Element appendSection(Element parent, String headerText, Optional< String > anchorId)
Element appendResult(Element parent, int index, AnalysisResultsViewModel.ResultDisplayAttributes attrs)

Copyright © 2012-2021 Basis Technology. Generated on: Thu Sep 30 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.