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.util.ArrayList;
25 import java.util.EnumSet;
26 import java.util.List;
29 import java.util.logging.Level;
30 import java.util.stream.Collectors;
31 import org.apache.commons.io.FilenameUtils;
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;
88 String ext = abstractFile.getNameExtension();
89 if (StringUtils.isNotBlank(ext)) {
99 backgroundTasksPool.submit(
new TranslationTask(
100 new WeakReference<>(
this),
weakPcl));
128 private final PropertyChangeListener
pcl = (PropertyChangeEvent evt) -> {
129 String eventType = evt.getPropertyName();
137 if ((moduleContentEvent.getSource() instanceof Content) ==
false) {
140 Content newContent = (Content) moduleContentEvent.getSource();
143 if (
getContent().getId() == newContent.getId()) {
151 }
catch (NullPointerException ex) {
154 logger.log(Level.WARNING,
"Failed to post key refresh event", ex);
158 if (evt.getNewValue() == null) {
170 if (event.getAddedTag().getContent().equals(content)) {
173 Score value = scorePropAndDescr.getLeft();
174 String descr = scorePropAndDescr.getRight();
182 if (event.getDeletedTagInfo().getContentID() == content.getId()) {
185 Score value = scorePropAndDescr.getLeft();
186 String descr = scorePropAndDescr.getRight();
194 if (event.getContentID() == content.getId()) {
199 }
else if (eventType.equals(NodeSpecificEvents.TRANSLATION_AVAILABLE.toString())) {
200 this.setDisplayName(evt.getNewValue().toString());
202 this.setShortDescription(content.getName());
205 SCOData scoData = (SCOData) evt.getNewValue();
206 if (scoData.getScoreAndDescription() != null) {
207 updateSheet(
new NodeProperty<>(SCORE.toString(), SCORE.toString(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft()));
209 if (scoData.getComment() != null) {
212 if (scoData.getCountAndDescription() != null) {
213 updateSheet(
new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
225 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(pcl, null);
235 Sheet sheet =
new Sheet();
236 Sheet.Set sheetSet = Sheet.createPropertiesSet();
241 newProperties.forEach((property) -> {
242 sheetSet.put(property);
248 @NbBundle.Messages({
"AbstractAbstractFileNode.nameColLbl=Name",
249 "AbstractAbstractFileNode.originalName=Original Name",
250 "AbstractAbstractFileNode.createSheet.score.name=S",
251 "AbstractAbstractFileNode.createSheet.comment.name=C",
252 "AbstractAbstractFileNode.createSheet.count.name=O",
253 "AbstractAbstractFileNode.locationColLbl=Location",
254 "AbstractAbstractFileNode.modifiedTimeColLbl=Modified Time",
255 "AbstractAbstractFileNode.changeTimeColLbl=Change Time",
256 "AbstractAbstractFileNode.accessTimeColLbl=Access Time",
257 "AbstractAbstractFileNode.createdTimeColLbl=Created Time",
258 "AbstractAbstractFileNode.sizeColLbl=Size",
259 "AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir)",
260 "AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta)",
261 "AbstractAbstractFileNode.modeColLbl=Mode",
262 "AbstractAbstractFileNode.useridColLbl=UserID",
263 "AbstractAbstractFileNode.groupidColLbl=GroupID",
264 "AbstractAbstractFileNode.metaAddrColLbl=Meta Addr.",
265 "AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr.",
266 "AbstractAbstractFileNode.typeDirColLbl=Type(Dir)",
267 "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)",
268 "AbstractAbstractFileNode.knownColLbl=Known",
269 "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash",
270 "AbstractAbstractFileNode.objectId=Object ID",
271 "AbstractAbstractFileNode.mimeType=MIME Type",
272 "AbstractAbstractFileNode.extensionColLbl=Extension"})
275 NAME(AbstractAbstractFileNode_nameColLbl()),
277 SCORE(AbstractAbstractFileNode_createSheet_score_name()),
278 COMMENT(AbstractAbstractFileNode_createSheet_comment_name()),
280 LOCATION(AbstractAbstractFileNode_locationColLbl()),
281 MOD_TIME(AbstractAbstractFileNode_modifiedTimeColLbl()),
285 SIZE(AbstractAbstractFileNode_sizeColLbl()),
288 MODE(AbstractAbstractFileNode_modeColLbl()),
289 USER_ID(AbstractAbstractFileNode_useridColLbl()),
290 GROUP_ID(AbstractAbstractFileNode_groupidColLbl()),
293 TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
295 KNOWN(AbstractAbstractFileNode_knownColLbl()),
296 MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
304 this.displayString = displayString;
309 return displayString;
317 List<NodeProperty<?>> properties =
new ArrayList<>();
318 properties.add(
new NodeProperty<>(NAME.toString(), NAME.toString(),
NO_DESCR, getContentDisplayName(content)));
336 backgroundTasksPool.submit(
new GetSCOTask(
337 new WeakReference<>(
this), weakPcl));
345 properties.add(
new NodeProperty<>(FLAGS_DIR.toString(), FLAGS_DIR.toString(),
NO_DESCR, content.getDirFlagAsString()));
346 properties.add(
new NodeProperty<>(FLAGS_META.toString(), FLAGS_META.toString(),
NO_DESCR, content.getMetaFlagsAsString()));
347 properties.add(
new NodeProperty<>(KNOWN.toString(), KNOWN.toString(),
NO_DESCR, content.getKnown().getName()));
348 properties.add(
new NodeProperty<>(LOCATION.toString(), LOCATION.toString(),
NO_DESCR, getContentPath(content)));
349 properties.add(
new NodeProperty<>(MD5HASH.toString(), MD5HASH.toString(),
NO_DESCR, StringUtils.defaultString(content.getMd5Hash())));
350 properties.add(
new NodeProperty<>(MIMETYPE.toString(), MIMETYPE.toString(),
NO_DESCR, StringUtils.defaultString(content.getMIMEType())));
351 properties.add(
new NodeProperty<>(EXTENSION.toString(), EXTENSION.toString(),
NO_DESCR, content.getNameExtension()));
365 @NbBundle.Messages(
"AbstractAbstractFileNode.tagsProperty.displayName=Tags")
368 List<ContentTag> tags = getContentTagsFromDatabase();
369 sheetSet.put(
new NodeProperty<>(
"Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
370 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
372 .collect(Collectors.joining(
", "))));
388 return StringUtils.join(file.getHashSetNames(),
", ");
389 }
catch (TskCoreException tskCoreException) {
390 logger.log(Level.WARNING,
"Error getting hashset hits: ", tskCoreException);
396 "AbstractAbstractFileNode.createSheet.count.displayName=O",
397 "AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated",
398 "# {0} - occurrenceCount",
399 "AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the MD5 correlation value"})
402 String defaultDescription) {
404 String description = defaultDescription;
407 if (attributeType != null && StringUtils.isNotBlank(attributeValue)) {
409 description = Bundle.AbstractAbstractFileNode_createSheet_count_description(count);
410 }
else if (attributeType != null) {
411 description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
414 logger.log(Level.WARNING,
"Error getting count of datasources with correlation attribute", ex);
416 logger.log(Level.WARNING,
"Unable to normalize data to get count of datasources with correlation attribute", ex);
418 return Pair.of(count, description);
422 "AbstractAbstractFileNode.createSheet.score.displayName=S",
423 "AbstractAbstractFileNode.createSheet.notableFile.description=File recognized as notable.",
424 "AbstractAbstractFileNode.createSheet.interestingResult.description=File has interesting result associated with it.",
425 "AbstractAbstractFileNode.createSheet.taggedFile.description=File has been tagged.",
426 "AbstractAbstractFileNode.createSheet.notableTaggedFile.description=File tagged with notable tag.",
427 "AbstractAbstractFileNode.createSheet.noScore.description=No score"})
431 String description = Bundle.AbstractAbstractFileNode_createSheet_noScore_description();
432 if (content.getKnown() == TskData.FileKnown.BAD) {
434 description = Bundle.AbstractAbstractFileNode_createSheet_notableFile_description();
439 description = Bundle.AbstractAbstractFileNode_createSheet_interestingResult_description();
441 }
catch (TskCoreException ex) {
442 logger.log(Level.WARNING,
"Error getting artifacts for file: " + content.getName(), ex);
446 description = Bundle.AbstractAbstractFileNode_createSheet_taggedFile_description();
447 for (Tag tag : tags) {
448 if (tag.getName().getKnownStatus() == TskData.FileKnown.BAD) {
450 description = Bundle.AbstractAbstractFileNode_createSheet_notableTaggedFile_description();
455 return Pair.of(score, description);
459 "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
465 for (Tag tag : tags) {
466 if (!StringUtils.isBlank(tag.getComment())) {
472 if (attribute != null && !StringUtils.isBlank(attribute.
getComment())) {
486 String getTranslatedFileName() {
488 if (content.getName().matches(
"^\\p{ASCII}+$")) {
491 TextTranslationService tts = TextTranslationService.getInstance();
492 if (tts.hasProvider()) {
494 String base = FilenameUtils.getBaseName(content.getName());
496 String translation = tts.translate(base);
497 String ext = FilenameUtils.getExtension(content.getName());
500 String extensionDelimiter = (ext.isEmpty()) ?
"" :
".";
504 if (!translation.isEmpty()) {
505 return translation + extensionDelimiter + ext;
507 }
catch (NoServiceProviderException noServiceEx) {
508 logger.log(Level.WARNING,
"Translate unsuccessful because no TextTranslator "
509 +
"implementation was provided.", noServiceEx.getMessage());
510 }
catch (TranslationException noTranslationEx) {
511 logger.log(Level.WARNING,
"Could not successfully translate file name "
512 + content.getName(), noTranslationEx.getMessage());
523 List<ContentTag> getContentTagsFromDatabase() {
524 List<ContentTag> tags =
new ArrayList<>();
526 tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(content));
527 }
catch (TskCoreException | NoCurrentCaseException ex) {
528 logger.log(Level.SEVERE,
"Failed to get tags for content " + content.getName(), ex);
535 return new ArrayList<>(getContentTagsFromDatabase());
547 static String getContentPath(AbstractFile file) {
549 return file.getUniquePath();
550 }
catch (TskCoreException ex) {
551 logger.log(Level.SEVERE,
"Except while calling Content.getUniquePath() on " + file.getName(), ex);
556 static String getContentDisplayName(AbstractFile file) {
557 String name = file.getName();
560 return DirectoryNode.DOTDOTDIR;
562 return DirectoryNode.DOTDIR;
579 map.put(NAME.toString(), getContentDisplayName(content));
580 map.put(LOCATION.toString(), getContentPath(content));
585 map.put(SIZE.toString(), content.getSize());
586 map.put(FLAGS_DIR.toString(), content.getDirFlagAsString());
587 map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());
588 map.put(KNOWN.toString(), content.getKnown().getName());
589 map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
590 map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
591 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)
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
static EamDb getInstance()
static boolean displayTranslatedFileNames()
static CorrelationAttributeInstance getInstanceFromContent(Content content)
Pair< Long, String > getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription)
static boolean getHideSCOColumns()
static boolean isEnabled()
AbstractFilePropertyType(String displayString)
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 String getHashSetHitsCsvList(AbstractFile file)
void addTagProperty(Sheet.Set sheetSet)
final PropertyChangeListener weakPcl
static final String NO_DESCR