Autopsy  4.15.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
AbstractAbstractFileNode.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2012-2020 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.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.lang.ref.WeakReference;
24 import java.text.MessageFormat;
25 import java.util.ArrayList;
26 import java.util.EnumSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.logging.Level;
31 import java.util.stream.Collectors;
32 import org.apache.commons.lang3.StringUtils;
33 import org.apache.commons.lang3.tuple.Pair;
34 import org.openide.nodes.Sheet;
35 import org.openide.util.NbBundle;
36 import org.openide.util.WeakListeners;
51 import static org.sleuthkit.autopsy.datamodel.Bundle.*;
61 import org.sleuthkit.datamodel.AbstractFile;
62 import org.sleuthkit.datamodel.BlackboardArtifact;
63 import org.sleuthkit.datamodel.Content;
64 import org.sleuthkit.datamodel.ContentTag;
65 import org.sleuthkit.datamodel.Tag;
66 import org.sleuthkit.datamodel.TskCoreException;
67 import org.sleuthkit.datamodel.TskData;
70 
76 public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends AbstractContentNode<T> {
77 
78  private static final Logger logger = Logger.getLogger(AbstractAbstractFileNode.class.getName());
79 
80  private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
82  private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(CONTENT_CHANGED);
83 
87  AbstractAbstractFileNode(T abstractFile) {
88  super(abstractFile);
89  String ext = abstractFile.getNameExtension();
90  if (StringUtils.isNotBlank(ext)) {
91  ext = "." + ext;
92  // If this is an archive file we will listen for ingest events
93  // that will notify us when new content has been identified.
94  if (FileTypeExtensions.getArchiveExtensions().contains(ext)) {
96  }
97  }
98 
99  try {
100  //See JIRA-5971
101  //Attempt to cache file path during construction of this UI component.
102  this.content.getUniquePath();
103  } catch (TskCoreException ex) {
104  logger.log(Level.SEVERE, String.format("Failed attempt to cache the "
105  + "unique path of the abstract file instance. Name: %s (objID=%d)",
106  this.content.getName(), this.content.getId()), ex);
107  }
108 
110  backgroundTasksPool.submit(new TranslationTask(
111  new WeakReference<>(this), weakPcl));
112  }
113 
114  // Listen for case events so that we can detect when the case is closed
115  // or when tags are added.
117  }
118 
128  @Override
129  protected void finalize() throws Throwable {
130  super.finalize();
131  removeListeners();
132  }
133 
134  private void removeListeners() {
137  }
138 
139  private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
140  String eventType = evt.getPropertyName();
141 
142  // Is this a content changed event?
143  if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
144  if ((evt.getOldValue() instanceof ModuleContentEvent) == false) {
145  return;
146  }
147  ModuleContentEvent moduleContentEvent = (ModuleContentEvent) evt.getOldValue();
148  if ((moduleContentEvent.getSource() instanceof Content) == false) {
149  return;
150  }
151  Content newContent = (Content) moduleContentEvent.getSource();
152 
153  // Does the event indicate that content has been added to *this* file?
154  if (getContent().getId() == newContent.getId()) {
155  // If so, refresh our children.
156  try {
157  // We only want to refresh our parents children if we are in the
158  // data sources branch of the tree. The parent nodes in other
159  // branches of the tree (e.g. File Types and Deleted Files) do
160  // not need to be refreshed.
161  BaseChildFactory.post(getParentNode().getName(), new RefreshKeysEvent());
162  } catch (NullPointerException ex) {
163  // Skip
164  } catch (NoSuchEventBusException ex) {
165  logger.log(Level.WARNING, "Failed to post key refresh event", ex); //NON-NLS
166  }
167  }
168  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
169  if (evt.getNewValue() == null) {
170  // case was closed. Remove listeners so that we don't get called with a stale case handle
171  removeListeners();
172  }
173  /*
174  * No need to do any asynchrony around tag added, deleted or CR
175  * change events, they are so infrequent and user driven that we can
176  * just keep a simple blocking approach, where we go out to the
177  * database ourselves.
178  */
179  } else if (eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())) {
181  if (event.getAddedTag().getContent().equals(content)) {
182  List<Tag> tags = this.getAllTagsFromDatabase();
183  Pair<Score, String> scorePropAndDescr = getScorePropertyAndDescription(tags);
184  Score value = scorePropAndDescr.getLeft();
185  String descr = scorePropAndDescr.getRight();
187  updateSheet(new NodeProperty<>(SCORE.toString(), SCORE.toString(), descr, value),
188  new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, getCommentProperty(tags, attribute))
189  );
190  }
191  } else if (eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) {
193  if (event.getDeletedTagInfo().getContentID() == content.getId()) {
194  List<Tag> tags = getAllTagsFromDatabase();
195  Pair<Score, String> scorePropAndDescr = getScorePropertyAndDescription(tags);
196  Score value = scorePropAndDescr.getLeft();
197  String descr = scorePropAndDescr.getRight();
199  updateSheet(new NodeProperty<>(SCORE.toString(), SCORE.toString(), descr, value),
200  new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, getCommentProperty(tags, attribute))
201  );
202  }
203  } else if (eventType.equals(Case.Events.CR_COMMENT_CHANGED.toString())) {
205  if (event.getContentID() == content.getId()) {
206  List<Tag> tags = getAllTagsFromDatabase();
208  updateSheet(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, getCommentProperty(tags, attribute)));
209  }
210  } else if (eventType.equals(NodeSpecificEvents.TRANSLATION_AVAILABLE.toString())) {
211  this.setDisplayName(evt.getNewValue().toString());
212  //Set the tooltip
213  this.setShortDescription(content.getName());
214  updateSheet(new NodeProperty<>(ORIGINAL_NAME.toString(), ORIGINAL_NAME.toString(), NO_DESCR, content.getName()));
215  } else if (eventType.equals(NodeSpecificEvents.SCO_AVAILABLE.toString()) && !UserPreferences.getHideSCOColumns()) {
216  SCOData scoData = (SCOData) evt.getNewValue();
217  if (scoData.getScoreAndDescription() != null) {
218  updateSheet(new NodeProperty<>(SCORE.toString(), SCORE.toString(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft()));
219  }
220  if (scoData.getComment() != null) {
221  updateSheet(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, scoData.getComment()));
222  }
223  if (scoData.getCountAndDescription() != null) {
224  updateSheet(new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
225  }
226  }
227  };
236  private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
237 
238  /*
239  * This is called when the node is first initialized. Any new updates or
240  * changes happen by directly manipulating the sheet. That means we can fire
241  * off background events everytime this method is called and not worry about
242  * duplicated jobs.
243  */
244  @Override
245  protected synchronized Sheet createSheet() {
246  Sheet sheet = new Sheet();
247  Sheet.Set sheetSet = Sheet.createPropertiesSet();
248  sheet.put(sheetSet);
249 
250  //This will fire off fresh background tasks.
251  List<NodeProperty<?>> newProperties = getProperties();
252  newProperties.forEach((property) -> {
253  sheetSet.put(property);
254  });
255 
256  return sheet;
257  }
258 
259  @NbBundle.Messages({"AbstractAbstractFileNode.nameColLbl=Name",
260  "AbstractAbstractFileNode.originalName=Original Name",
261  "AbstractAbstractFileNode.createSheet.score.name=S",
262  "AbstractAbstractFileNode.createSheet.comment.name=C",
263  "AbstractAbstractFileNode.createSheet.count.name=O",
264  "AbstractAbstractFileNode.locationColLbl=Location",
265  "AbstractAbstractFileNode.modifiedTimeColLbl=Modified Time",
266  "AbstractAbstractFileNode.changeTimeColLbl=Change Time",
267  "AbstractAbstractFileNode.accessTimeColLbl=Access Time",
268  "AbstractAbstractFileNode.createdTimeColLbl=Created Time",
269  "AbstractAbstractFileNode.sizeColLbl=Size",
270  "AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir)",
271  "AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta)",
272  "AbstractAbstractFileNode.modeColLbl=Mode",
273  "AbstractAbstractFileNode.useridColLbl=UserID",
274  "AbstractAbstractFileNode.groupidColLbl=GroupID",
275  "AbstractAbstractFileNode.metaAddrColLbl=Meta Addr.",
276  "AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr.",
277  "AbstractAbstractFileNode.typeDirColLbl=Type(Dir)",
278  "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)",
279  "AbstractAbstractFileNode.knownColLbl=Known",
280  "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash",
281  "AbstractAbstractFileNode.objectId=Object ID",
282  "AbstractAbstractFileNode.mimeType=MIME Type",
283  "AbstractAbstractFileNode.extensionColLbl=Extension"})
285 
286  NAME(AbstractAbstractFileNode_nameColLbl()),
287  ORIGINAL_NAME(AbstractAbstractFileNode_originalName()),
288  SCORE(AbstractAbstractFileNode_createSheet_score_name()),
289  COMMENT(AbstractAbstractFileNode_createSheet_comment_name()),
290  OCCURRENCES(AbstractAbstractFileNode_createSheet_count_name()),
291  LOCATION(AbstractAbstractFileNode_locationColLbl()),
292  MOD_TIME(AbstractAbstractFileNode_modifiedTimeColLbl()),
293  CHANGED_TIME(AbstractAbstractFileNode_changeTimeColLbl()),
294  ACCESS_TIME(AbstractAbstractFileNode_accessTimeColLbl()),
295  CREATED_TIME(AbstractAbstractFileNode_createdTimeColLbl()),
296  SIZE(AbstractAbstractFileNode_sizeColLbl()),
297  FLAGS_DIR(AbstractAbstractFileNode_flagsDirColLbl()),
298  FLAGS_META(AbstractAbstractFileNode_flagsMetaColLbl()),
299  MODE(AbstractAbstractFileNode_modeColLbl()),
300  USER_ID(AbstractAbstractFileNode_useridColLbl()),
301  GROUP_ID(AbstractAbstractFileNode_groupidColLbl()),
302  META_ADDR(AbstractAbstractFileNode_metaAddrColLbl()),
303  ATTR_ADDR(AbstractAbstractFileNode_attrAddrColLbl()),
304  TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
305  TYPE_META(AbstractAbstractFileNode_typeMetaColLbl()),
306  KNOWN(AbstractAbstractFileNode_knownColLbl()),
307  MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
308  ObjectID(AbstractAbstractFileNode_objectId()),
309  MIMETYPE(AbstractAbstractFileNode_mimeType()),
310  EXTENSION(AbstractAbstractFileNode_extensionColLbl());
311 
312  final private String displayString;
313 
314  private AbstractFilePropertyType(String displayString) {
315  this.displayString = displayString;
316  }
317 
318  @Override
319  public String toString() {
320  return displayString;
321  }
322  }
323 
327  private List<NodeProperty<?>> getProperties() {
328  List<NodeProperty<?>> properties = new ArrayList<>();
329  properties.add(new NodeProperty<>(NAME.toString(), NAME.toString(), NO_DESCR, getContentDisplayName(content)));
330  /*
331  * Initialize an empty place holder value. At the bottom, we kick off a
332  * background task that promises to update these values.
333  */
334 
336  properties.add(new NodeProperty<>(ORIGINAL_NAME.toString(), ORIGINAL_NAME.toString(), NO_DESCR, ""));
337  }
338 
339  // Create place holders for S C O
341  properties.add(new NodeProperty<>(SCORE.toString(), SCORE.toString(), VALUE_LOADING, ""));
342  properties.add(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), VALUE_LOADING, ""));
344  properties.add(new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), VALUE_LOADING, ""));
345  }
346  // Get the SCO columns data in a background task
347  backgroundTasksPool.submit(new GetSCOTask(
348  new WeakReference<>(this), weakPcl));
349  }
350 
351  properties.add(new NodeProperty<>(MOD_TIME.toString(), MOD_TIME.toString(), NO_DESCR, ContentUtils.getStringTime(content.getMtime(), content)));
352  properties.add(new NodeProperty<>(CHANGED_TIME.toString(), CHANGED_TIME.toString(), NO_DESCR, ContentUtils.getStringTime(content.getCtime(), content)));
353  properties.add(new NodeProperty<>(ACCESS_TIME.toString(), ACCESS_TIME.toString(), NO_DESCR, ContentUtils.getStringTime(content.getAtime(), content)));
354  properties.add(new NodeProperty<>(CREATED_TIME.toString(), CREATED_TIME.toString(), NO_DESCR, ContentUtils.getStringTime(content.getCrtime(), content)));
355  properties.add(new NodeProperty<>(SIZE.toString(), SIZE.toString(), NO_DESCR, content.getSize()));
356  properties.add(new NodeProperty<>(FLAGS_DIR.toString(), FLAGS_DIR.toString(), NO_DESCR, content.getDirFlagAsString()));
357  properties.add(new NodeProperty<>(FLAGS_META.toString(), FLAGS_META.toString(), NO_DESCR, content.getMetaFlagsAsString()));
358  properties.add(new NodeProperty<>(KNOWN.toString(), KNOWN.toString(), NO_DESCR, content.getKnown().getName()));
359  properties.add(new NodeProperty<>(LOCATION.toString(), LOCATION.toString(), NO_DESCR, getContentPath(content)));
360  properties.add(new NodeProperty<>(MD5HASH.toString(), MD5HASH.toString(), NO_DESCR, StringUtils.defaultString(content.getMd5Hash())));
361  properties.add(new NodeProperty<>(MIMETYPE.toString(), MIMETYPE.toString(), NO_DESCR, StringUtils.defaultString(content.getMIMEType())));
362  properties.add(new NodeProperty<>(EXTENSION.toString(), EXTENSION.toString(), NO_DESCR, content.getNameExtension()));
363 
364  return properties;
365  }
366 
376  @NbBundle.Messages("AbstractAbstractFileNode.tagsProperty.displayName=Tags")
377  @Deprecated
378  protected void addTagProperty(Sheet.Set sheetSet) {
379  List<ContentTag> tags = getContentTagsFromDatabase();
380  sheetSet.put(new NodeProperty<>("Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
381  NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
382  .distinct()
383  .collect(Collectors.joining(", "))));
384  }
385 
396  @Deprecated
397  protected static String getHashSetHitsCsvList(AbstractFile file) {
398  try {
399  return StringUtils.join(file.getHashSetNames(), ", ");
400  } catch (TskCoreException tskCoreException) {
401  logger.log(Level.WARNING, "Error getting hashset hits: ", tskCoreException); //NON-NLS
402  return "";
403  }
404  }
405 
406  @NbBundle.Messages({
407  "AbstractAbstractFileNode.createSheet.count.displayName=O",
408  "AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated",
409  "# {0} - occurrenceCount",
410  "AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the MD5 correlation value"})
411  @Override
412  protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue,
413  String defaultDescription) {
414  Long count = -1L; //The column renderer will not display negative values, negative value used when count unavailble to preserve sorting
415  String description = defaultDescription;
416  try {
417  //don't perform the query if there is no correlation value
418  if (attributeType != null && StringUtils.isNotBlank(attributeValue)) {
420  description = Bundle.AbstractAbstractFileNode_createSheet_count_description(count);
421  } else if (attributeType != null) {
422  description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
423  }
424  } catch (CentralRepoException ex) {
425  logger.log(Level.WARNING, "Error getting count of datasources with correlation attribute", ex);
427  logger.log(Level.WARNING, "Unable to normalize data to get count of datasources with correlation attribute", ex);
428  }
429  return Pair.of(count, description);
430  }
431 
432  @NbBundle.Messages({
433  "AbstractAbstractFileNode.createSheet.score.displayName=S",
434  "AbstractAbstractFileNode.createSheet.notableFile.description=File recognized as notable.",
435  "AbstractAbstractFileNode.createSheet.interestingResult.description=File has interesting result associated with it.",
436  "AbstractAbstractFileNode.createSheet.taggedFile.description=File has been tagged.",
437  "AbstractAbstractFileNode.createSheet.notableTaggedFile.description=File tagged with notable tag.",
438  "AbstractAbstractFileNode.createSheet.noScore.description=No score"})
439  @Override
440  protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
442  String description = Bundle.AbstractAbstractFileNode_createSheet_noScore_description();
443  if (content.getKnown() == TskData.FileKnown.BAD) {
445  description = Bundle.AbstractAbstractFileNode_createSheet_notableFile_description();
446  }
447  try {
448  if (score == DataResultViewerTable.Score.NO_SCORE && !content.getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT).isEmpty()) {
450  description = Bundle.AbstractAbstractFileNode_createSheet_interestingResult_description();
451  }
452  } catch (TskCoreException ex) {
453  logger.log(Level.WARNING, "Error getting artifacts for file: " + content.getName(), ex);
454  }
455  if (!tags.isEmpty() && (score == DataResultViewerTable.Score.NO_SCORE || score == DataResultViewerTable.Score.INTERESTING_SCORE)) {
457  description = Bundle.AbstractAbstractFileNode_createSheet_taggedFile_description();
458  for (Tag tag : tags) {
459  if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
461  description = Bundle.AbstractAbstractFileNode_createSheet_notableTaggedFile_description();
462  break;
463  }
464  }
465  }
466  return Pair.of(score, description);
467  }
468 
469  @NbBundle.Messages({
470  "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
471  @Override
472  protected HasCommentStatus getCommentProperty(List<Tag> tags, CorrelationAttributeInstance attribute) {
473 
475 
476  for (Tag tag : tags) {
477  if (!StringUtils.isBlank(tag.getComment())) {
478  //if the tag is null or empty or contains just white space it will indicate there is not a comment
480  break;
481  }
482  }
483  if (attribute != null && !StringUtils.isBlank(attribute.getComment())) {
486  } else {
488  }
489  }
490  return status;
491  }
492 
499  String getTranslatedFileName() {
500  try {
501  return FileNameTranslationUtil.translate(content.getName());
502  } catch (NoServiceProviderException | TranslationException ex) {
503  logger.log(Level.WARNING, MessageFormat.format("Error translating file name (objID={0}))", content.getId()), ex);
504  return "";
505  }
506  }
507 
513  List<ContentTag> getContentTagsFromDatabase() {
514  List<ContentTag> tags = new ArrayList<>();
515  try {
516  tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(content));
517  } catch (TskCoreException | NoCurrentCaseException ex) {
518  logger.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex);
519  }
520  return tags;
521  }
522 
523  @Override
524  protected List<Tag> getAllTagsFromDatabase() {
525  return new ArrayList<>(getContentTagsFromDatabase());
526  }
527 
528  @Override
530  CorrelationAttributeInstance attribute = null;
532  attribute = CorrelationAttributeUtil.getCorrAttrForFile(content);
533  }
534  return attribute;
535  }
536 
537  static String getContentPath(AbstractFile file) {
538  try {
539  return file.getUniquePath();
540  } catch (TskCoreException ex) {
541  logger.log(Level.SEVERE, "Except while calling Content.getUniquePath() on " + file.getName(), ex); //NON-NLS
542  return ""; //NON-NLS
543  }
544  }
545 
546  static String getContentDisplayName(AbstractFile file) {
547  String name = file.getName();
548  switch (name) {
549  case "..":
550  return DirectoryNode.DOTDOTDIR;
551  case ".":
552  return DirectoryNode.DOTDIR;
553  default:
554  return name;
555  }
556  }
557 
568  static public void fillPropertyMap(Map<String, Object> map, AbstractFile content) {
569  map.put(NAME.toString(), getContentDisplayName(content));
570  map.put(LOCATION.toString(), getContentPath(content));
571  map.put(MOD_TIME.toString(), ContentUtils.getStringTime(content.getMtime(), content));
572  map.put(CHANGED_TIME.toString(), ContentUtils.getStringTime(content.getCtime(), content));
573  map.put(ACCESS_TIME.toString(), ContentUtils.getStringTime(content.getAtime(), content));
574  map.put(CREATED_TIME.toString(), ContentUtils.getStringTime(content.getCrtime(), content));
575  map.put(SIZE.toString(), content.getSize());
576  map.put(FLAGS_DIR.toString(), content.getDirFlagAsString());
577  map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());
578  map.put(KNOWN.toString(), content.getKnown().getName());
579  map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
580  map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
581  map.put(EXTENSION.toString(), content.getNameExtension());
582  }
583 }
synchronized void updateSheet(NodeProperty<?>...newProps)
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static String getStringTime(long epochSeconds, TimeZone tzone)
static synchronized IngestManager getInstance()
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
Pair< DataResultViewerTable.Score, String > getScorePropertyAndDescription(List< Tag > tags)
static void fillPropertyMap(Map< String, Object > map, AbstractFile content)
Pair< Long, String > getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription)
static CorrelationAttributeInstance getCorrAttrForFile(AbstractFile file)
static void post(String nodeName, Object event)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
HasCommentStatus getCommentProperty(List< Tag > tags, CorrelationAttributeInstance attribute)
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:491
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:536
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)

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