Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
ContextViewer.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019-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.contextviewer;
20 
21 import java.awt.Component;
22 import java.awt.Insets;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.logging.Level;
30 import javax.swing.BoxLayout;
31 import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
32 import javax.swing.border.EmptyBorder;
33 import org.apache.commons.lang.StringUtils;
34 import org.openide.nodes.Node;
35 import org.openide.util.NbBundle;
36 import org.openide.util.lookup.ServiceProvider;
43 import org.sleuthkit.datamodel.AbstractFile;
44 import org.sleuthkit.datamodel.BlackboardArtifact;
45 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
46 import org.sleuthkit.datamodel.BlackboardAttribute;
47 import org.sleuthkit.datamodel.SleuthkitCase;
48 import org.sleuthkit.datamodel.TskCoreException;
49 
55 @ServiceProvider(service = DataContentViewer.class, position = 8)
56 public final class ContextViewer extends javax.swing.JPanel implements DataContentViewer {
57 
58  private static final long serialVersionUID = 1L;
59  private static final Logger logger = Logger.getLogger(ContextViewer.class.getName());
60  private static final int ARTIFACT_STR_MAX_LEN = 1024;
61  private static final int ATTRIBUTE_STR_MAX_LEN = 200;
62 
63  private final static Insets FIRST_HEADER_INSETS = new Insets(0, 0, 0, 0);
64  private final static Insets HEADER_INSETS = new Insets(ContentViewerDefaults.getSectionSpacing(), 0, ContentViewerDefaults.getLineSpacing(), 0);
65  private final static Insets DATA_ROW_INSETS = new Insets(0, ContentViewerDefaults.getSectionIndent(), ContentViewerDefaults.getLineSpacing(), 0);
66 
67  // defines a list of artifacts that provide context for a file
68  private static final List<BlackboardArtifact.ARTIFACT_TYPE> CONTEXT_ARTIFACTS = new ArrayList<>();
69  private final List<ContextSourcePanel> contextSourcePanels = new ArrayList<>();
70  private final List<ContextUsagePanel> contextUsagePanels = new ArrayList<>();
71 
72  static {
73  CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT);
74  }
75 
79  public ContextViewer() {
80 
81  initComponents();
82  jScrollPane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
83  }
84 
90  @SuppressWarnings("unchecked")
91  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
92  private void initComponents() {
93 
94  jSourcePanel = new javax.swing.JPanel();
95  javax.swing.JLabel jSourceLabel = new javax.swing.JLabel();
96  jUsagePanel = new javax.swing.JPanel();
97  javax.swing.JLabel jUsageLabel = new javax.swing.JLabel();
98  jUnknownPanel = new javax.swing.JPanel();
99  javax.swing.JLabel jUnknownLabel = new javax.swing.JLabel();
100  jScrollPane = new javax.swing.JScrollPane();
101 
102  jSourcePanel.setBorder(new EmptyBorder(FIRST_HEADER_INSETS));
103  jSourcePanel.setLayout(new javax.swing.BoxLayout(jSourcePanel, javax.swing.BoxLayout.PAGE_AXIS));
104 
105  jSourceLabel.setFont(ContentViewerDefaults.getHeaderFont());
106  org.openide.awt.Mnemonics.setLocalizedText(jSourceLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceLabel.text")); // NOI18N
107  jSourcePanel.add(jSourceLabel);
108 
109  jUsagePanel.setBorder(new EmptyBorder(HEADER_INSETS));
110  jUsagePanel.setLayout(new javax.swing.BoxLayout(jUsagePanel, javax.swing.BoxLayout.PAGE_AXIS));
111 
112  jUsageLabel.setFont(ContentViewerDefaults.getHeaderFont()
113  );
114  org.openide.awt.Mnemonics.setLocalizedText(jUsageLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUsageLabel.text")); // NOI18N
115  jUsagePanel.add(jUsageLabel);
116 
117  jUnknownPanel.setLayout(new javax.swing.BoxLayout(jUnknownPanel, javax.swing.BoxLayout.PAGE_AXIS));
118 
119  org.openide.awt.Mnemonics.setLocalizedText(jUnknownLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jUnknownLabel.text")); // NOI18N
120  jUnknownLabel.setBorder(new EmptyBorder(DATA_ROW_INSETS));
121  jUnknownPanel.add(jUnknownLabel);
122 
123  setPreferredSize(new java.awt.Dimension(0, 0));
124 
125  jScrollPane.setPreferredSize(new java.awt.Dimension(16, 16));
126 
127  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
128  this.setLayout(layout);
129  layout.setHorizontalGroup(
130  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
131  .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 509, Short.MAX_VALUE)
132  );
133  layout.setVerticalGroup(
134  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
135  .addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
136  );
137  }// </editor-fold>//GEN-END:initComponents
138 
139  @Override
140  public void setNode(Node selectedNode) {
141  if ((selectedNode == null) || (!isSupported(selectedNode))) {
142  resetComponent();
143  return;
144  }
145 
146  AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
147  try {
148  populatePanels(file);
149  } catch (NoCurrentCaseException | TskCoreException ex) {
150  logger.log(Level.SEVERE, String.format("Exception displaying context for file %s", file.getName()), ex); //NON-NLS
151  }
152  }
153 
154  @NbBundle.Messages({
155  "ContextViewer.title=Context",
156  "ContextViewer.toolTip=Displays context for selected file."
157  })
158 
159  @Override
160  public String getTitle() {
161  return Bundle.ContextViewer_title();
162  }
163 
164  @Override
165  public String getToolTip() {
166  return Bundle.ContextViewer_toolTip();
167  }
168 
169  @Override
170  public DataContentViewer createInstance() {
171  return new ContextViewer();
172  }
173 
174  @Override
175  public Component getComponent() {
176  return this;
177  }
178 
179  @Override
180  public void resetComponent() {
181  contextSourcePanels.clear();
182  contextUsagePanels.clear();
183  }
184 
185  @Override
186  public boolean isSupported(Node node) {
187 
188  // check if the node has an abstract file and the file has any context defining artifacts.
189  if (node.getLookup().lookup(AbstractFile.class) != null) {
190  AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class);
191  for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
192  List<BlackboardArtifact> artifactsList;
193  try {
194  artifactsList = abstractFile.getArtifacts(artifactType);
195  if (!artifactsList.isEmpty()) {
196  return true;
197  }
198  } catch (TskCoreException ex) {
199  logger.log(Level.SEVERE, String.format("Exception while looking up context artifacts for file %s", abstractFile), ex); //NON-NLS
200  }
201  }
202 
203  }
204 
205  return false;
206  }
207 
208  @Override
209  public int isPreferred(Node node) {
210  // this is a low preference viewer.
211  return ViewerPriority.viewerPriority.LevelOne.getFlag();
212  }
213 
214  @NbBundle.Messages({
215  "ContextViewer.unknownSource=Unknown ",
216  })
226  private void populatePanels(AbstractFile sourceFile) throws NoCurrentCaseException, TskCoreException {
227 
228  SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
229 
230  // Check for all context artifacts
231  boolean foundASource = false;
232  for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
233  List<BlackboardArtifact> artifactsList = tskCase.getBlackboardArtifacts(artifactType, sourceFile.getId());
234 
235  foundASource = !artifactsList.isEmpty();
236  for (BlackboardArtifact contextArtifact : artifactsList) {
237  addAssociatedArtifactToPanel(contextArtifact);
238  }
239  }
240  javax.swing.JPanel contextContainer = new javax.swing.JPanel();
241  contextContainer.setLayout(new BoxLayout(contextContainer, BoxLayout.Y_AXIS));
242  contextContainer.setBorder(new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
243 
244  contextContainer.add(jSourcePanel);
245 
246  if (contextSourcePanels.isEmpty()) {
247  contextContainer.add(jUnknownPanel);
248  } else {
249  for (javax.swing.JPanel sourcePanel : contextSourcePanels) {
250  contextContainer.add(sourcePanel);
251  contextContainer.setAlignmentX(0);
252  }
253  }
254  contextContainer.add(jUsagePanel);
255  if (contextUsagePanels.isEmpty()) {
256  contextContainer.add(jUnknownPanel);
257  } else {
258  for (javax.swing.JPanel usagePanel : contextUsagePanels) {
259  contextContainer.add(usagePanel);
260  contextContainer.setAlignmentX(0);
261  }
262  }
263 
264  contextContainer.setBackground(ContentViewerDefaults.getPanelBackground());
265  contextContainer.setEnabled(foundASource);
266  contextContainer.setVisible(foundASource);
267  jScrollPane.getViewport().setView(contextContainer);
268  jScrollPane.setEnabled(foundASource);
269  jScrollPane.setVisible(foundASource);
270  jScrollPane.repaint();
271  jScrollPane.revalidate();
272 
273 
274  }
275 
284  private void addAssociatedArtifactToPanel(BlackboardArtifact artifact) throws TskCoreException {
285 
286  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
287  BlackboardAttribute associatedArtifactAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
288  if (associatedArtifactAttribute != null) {
289  long artifactId = associatedArtifactAttribute.getValueLong();
290  BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(artifactId);
291 
292  addArtifactToPanels(associatedArtifact);
293  }
294  }
295  }
296 
304  @NbBundle.Messages({
305  "ContextViewer.attachmentSource=Attached to: ",
306  "ContextViewer.downloadSource=Downloaded from: ",
307  "ContextViewer.recentDocs=Recent Documents: ",
308  "ContextViewer.programExecution=Program Execution: "
309  })
310  private void addArtifactToPanels(BlackboardArtifact associatedArtifact) throws TskCoreException {
311  Long dateTime = getArtifactDateTime(associatedArtifact);
312  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID()
313  || BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == associatedArtifact.getArtifactTypeID()) {
314  String sourceName = Bundle.ContextViewer_attachmentSource();
315  String sourceText = msgArtifactToAbbreviatedString(associatedArtifact);
316  ContextSourcePanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, dateTime);
317  sourcePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS));
318  sourcePanel.setAlignmentX(0);
319  contextSourcePanels.add(sourcePanel);
320 
321  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID()
322  || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == associatedArtifact.getArtifactTypeID()) {
323  String sourceName = Bundle.ContextViewer_downloadSource();
324  String sourceText = webDownloadArtifactToString(associatedArtifact);
325  ContextSourcePanel sourcePanel = new ContextSourcePanel(sourceName, sourceText, associatedArtifact, dateTime);
326  sourcePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS));
327  sourcePanel.setAlignmentX(0);
328  contextSourcePanels.add(sourcePanel);
329 
330  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) {
331  String sourceName = Bundle.ContextViewer_recentDocs();
332  String sourceText = recentDocArtifactToString(associatedArtifact);
333  ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime);
334  usagePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS));
335  usagePanel.setAlignmentX(0);
336  contextUsagePanels.add(usagePanel);
337 
338  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) {
339  String sourceName = Bundle.ContextViewer_programExecution();
340  String sourceText = programExecArtifactToString(associatedArtifact);
341  ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime);
342  usagePanel.setBorder(new EmptyBorder(DATA_ROW_INSETS));
343  usagePanel.setAlignmentX(0);
344  contextUsagePanels.add(usagePanel);
345  }
346 
347  Collections.sort(contextSourcePanels, new SortByDateTime());
348  Collections.sort(contextUsagePanels, new SortByDateTime());
349  }
350 
361  @NbBundle.Messages({
362  "ContextViewer.downloadURL=URL",
363  "ContextViewer.downloadedOn=On"
364  })
365  private String webDownloadArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
366  StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
367  Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
368 
369  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
370  || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
371  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL, attributesMap, Bundle.ContextViewer_downloadURL());
372  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, attributesMap, Bundle.ContextViewer_downloadedOn());
373  }
374  return sb.toString();
375  }
376 
387  @NbBundle.Messages({
388  "ContextViewer.on=Opened at",
389  "ContextViewer.unknown=Opened at unknown time"
390  })
391  private String recentDocArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
392  StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
393  Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
394 
395  BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
396 
397  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
398  if (attribute != null && attribute.getValueLong() > 0) {
399  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_on());
400  } else {
401  sb.append(Bundle.ContextViewer_unknown());
402  }
403  }
404  return sb.toString();
405  }
406 
417  @NbBundle.Messages({
418  "ContextViewer.runOn=Program Run On",
419  "ContextViewer.runUnknown= Program Run at unknown time"
420  })
421  private String programExecArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
422  StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
423  Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
424 
425  BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
426 
427  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifact.getArtifactTypeID()) {
428  if (attribute != null && attribute.getValueLong() > 0) {
429  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_runOn());
430  } else {
431  sb.append(Bundle.ContextViewer_runUnknown());
432  }
433  }
434  return sb.toString();
435  }
436 
446  @NbBundle.Messages({
447  "ContextViewer.message=Message",
448  "ContextViewer.email=Email",
449  "ContextViewer.messageFrom=From",
450  "ContextViewer.messageTo=To",
451  "ContextViewer.messageOn=On",})
452  private String msgArtifactToAbbreviatedString(BlackboardArtifact artifact) throws TskCoreException {
453 
454  StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
455  Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
456 
457  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifact.getArtifactTypeID()) {
458  sb.append(Bundle.ContextViewer_message()).append(' ');
459  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, attributesMap, Bundle.ContextViewer_messageFrom());
460  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, attributesMap, Bundle.ContextViewer_messageTo());
461  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_messageOn());
462  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
463  sb.append(Bundle.ContextViewer_email()).append(' ');
464  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM, attributesMap, Bundle.ContextViewer_messageFrom());
465  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO, attributesMap, Bundle.ContextViewer_messageTo());
466  appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT, attributesMap, Bundle.ContextViewer_messageOn());
467  }
468  return sb.toString();
469  }
470 
481  private void appendAttributeString(StringBuilder sb, BlackboardAttribute.ATTRIBUTE_TYPE attribType,
482  Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap, String prependStr) {
483 
484  BlackboardAttribute attribute = attributesMap.get(attribType);
485  if (attribute != null) {
486  String attrVal = attribute.getDisplayString();
487  if (!StringUtils.isEmpty(attrVal)) {
488  if (!StringUtils.isEmpty(prependStr)) {
489  sb.append(prependStr).append(' ');
490  }
491  sb.append(StringUtils.abbreviate(attrVal, ATTRIBUTE_STR_MAX_LEN)).append(' ');
492  }
493  }
494  }
495 
506  private Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> getAttributesMap(BlackboardArtifact artifact) throws TskCoreException {
507  Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap = new HashMap<>();
508 
509  List<BlackboardAttribute> attributeList = artifact.getAttributes();
510  for (BlackboardAttribute attribute : attributeList) {
511  BlackboardAttribute.ATTRIBUTE_TYPE type = BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attribute.getAttributeType().getTypeID());
512  attributeMap.put(type, attribute);
513  }
514 
515  return attributeMap;
516  }
517 
518  interface DateTimePanel {
524  Long getDateTime();
525  }
526 
536  private Long getArtifactDateTime(BlackboardArtifact artifact) throws TskCoreException {
537  BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
538 
539  if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
540  attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
541  } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
542  || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
543  attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED));
544  }
545  return (attribute != null ? attribute.getValueLong() : null);
546  }
547 
551  class SortByDateTime implements Comparator<DateTimePanel> {
552 
553  @Override
554  public int compare(DateTimePanel panel1, DateTimePanel panel2) {
555  Long dateTime1 = panel1.getDateTime();
556  Long dateTime2 = panel2.getDateTime();
557 
558  if(dateTime1 == null && dateTime2 == null) {
559  return 0;
560  } else if(dateTime1 == null) {
561  return -1;
562  } else if(dateTime2 == null) {
563  return 1;
564  }
565 
566  return dateTime1.compareTo(dateTime2);
567  }
568 
569  }
570 
571 
572  // Variables declaration - do not modify//GEN-BEGIN:variables
573  private javax.swing.JScrollPane jScrollPane;
574  private javax.swing.JPanel jSourcePanel;
575  private javax.swing.JPanel jUnknownPanel;
576  private javax.swing.JPanel jUsagePanel;
577  // End of variables declaration//GEN-END:variables
578 }
Map< BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute > getAttributesMap(BlackboardArtifact artifact)
void appendAttributeString(StringBuilder sb, BlackboardAttribute.ATTRIBUTE_TYPE attribType, Map< BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute > attributesMap, String prependStr)
void addArtifactToPanels(BlackboardArtifact associatedArtifact)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
String msgArtifactToAbbreviatedString(BlackboardArtifact artifact)

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.