Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
CaseEventListener.java
Go to the documentation of this file.
1 /*
2  * Central Repository
3  *
4  * Copyright 2017-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.centralrepository.eventlisteners;
20 
21 import com.google.common.util.concurrent.ThreadFactoryBuilder;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import java.util.ArrayList;
25 import java.util.EnumSet;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.concurrent.ExecutorService;
29 import java.util.concurrent.Executors;
30 import java.util.logging.Level;
31 import org.apache.commons.lang.StringUtils;
32 import org.openide.util.NbBundle.Messages;
49 import org.sleuthkit.datamodel.AbstractFile;
50 import org.sleuthkit.datamodel.BlackboardArtifact;
51 import org.sleuthkit.datamodel.BlackboardArtifactTag;
52 import org.sleuthkit.datamodel.Content;
53 import org.sleuthkit.datamodel.ContentTag;
54 import org.sleuthkit.datamodel.TagName;
55 import org.sleuthkit.datamodel.TskCoreException;
56 import org.sleuthkit.datamodel.TskData;
58 import org.sleuthkit.datamodel.Tag;
60 import org.sleuthkit.datamodel.AnalysisResult;
61 import org.sleuthkit.datamodel.DataArtifact;
62 
67 @Messages({"caseeventlistener.evidencetag=Evidence"})
68 public final class CaseEventListener implements PropertyChangeListener {
69 
70  private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName());
71  private static final String CASE_EVENT_THREAD_NAME = "CR-Case-Event-Listener-%d";
72  private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(
80  private final ExecutorService jobProcessingExecutor;
81 
86  public CaseEventListener() {
87  jobProcessingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(CASE_EVENT_THREAD_NAME).build());
88  }
89 
93  public void startUp() {
94  Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this);
95  }
96 
100  public void shutdown() {
101  Case.removeEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this);
102  ThreadUtils.shutDownTaskExecutor(jobProcessingExecutor);
103  }
104 
105  @Override
106  public void propertyChange(PropertyChangeEvent evt) {
107  if (!(evt instanceof AutopsyEvent) || (((AutopsyEvent) evt).getSourceType() != AutopsyEvent.SourceType.LOCAL)) {
108  return;
109  }
110 
111  if (!CentralRepository.isEnabled()) {
112  return;
113  }
114 
115  CentralRepository centralRepo;
116  try {
117  centralRepo = CentralRepository.getInstance();
118  } catch (CentralRepoException ex) {
119  LOGGER.log(Level.SEVERE, "Failed to access central repository", ex);
120  return;
121  }
122 
123  /*
124  * IMPORTANT: If any changes are made to which event types are handled,
125  * the change must also be made to the contents of the
126  * CASE_EVENTS_OF_INTEREST set.
127  */
128  switch (Case.Events.valueOf(evt.getPropertyName())) {
129  case CONTENT_TAG_ADDED:
130  case CONTENT_TAG_DELETED:
131  jobProcessingExecutor.submit(new ContentTagTask(centralRepo, evt));
132  break;
133  case BLACKBOARD_ARTIFACT_TAG_DELETED:
134  case BLACKBOARD_ARTIFACT_TAG_ADDED:
135  jobProcessingExecutor.submit(new ArtifactTagTask(centralRepo, evt));
136  break;
137  case DATA_SOURCE_ADDED:
138  jobProcessingExecutor.submit(new DataSourceAddedTask(centralRepo, evt));
139  break;
140  case TAG_DEFINITION_CHANGED:
141  jobProcessingExecutor.submit(new TagDefinitionChangeTask(evt));
142  break;
143  case CURRENT_CASE:
144  jobProcessingExecutor.submit(new CurrentCaseTask(centralRepo, evt));
145  break;
146  case DATA_SOURCE_NAME_CHANGED:
147  jobProcessingExecutor.submit(new DataSourceNameChangedTask(centralRepo, evt));
148  break;
149  default:
150  break;
151  }
152  }
153 
161  private static boolean isNotableTag(Tag tag) {
162  return (tag != null && isNotableTagDefinition(tag.getName()));
163  }
164 
172  private static boolean isNotableTagDefinition(TagName tagDef) {
173  return (tagDef != null && TagsManager.getNotableTagDisplayNames().contains(tagDef.getDisplayName()));
174  }
175 
183  private static boolean hasNotableTag(List<? extends Tag> tags) {
184  if (tags == null) {
185  return false;
186  }
187  return tags.stream()
189  .findFirst()
190  .isPresent();
191  }
192 
201  private static void setArtifactKnownStatus(CentralRepository centralRepo, BlackboardArtifact artifact, TskData.FileKnown notableStatus) {
202  List<CorrelationAttributeInstance> corrAttrInstances = new ArrayList<>();
203  if (artifact instanceof DataArtifact) {
204  corrAttrInstances.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((DataArtifact) artifact));
205  } else if (artifact instanceof AnalysisResult) {
206  corrAttrInstances.addAll(CorrelationAttributeUtil.makeCorrAttrsForSearch((AnalysisResult) artifact));
207  }
208  for (CorrelationAttributeInstance corrAttrInstance : corrAttrInstances) {
209  try {
210  centralRepo.setAttributeInstanceKnownStatus(corrAttrInstance, notableStatus);
211  } catch (CentralRepoException ex) {
212  LOGGER.log(Level.SEVERE, String.format("Error setting correlation attribute instance known status", corrAttrInstance), ex); //NON-NLS
213  }
214  }
215  }
216 
217  private final class ContentTagTask implements Runnable {
218 
220  private final PropertyChangeEvent event;
221 
222  private ContentTagTask(CentralRepository db, PropertyChangeEvent evt) {
223  dbManager = db;
224  event = evt;
225  }
226 
227  @Override
228  public void run() {
229  if (!CentralRepository.isEnabled()) {
230  return;
231  }
232 
233  Case.Events curEventType = Case.Events.valueOf(event.getPropertyName());
234  if (curEventType == Case.Events.CONTENT_TAG_ADDED && event instanceof ContentTagAddedEvent) {
235  handleTagAdded((ContentTagAddedEvent) event);
236  } else if (curEventType == Case.Events.CONTENT_TAG_DELETED && event instanceof ContentTagDeletedEvent) {
237  handleTagDeleted((ContentTagDeletedEvent) event);
238  } else {
239  LOGGER.log(Level.SEVERE,
240  String.format("Received an event %s of type %s and was expecting either CONTENT_TAG_ADDED or CONTENT_TAG_DELETED.",
241  event, curEventType));
242  }
243  }
244 
246  // ensure tag deleted event has a valid content id
247  if (evt.getDeletedTagInfo() == null) {
248  LOGGER.log(Level.SEVERE, "ContentTagDeletedEvent did not have valid content to provide a content id.");
249  return;
250  }
251 
252  try {
253  // obtain content
254  Content content = Case.getCurrentCaseThrows().getSleuthkitCase().getContentById(evt.getDeletedTagInfo().getContentID());
255  if (content == null) {
256  LOGGER.log(Level.WARNING,
257  String.format("Unable to get content for item with content id: %d.", evt.getDeletedTagInfo().getContentID()));
258  return;
259  }
260 
261  // then handle the event
262  handleTagChange(content);
263  } catch (NoCurrentCaseException | TskCoreException ex) {
264  LOGGER.log(Level.WARNING, "Error updating non-file object: " + evt.getDeletedTagInfo().getContentID(), ex);
265  }
266  }
267 
269  // ensure tag added event has a valid content id
270  if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null) {
271  LOGGER.log(Level.SEVERE, "ContentTagAddedEvent did not have valid content to provide a content id.");
272  return;
273  }
274 
275  // then handle the event
276  handleTagChange(evt.getAddedTag().getContent());
277  }
278 
286  private void handleTagChange(Content content) {
287  AbstractFile af = null;
288  try {
289  af = Case.getCurrentCaseThrows().getSleuthkitCase().getAbstractFileById(content.getId());
290  } catch (NoCurrentCaseException | TskCoreException ex) {
291  Long contentID = (content != null) ? content.getId() : null;
292  LOGGER.log(Level.WARNING, "Error updating non-file object: " + contentID, ex);
293  }
294 
295  if (af == null) {
296  return;
297  }
298 
299  try {
300  // Get the tags on the content object
302 
303  if (hasNotableTag(tagsManager.getContentTagsByContent(content))) {
304  // if there is a notable tag on the object, set content known status to bad
305  setContentKnownStatus(af, TskData.FileKnown.BAD);
306  } else {
307  // otherwise, set to unknown
308  setContentKnownStatus(af, TskData.FileKnown.UNKNOWN);
309  }
310  } catch (TskCoreException | NoCurrentCaseException ex) {
311  LOGGER.log(Level.SEVERE, "Failed to obtain tags manager for case.", ex);
312  }
313  }
314 
324  private void setContentKnownStatus(AbstractFile af, TskData.FileKnown knownStatus) {
325  final List<CorrelationAttributeInstance> md5CorrelationAttr = CorrelationAttributeUtil.makeCorrAttrsForSearch(af);
326  if (!md5CorrelationAttr.isEmpty()) {
327  //for an abstract file the 'list' of attributes will be a single attribute or empty and is returning a list for consistency with other makeCorrAttrsForSearch methods per 7852
328  // send update to Central Repository db
329  try {
330  dbManager.setAttributeInstanceKnownStatus(md5CorrelationAttr.get(0), knownStatus);
331  } catch (CentralRepoException ex) {
332  LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database while setting artifact known status.", ex); //NON-NLS
333  }
334  }
335  }
336  }
337 
338  private final class ArtifactTagTask implements Runnable {
339 
341  private final PropertyChangeEvent event;
342 
343  private ArtifactTagTask(CentralRepository db, PropertyChangeEvent evt) {
344  dbManager = db;
345  event = evt;
346  }
347 
348  @Override
349  public void run() {
350  if (!CentralRepository.isEnabled()) {
351  return;
352  }
353 
354  Case.Events curEventType = Case.Events.valueOf(event.getPropertyName());
355  if (curEventType == Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED && event instanceof BlackBoardArtifactTagAddedEvent) {
356  handleTagAdded((BlackBoardArtifactTagAddedEvent) event);
357  } else if (curEventType == Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED && event instanceof BlackBoardArtifactTagDeletedEvent) {
358  handleTagDeleted((BlackBoardArtifactTagDeletedEvent) event);
359  } else {
360  LOGGER.log(Level.WARNING,
361  String.format("Received an event %s of type %s and was expecting either CONTENT_TAG_ADDED or CONTENT_TAG_DELETED.",
362  event, curEventType));
363  }
364  }
365 
367  // ensure tag deleted event has a valid content id
368  if (evt.getDeletedTagInfo() == null) {
369  LOGGER.log(Level.SEVERE, "BlackBoardArtifactTagDeletedEvent did not have valid content to provide a content id.");
370  return;
371  }
372 
373  try {
374  Case openCase = Case.getCurrentCaseThrows();
375 
376  // obtain content
377  Content content = openCase.getSleuthkitCase().getContentById(evt.getDeletedTagInfo().getContentID());
378  if (content == null) {
379  LOGGER.log(Level.WARNING,
380  String.format("Unable to get content for item with content id: %d.", evt.getDeletedTagInfo().getContentID()));
381  return;
382  }
383 
384  // obtain blackboard artifact
385  BlackboardArtifact bbArtifact = openCase.getSleuthkitCase().getBlackboardArtifact(evt.getDeletedTagInfo().getArtifactID());
386  if (bbArtifact == null) {
387  LOGGER.log(Level.WARNING,
388  String.format("Unable to get blackboard artifact for item with artifact id: %d.", evt.getDeletedTagInfo().getArtifactID()));
389  return;
390  }
391 
392  // then handle the event
393  handleTagChange(content, bbArtifact);
394  } catch (NoCurrentCaseException | TskCoreException ex) {
395  LOGGER.log(Level.WARNING, "Error updating non-file object.", ex);
396  }
397  }
398 
400  // ensure tag added event has a valid content id
401  if (evt.getAddedTag() == null || evt.getAddedTag().getContent() == null || evt.getAddedTag().getArtifact() == null) {
402  LOGGER.log(Level.SEVERE, "BlackBoardArtifactTagAddedEvent did not have valid content to provide a content id.");
403  return;
404  }
405 
406  // then handle the event
407  handleTagChange(evt.getAddedTag().getContent(), evt.getAddedTag().getArtifact());
408  }
409 
418  private void handleTagChange(Content content, BlackboardArtifact bbArtifact) {
419  Case openCase;
420  try {
421  openCase = Case.getCurrentCaseThrows();
422  } catch (NoCurrentCaseException ex) {
423  LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex);
424  return;
425  }
426 
427  try {
428  if (isKnownFile(content)) {
429  return;
430  }
431 
432  TagsManager tagsManager = openCase.getServices().getTagsManager();
433  List<BlackboardArtifactTag> tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact);
434  if (hasNotableTag(tags)) {
435  setArtifactKnownStatus(dbManager, bbArtifact, TskData.FileKnown.BAD);
436  } else {
437  setArtifactKnownStatus(dbManager, bbArtifact, TskData.FileKnown.UNKNOWN);
438  }
439  } catch (TskCoreException ex) {
440  LOGGER.log(Level.SEVERE, "Failed to obtain tags manager for case.", ex);
441  }
442  }
443 
451  private boolean isKnownFile(Content content) {
452  return ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN));
453  }
454 
455  }
456 
457  private final class TagDefinitionChangeTask implements Runnable {
458 
459  private final PropertyChangeEvent event;
460 
461  private TagDefinitionChangeTask(PropertyChangeEvent evt) {
462  event = evt;
463  }
464 
465  @Override
466  public void run() {
467  if (!CentralRepository.isEnabled()) {
468  return;
469  }
470  //get the display name of the tag that has had it's definition modified
471  String modifiedTagName = (String) event.getOldValue();
472 
473  /*
474  * Set knownBad status for all files/artifacts in the given case
475  * that are tagged with the given tag name.
476  */
477  try {
478  TagName tagName = Case.getCurrentCaseThrows().getServices().getTagsManager().getDisplayNamesToTagNamesMap().get(modifiedTagName);
479  //First update the artifacts
480  //Get all BlackboardArtifactTags with this tag name
481  List<BlackboardArtifactTag> artifactTags = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboardArtifactTagsByTagName(tagName);
482  for (BlackboardArtifactTag bbTag : artifactTags) {
483  //start with assumption that none of the other tags applied to this Correlation Attribute will prevent it's status from being changed
484  boolean hasTagWithConflictingKnownStatus = false;
485  // if the status of the tag has been changed to TskData.FileKnown.UNKNOWN
486  // we need to check the status of all other tags on this correlation attribute before changing
487  // the status of the correlation attribute in the central repository
488  if (tagName.getKnownStatus() == TskData.FileKnown.UNKNOWN) {
489  Content content = bbTag.getContent();
490  // If the content which this Blackboard Artifact Tag is linked to is an AbstractFile with KNOWN status then
491  // it's status in the central reporsitory should not be changed to UNKNOWN
492  if ((content instanceof AbstractFile) && (((AbstractFile) content).getKnown() == TskData.FileKnown.KNOWN)) {
493  continue;
494  }
495  //Get the BlackboardArtifact which this BlackboardArtifactTag has been applied to.
496  BlackboardArtifact bbArtifact = bbTag.getArtifact();
498  List<BlackboardArtifactTag> tags = tagsManager.getBlackboardArtifactTagsByArtifact(bbArtifact);
499  //get all tags which are on this blackboard artifact
500  for (BlackboardArtifactTag t : tags) {
501  //All instances of the modified tag name will be changed, they can not conflict with each other
502  if (t.getName().equals(tagName)) {
503  continue;
504  }
505  //if any other tags on this artifact are Notable in status then this artifact can not have its status changed
506  if (TskData.FileKnown.BAD == t.getName().getKnownStatus()) {
507  //a tag with a conflicting status has been found, the status of this correlation attribute can not be modified
508  hasTagWithConflictingKnownStatus = true;
509  break;
510  }
511  }
512  }
513  //if the Correlation Attribute will have no tags with a status which would prevent the current status from being changed
514  if (!hasTagWithConflictingKnownStatus) {
515  setArtifactKnownStatus(CentralRepository.getInstance(), bbTag.getArtifact(), tagName.getKnownStatus());
516  }
517  }
518  // Next update the files
519 
520  List<ContentTag> fileTags = Case.getCurrentCaseThrows().getSleuthkitCase().getContentTagsByTagName(tagName);
521  //Get all ContentTags with this tag name
522  for (ContentTag contentTag : fileTags) {
523  //start with assumption that none of the other tags applied to this ContentTag will prevent it's status from being changed
524  boolean hasTagWithConflictingKnownStatus = false;
525  // if the status of the tag has been changed to TskData.FileKnown.UNKNOWN
526  // we need to check the status of all other tags on this file before changing
527  // the status of the file in the central repository
528  if (tagName.getKnownStatus() == TskData.FileKnown.UNKNOWN) {
529  Content content = contentTag.getContent();
531  List<ContentTag> tags = tagsManager.getContentTagsByContent(content);
532  //get all tags which are on this file
533  for (ContentTag t : tags) {
534  //All instances of the modified tag name will be changed, they can not conflict with each other
535  if (t.getName().equals(tagName)) {
536  continue;
537  }
538  //if any other tags on this file are Notable in status then this file can not have its status changed
539  if (TskData.FileKnown.BAD == t.getName().getKnownStatus()) {
540  //a tag with a conflicting status has been found, the status of this file can not be modified
541  hasTagWithConflictingKnownStatus = true;
542  break;
543  }
544  }
545  }
546  //if the file will have no tags with a status which would prevent the current status from being changed
547  if (!hasTagWithConflictingKnownStatus) {
548  Content taggedContent = contentTag.getContent();
549  if (taggedContent instanceof AbstractFile) {
550  final List<CorrelationAttributeInstance> eamArtifact = CorrelationAttributeUtil.makeCorrAttrsForSearch((AbstractFile) taggedContent);
551  if (!eamArtifact.isEmpty()) {
552  //for an abstract file the 'list' of attributes will be a single attribute or empty and is returning a list for consistency with other makeCorrAttrsForSearch methods per 7852
553  CentralRepository.getInstance().setAttributeInstanceKnownStatus(eamArtifact.get(0), tagName.getKnownStatus());
554  }
555  }
556  }
557  }
558  } catch (TskCoreException ex) {
559  LOGGER.log(Level.SEVERE, "Cannot update known status in central repository for tag: " + modifiedTagName, ex); //NON-NLS
560  } catch (CentralRepoException ex) {
561  LOGGER.log(Level.SEVERE, "Cannot get central repository for tag: " + modifiedTagName, ex); //NON-NLS
562  } catch (NoCurrentCaseException ex) {
563  LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
564  }
565  } //TAG_STATUS_CHANGED
566  }
567 
568  private final class DataSourceAddedTask implements Runnable {
569 
571  private final PropertyChangeEvent event;
572 
573  private DataSourceAddedTask(CentralRepository db, PropertyChangeEvent evt) {
574  dbManager = db;
575  event = evt;
576  }
577 
578  @Override
579  public void run() {
580  if (!CentralRepository.isEnabled()) {
581  return;
582  }
583  Case openCase;
584  try {
585  openCase = Case.getCurrentCaseThrows();
586  } catch (NoCurrentCaseException ex) {
587  LOGGER.log(Level.SEVERE, "Exception while getting open case.", ex);
588  return;
589  }
590 
591  final DataSourceAddedEvent dataSourceAddedEvent = (DataSourceAddedEvent) event;
592  Content newDataSource = dataSourceAddedEvent.getDataSource();
593 
594  try {
595  CorrelationCase correlationCase = dbManager.getCase(openCase);
596  if (null == dbManager.getDataSource(correlationCase, newDataSource.getId())) {
597  CorrelationDataSource.fromTSKDataSource(correlationCase, newDataSource);
598  }
599  } catch (CentralRepoException ex) {
600  LOGGER.log(Level.SEVERE, "Error adding new data source to the central repository", ex); //NON-NLS
601  }
602  } // DATA_SOURCE_ADDED
603  }
604 
605  private final class CurrentCaseTask implements Runnable {
606 
608  private final PropertyChangeEvent event;
609 
610  private CurrentCaseTask(CentralRepository db, PropertyChangeEvent evt) {
611  dbManager = db;
612  event = evt;
613  }
614 
615  @Override
616  public void run() {
617  /*
618  * A case has been opened if evt.getOldValue() is null and
619  * evt.getNewValue() is a valid Case.
620  */
621  if ((null == event.getOldValue()) && (event.getNewValue() instanceof Case)) {
622  Case curCase = (Case) event.getNewValue();
623 
624  if (!CentralRepository.isEnabled()) {
625  return;
626  }
627 
628  try {
629  // NOTE: Cannot determine if the opened case is a new case or a reopened case,
630  // so check for existing name in DB and insert if missing.
631  if (dbManager.getCase(curCase) == null) {
632  dbManager.newCase(curCase);
633  }
634  } catch (CentralRepoException ex) {
635  LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS
636  }
637  }
638  } // CURRENT_CASE
639  }
640 
641  private final class DataSourceNameChangedTask implements Runnable {
642 
644  private final PropertyChangeEvent event;
645 
646  private DataSourceNameChangedTask(CentralRepository db, PropertyChangeEvent evt) {
647  dbManager = db;
648  event = evt;
649  }
650 
651  @Override
652  public void run() {
653 
654  final DataSourceNameChangedEvent dataSourceNameChangedEvent = (DataSourceNameChangedEvent) event;
655  Content dataSource = dataSourceNameChangedEvent.getDataSource();
656  String newName = (String) event.getNewValue();
657 
658  if (!StringUtils.isEmpty(newName)) {
659 
660  if (!CentralRepository.isEnabled()) {
661  return;
662  }
663 
664  try {
665  CorrelationCase correlationCase = dbManager.getCase(Case.getCurrentCaseThrows());
666  CorrelationDataSource existingEamDataSource = dbManager.getDataSource(correlationCase, dataSource.getId());
667  dbManager.updateDataSourceName(existingEamDataSource, newName);
668  } catch (CentralRepoException ex) {
669  LOGGER.log(Level.SEVERE, "Error updating data source with ID " + dataSource.getId() + " to " + newName, ex); //NON-NLS
670  } catch (NoCurrentCaseException ex) {
671  LOGGER.log(Level.SEVERE, "No open case", ex);
672  }
673  }
674  }
675  }
676 
677 }
static CorrelationDataSource fromTSKDataSource(CorrelationCase correlationCase, Content dataSource)
List< ContentTag > getContentTagsByContent(Content content)
void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus)
static void shutDownTaskExecutor(ExecutorService executor)
static List< CorrelationAttributeInstance > makeCorrAttrsForSearch(AnalysisResult analysisResult)
static void setArtifactKnownStatus(CentralRepository centralRepo, BlackboardArtifact artifact, TskData.FileKnown notableStatus)
void updateDataSourceName(CorrelationDataSource eamDataSource, String newName)
CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long caseDbDataSourceId)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:711
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:756
List< BlackboardArtifactTag > getBlackboardArtifactTagsByArtifact(BlackboardArtifact artifact)

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