19 package org.sleuthkit.autopsy.datamodel;
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;
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;
89 String ext = abstractFile.getNameExtension();
90 if (StringUtils.isNotBlank(ext)) {
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);
110 backgroundTasksPool.submit(
new TranslationTask(
111 new WeakReference<>(
this),
weakPcl));
139 private final PropertyChangeListener
pcl = (PropertyChangeEvent evt) -> {
140 String eventType = evt.getPropertyName();
148 if ((moduleContentEvent.getSource() instanceof Content) ==
false) {
151 Content newContent = (Content) moduleContentEvent.getSource();
154 if (
getContent().getId() == newContent.getId()) {
162 }
catch (NullPointerException ex) {
165 logger.log(Level.WARNING,
"Failed to post key refresh event", ex);
169 if (evt.getNewValue() == null) {
181 if (event.getAddedTag().getContent().equals(content)) {
184 Score value = scorePropAndDescr.getLeft();
185 String descr = scorePropAndDescr.getRight();
193 if (event.getDeletedTagInfo().getContentID() == content.getId()) {
196 Score value = scorePropAndDescr.getLeft();
197 String descr = scorePropAndDescr.getRight();
205 if (event.getContentID() == content.getId()) {
210 }
else if (eventType.equals(NodeSpecificEvents.TRANSLATION_AVAILABLE.toString())) {
211 this.setDisplayName(evt.getNewValue().toString());
213 this.setShortDescription(content.getName());
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()));
220 if (scoData.getComment() != null) {
223 if (scoData.getCountAndDescription() != null) {
224 updateSheet(
new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
236 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(pcl, null);
246 Sheet sheet =
new Sheet();
247 Sheet.Set sheetSet = Sheet.createPropertiesSet();
252 newProperties.forEach((property) -> {
253 sheetSet.put(property);
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"})
286 NAME(AbstractAbstractFileNode_nameColLbl()),
288 SCORE(AbstractAbstractFileNode_createSheet_score_name()),
289 COMMENT(AbstractAbstractFileNode_createSheet_comment_name()),
291 LOCATION(AbstractAbstractFileNode_locationColLbl()),
292 MOD_TIME(AbstractAbstractFileNode_modifiedTimeColLbl()),
296 SIZE(AbstractAbstractFileNode_sizeColLbl()),
299 MODE(AbstractAbstractFileNode_modeColLbl()),
300 USER_ID(AbstractAbstractFileNode_useridColLbl()),
301 GROUP_ID(AbstractAbstractFileNode_groupidColLbl()),
304 TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
306 KNOWN(AbstractAbstractFileNode_knownColLbl()),
307 MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
315 this.displayString = displayString;
320 return displayString;
328 List<NodeProperty<?>> properties =
new ArrayList<>();
329 properties.add(
new NodeProperty<>(NAME.toString(), NAME.toString(),
NO_DESCR, getContentDisplayName(content)));
347 backgroundTasksPool.submit(
new GetSCOTask(
348 new WeakReference<>(
this), weakPcl));
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()));
376 @NbBundle.Messages(
"AbstractAbstractFileNode.tagsProperty.displayName=Tags")
379 List<ContentTag> tags = getContentTagsFromDatabase();
380 sheetSet.put(
new NodeProperty<>(
"Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
381 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
383 .collect(Collectors.joining(
", "))));
399 return StringUtils.join(file.getHashSetNames(),
", ");
400 }
catch (TskCoreException tskCoreException) {
401 logger.log(Level.WARNING,
"Error getting hashset hits: ", tskCoreException);
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"})
413 String defaultDescription) {
415 String description = defaultDescription;
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();
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);
429 return Pair.of(count, description);
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"})
442 String description = Bundle.AbstractAbstractFileNode_createSheet_noScore_description();
443 if (content.getKnown() == TskData.FileKnown.BAD) {
445 description = Bundle.AbstractAbstractFileNode_createSheet_notableFile_description();
450 description = Bundle.AbstractAbstractFileNode_createSheet_interestingResult_description();
452 }
catch (TskCoreException ex) {
453 logger.log(Level.WARNING,
"Error getting artifacts for file: " + content.getName(), ex);
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();
466 return Pair.of(score, description);
470 "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
476 for (Tag tag : tags) {
477 if (!StringUtils.isBlank(tag.getComment())) {
483 if (attribute != null && !StringUtils.isBlank(attribute.
getComment())) {
499 String getTranslatedFileName() {
502 }
catch (NoServiceProviderException | TranslationException ex) {
503 logger.log(Level.WARNING, MessageFormat.format(
"Error translating file name (objID={0}))", content.getId()), ex);
513 List<ContentTag> getContentTagsFromDatabase() {
514 List<ContentTag> tags =
new ArrayList<>();
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);
525 return new ArrayList<>(getContentTagsFromDatabase());
537 static String getContentPath(AbstractFile file) {
539 return file.getUniquePath();
540 }
catch (TskCoreException ex) {
541 logger.log(Level.SEVERE,
"Except while calling Content.getUniquePath() on " + file.getName(), ex);
546 static String getContentDisplayName(AbstractFile file) {
547 String name = file.getName();
550 return DirectoryNode.DOTDOTDIR;
552 return DirectoryNode.DOTDIR;
569 map.put(NAME.toString(), getContentDisplayName(content));
570 map.put(LOCATION.toString(), getContentPath(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());
synchronized void updateSheet(NodeProperty<?>...newProps)
static final Logger logger
static final String VALUE_LOADING
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static String getStringTime(long epochSeconds, TimeZone tzone)
static List< String > getArchiveExtensions()
final String displayString
static synchronized IngestManager getInstance()
CorrelationAttributeInstance getCorrelationAttributeInstance()
synchronized Sheet createSheet()
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
Pair< DataResultViewerTable.Score, String > getScorePropertyAndDescription(List< Tag > tags)
List< Tag > getAllTagsFromDatabase()
static void fillPropertyMap(Map< String, Object > map, AbstractFile content)
static String translate(String fileName)
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
static TextTranslationService getInstance()
static boolean displayTranslatedFileNames()
Pair< Long, String > getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription)
static CorrelationAttributeInstance getCorrAttrForFile(AbstractFile file)
static boolean getHideSCOColumns()
AbstractFilePropertyType(String displayString)
synchronized boolean hasProvider()
static void post(String nodeName, Object event)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
HasCommentStatus getCommentProperty(List< Tag > tags, CorrelationAttributeInstance attribute)
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
final PropertyChangeListener pcl
List< NodeProperty<?> > getProperties()
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
static CentralRepository getInstance()
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
static String getHashSetHitsCsvList(AbstractFile file)
void addTagProperty(Sheet.Set sheetSet)
static boolean isEnabled()
final PropertyChangeListener weakPcl
static final String NO_DESCR