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.sha256HashColLbl=SHA-256 Hash",
282 "AbstractAbstractFileNode.objectId=Object ID",
283 "AbstractAbstractFileNode.mimeType=MIME Type",
284 "AbstractAbstractFileNode.extensionColLbl=Extension"})
287 NAME(AbstractAbstractFileNode_nameColLbl()),
289 SCORE(AbstractAbstractFileNode_createSheet_score_name()),
290 COMMENT(AbstractAbstractFileNode_createSheet_comment_name()),
292 LOCATION(AbstractAbstractFileNode_locationColLbl()),
293 MOD_TIME(AbstractAbstractFileNode_modifiedTimeColLbl()),
297 SIZE(AbstractAbstractFileNode_sizeColLbl()),
300 MODE(AbstractAbstractFileNode_modeColLbl()),
301 USER_ID(AbstractAbstractFileNode_useridColLbl()),
302 GROUP_ID(AbstractAbstractFileNode_groupidColLbl()),
305 TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
307 KNOWN(AbstractAbstractFileNode_knownColLbl()),
308 MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
317 this.displayString = displayString;
322 return displayString;
330 List<NodeProperty<?>> properties =
new ArrayList<>();
331 properties.add(
new NodeProperty<>(NAME.toString(), NAME.toString(),
NO_DESCR, getContentDisplayName(content)));
349 backgroundTasksPool.submit(
new GetSCOTask(
350 new WeakReference<>(
this), weakPcl));
358 properties.add(
new NodeProperty<>(FLAGS_DIR.toString(), FLAGS_DIR.toString(),
NO_DESCR, content.getDirFlagAsString()));
359 properties.add(
new NodeProperty<>(FLAGS_META.toString(), FLAGS_META.toString(),
NO_DESCR, content.getMetaFlagsAsString()));
360 properties.add(
new NodeProperty<>(KNOWN.toString(), KNOWN.toString(),
NO_DESCR, content.getKnown().getName()));
361 properties.add(
new NodeProperty<>(LOCATION.toString(), LOCATION.toString(),
NO_DESCR, getContentPath(content)));
362 properties.add(
new NodeProperty<>(MD5HASH.toString(), MD5HASH.toString(),
NO_DESCR, StringUtils.defaultString(content.getMd5Hash())));
363 properties.add(
new NodeProperty<>(SHA256HASH.toString(), SHA256HASH.toString(),
NO_DESCR, StringUtils.defaultString(content.getSha256Hash())));
364 properties.add(
new NodeProperty<>(MIMETYPE.toString(), MIMETYPE.toString(),
NO_DESCR, StringUtils.defaultString(content.getMIMEType())));
365 properties.add(
new NodeProperty<>(EXTENSION.toString(), EXTENSION.toString(),
NO_DESCR, content.getNameExtension()));
379 @NbBundle.Messages(
"AbstractAbstractFileNode.tagsProperty.displayName=Tags")
382 List<ContentTag> tags = getContentTagsFromDatabase();
383 sheetSet.put(
new NodeProperty<>(
"Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
384 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
386 .collect(Collectors.joining(
", "))));
402 return StringUtils.join(file.getHashSetNames(),
", ");
403 }
catch (TskCoreException tskCoreException) {
404 logger.log(Level.WARNING,
"Error getting hashset hits: ", tskCoreException);
410 "AbstractAbstractFileNode.createSheet.count.displayName=O",
411 "AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated",
412 "# {0} - occurrenceCount",
413 "AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the MD5 correlation value"})
416 String defaultDescription) {
418 String description = defaultDescription;
421 if (attributeType != null && StringUtils.isNotBlank(attributeValue)) {
423 description = Bundle.AbstractAbstractFileNode_createSheet_count_description(count);
424 }
else if (attributeType != null) {
425 description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
428 logger.log(Level.WARNING,
"Error getting count of datasources with correlation attribute", ex);
430 logger.log(Level.WARNING,
"Unable to normalize data to get count of datasources with correlation attribute", ex);
432 return Pair.of(count, description);
436 "AbstractAbstractFileNode.createSheet.score.displayName=S",
437 "AbstractAbstractFileNode.createSheet.notableFile.description=File recognized as notable.",
438 "AbstractAbstractFileNode.createSheet.interestingResult.description=File has interesting result associated with it.",
439 "AbstractAbstractFileNode.createSheet.taggedFile.description=File has been tagged.",
440 "AbstractAbstractFileNode.createSheet.notableTaggedFile.description=File tagged with notable tag.",
441 "AbstractAbstractFileNode.createSheet.noScore.description=No score"})
445 String description = Bundle.AbstractAbstractFileNode_createSheet_noScore_description();
446 if (content.getKnown() == TskData.FileKnown.BAD) {
448 description = Bundle.AbstractAbstractFileNode_createSheet_notableFile_description();
453 description = Bundle.AbstractAbstractFileNode_createSheet_interestingResult_description();
455 }
catch (TskCoreException ex) {
456 logger.log(Level.WARNING,
"Error getting artifacts for file: " + content.getName(), ex);
460 description = Bundle.AbstractAbstractFileNode_createSheet_taggedFile_description();
461 for (Tag tag : tags) {
462 if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
464 description = Bundle.AbstractAbstractFileNode_createSheet_notableTaggedFile_description();
469 return Pair.of(score, description);
473 "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
479 for (Tag tag : tags) {
480 if (!StringUtils.isBlank(tag.getComment())) {
486 if (attribute != null && !StringUtils.isBlank(attribute.
getComment())) {
502 String getTranslatedFileName() {
505 }
catch (NoServiceProviderException | TranslationException ex) {
506 logger.log(Level.WARNING, MessageFormat.format(
"Error translating file name (objID={0}))", content.getId()), ex);
516 List<ContentTag> getContentTagsFromDatabase() {
517 List<ContentTag> tags =
new ArrayList<>();
519 tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(content));
520 }
catch (TskCoreException | NoCurrentCaseException ex) {
521 logger.log(Level.SEVERE,
"Failed to get tags for content " + content.getName(), ex);
528 return new ArrayList<>(getContentTagsFromDatabase());
540 static String getContentPath(AbstractFile file) {
542 return file.getUniquePath();
543 }
catch (TskCoreException ex) {
544 logger.log(Level.SEVERE,
"Except while calling Content.getUniquePath() on " + file.getName(), ex);
549 static String getContentDisplayName(AbstractFile file) {
550 String name = file.getName();
553 return DirectoryNode.DOTDOTDIR;
555 return DirectoryNode.DOTDIR;
572 map.put(NAME.toString(), getContentDisplayName(content));
573 map.put(LOCATION.toString(), getContentPath(content));
578 map.put(SIZE.toString(), content.getSize());
579 map.put(FLAGS_DIR.toString(), content.getDirFlagAsString());
580 map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());
581 map.put(KNOWN.toString(), content.getKnown().getName());
582 map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
583 map.put(SHA256HASH.toString(), StringUtils.defaultString(content.getSha256Hash()));
584 map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
585 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