Autopsy  4.20.0
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.Score;
36 
40 public class AnalysisResultsContentPanel extends javax.swing.JPanel {
41 
42  private static final long serialVersionUID = 1L;
43 
44  private static final String EMPTY_HTML = "<html><head></head><body></body></html>";
45 
46  // Anchors are inserted into the navigation so that the viewer can navigate to a selection.
47  // This is the prefix of those anchors.
48  private static final String RESULT_ANCHOR_PREFIX = "AnalysisResult_";
49 
56  }
57 
63  void showMessage(String message) {
65  textPanel.setText("<html><head></head><body>"
66  + MessageFormat.format("<p class=\"{0}\">{1}</p>",
68  message == null ? "" : EscapeUtil.escapeHtml(message))
69  + "</body></html>");
70  }
71 
75  void reset() {
76  textPanel.setText(EMPTY_HTML);
77  }
78 
84  void displayResults(NodeResults nodeResults) {
85  Document document = Jsoup.parse(EMPTY_HTML);
86  Element body = document.getElementsByTag("body").first();
87 
88  Optional<Element> panelHeader = appendPanelHeader(body, nodeResults.getItemName(), nodeResults.getAggregateScore());
89 
90  // for each analysis result item, display the data.
91  List<ResultDisplayAttributes> displayAttributes = nodeResults.getAnalysisResults();
92  for (int idx = 0; idx < displayAttributes.size(); idx++) {
93  AnalysisResultsViewModel.ResultDisplayAttributes resultAttrs = displayAttributes.get(idx);
94  Element sectionDiv = appendResult(body, idx, resultAttrs);
95  if (idx > 0 || panelHeader.isPresent()) {
96  sectionDiv.attr("class", ContentViewerHtmlStyles.getSpacedSectionClassName());
97  }
98  }
99 
100  // set the body html
101  ContentViewerHtmlStyles.setStyles(textPanel);
102  textPanel.setText(document.html());
103 
104  // if there is a selected result scroll to it
105  Optional<AnalysisResult> selectedResult = nodeResults.getSelectedResult();
106  if (selectedResult.isPresent()) {
107  textPanel.scrollToReference(getAnchor(selectedResult.get()));
108  } else {
109  // otherwise, scroll to the beginning.
110  textPanel.setCaretPosition(0);
111  }
112  }
113 
124  @Messages({
125  "AnalysisResultsContentPanel_aggregateScore_displayKey=Aggregate Score",
126  "AnalysisResultsContentPanel_content_displayKey=Item"
127  })
128  private Optional<Element> appendPanelHeader(Element parent, Optional<String> itemName, Optional<Score> score) {
129  // if no item name or score, don't display
130  if (!itemName.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  container.appendElement("p")
138  .attr("class", ContentViewerHtmlStyles.getTextClassName())
139  .text(MessageFormat.format("{0}: {1}",
140  Bundle.AnalysisResultsContentPanel_content_displayKey(),
141  itemName.get()));
142 
143  // if there is an aggregate score, append the value
144  container.appendElement("p")
145  .attr("class", ContentViewerHtmlStyles.getTextClassName())
146  .text(MessageFormat.format("{0}: {1}",
147  Bundle.AnalysisResultsContentPanel_aggregateScore_displayKey(),
148  score.get().getSignificance().getDisplayName()));
149 
150  return Optional.ofNullable(container);
151  }
152 
160  private String getAnchor(AnalysisResult analysisResult) {
161  return RESULT_ANCHOR_PREFIX + analysisResult.getId();
162  }
163 
173  @NbBundle.Messages({"# {0} - analysisResultsNumber",
174  "AnalysisResultsContentPanel_result_headerKey=Analysis Result {0}"
175  })
176  private Element appendResult(Element parent, int index, AnalysisResultsViewModel.ResultDisplayAttributes attrs) {
177  // create a new section with appropriate header
178  Element sectionDiv = appendSection(parent,
179  Bundle.AnalysisResultsContentPanel_result_headerKey(index + 1),
180  Optional.ofNullable(getAnchor(attrs.getAnalysisResult())));
181 
182  // create a table
183  Element table = sectionDiv.appendElement("table")
184  .attr("valign", "top")
185  .attr("align", "left");
186 
187  table.attr("class", ContentViewerHtmlStyles.getIndentedClassName());
188 
189  Element tableBody = table.appendElement("tbody");
190 
191  // append a row for each item
192  for (Pair<String, String> keyVal : attrs.getAttributesToDisplay()) {
193  Element row = tableBody.appendElement("tr");
194  String keyString = keyVal.getKey() == null ? "" : keyVal.getKey() + ":";
195  Element keyTd = row.appendElement("td")
197 
198  keyTd.appendElement("span")
199  .text(keyString)
200  .attr("class", ContentViewerHtmlStyles.getTextClassName());
201 
202  String valueString = keyVal.getValue() == null ? "" : keyVal.getValue();
203  row.appendElement("td")
204  .text(valueString)
205  .attr("class", ContentViewerHtmlStyles.getTextClassName());
206  }
207 
208  return sectionDiv;
209  }
210 
220  private Element appendSection(Element parent, String headerText, Optional<String> anchorId) {
221  Element sectionDiv = parent.appendElement("div");
222 
223  // append an anchor tag if there is one
224  Element anchorEl = null;
225  if (anchorId.isPresent()) {
226  anchorEl = sectionDiv.appendElement("a");
227  anchorEl.attr("name", anchorId.get());
228  anchorEl.attr("style", "padding: 0px; margin: 0px; display: inline-block;");
229  }
230 
231  // append the header
232  Element header = null;
233  header = (anchorEl == null)
234  ? sectionDiv.appendElement("h1")
235  : anchorEl.appendElement("h1");
236 
237  header.text(headerText);
238  header.attr("class", ContentViewerHtmlStyles.getHeaderClassName());
239  header.attr("style", "display: inline-block");
240 
241  // return the section element
242  return sectionDiv;
243  }
244 
250  @SuppressWarnings("unchecked")
251  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
252  private void initComponents() {
253 
254  javax.swing.JScrollPane scrollPane = new javax.swing.JScrollPane();
255  textPanel = new javax.swing.JTextPane();
256 
257  setPreferredSize(new java.awt.Dimension(100, 58));
258 
259  textPanel.setEditable(false);
260  textPanel.setName(""); // NOI18N
261  textPanel.setPreferredSize(new java.awt.Dimension(600, 52));
262  scrollPane.setViewportView(textPanel);
263 
264  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
265  this.setLayout(layout);
266  layout.setHorizontalGroup(
267  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
268  .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 907, Short.MAX_VALUE)
269  );
270  layout.setVerticalGroup(
271  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
272  .addComponent(scrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 435, Short.MAX_VALUE)
273  );
274  }// </editor-fold>//GEN-END:initComponents
275 
276 
277  // Variables declaration - do not modify//GEN-BEGIN:variables
278  private javax.swing.JTextPane textPanel;
279  // End of variables declaration//GEN-END:variables
280 
281 }
static String escapeHtml(String toEscape)
Definition: EscapeUtil.java:75
Optional< Element > appendPanelHeader(Element parent, Optional< String > itemName, Optional< Score > score)
Element appendSection(Element parent, String headerText, Optional< String > anchorId)
Element appendResult(Element parent, int index, AnalysisResultsViewModel.ResultDisplayAttributes attrs)

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