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;
90 String ext = abstractFile.getNameExtension();
91 if (StringUtils.isNotBlank(ext)) {
101 if (VirtualDirectory.NAME_CARVED.equals(abstractFile.getName())) {
109 }
catch (TskCoreException ex) {
110 logger.log(Level.SEVERE, String.format(
"Failed attempt to cache the "
111 +
"unique path of the abstract file instance. Name: %s (objID=%d)",
112 this.content.getName(), this.
content.getId()), ex);
116 backgroundTasksPool.submit(
new TranslationTask(
117 new WeakReference<>(
this),
weakPcl));
145 private final PropertyChangeListener
pcl = (PropertyChangeEvent evt) -> {
146 String eventType = evt.getPropertyName();
154 if ((moduleContentEvent.getSource() instanceof Content) ==
false) {
157 Content newContent = (Content) moduleContentEvent.getSource();
160 if (
getContent().getId() == newContent.getId()) {
174 }
catch (NullPointerException ex) {
177 logger.log(Level.WARNING,
"Failed to post key refresh event", ex);
181 if (evt.getNewValue() == null) {
193 if (event.getAddedTag().getContent().equals(
content)) {
196 Score value = scorePropAndDescr.getLeft();
197 String descr = scorePropAndDescr.getRight();
198 List<CorrelationAttributeInstance> listWithJustFileAttr =
new ArrayList<>();
200 if (corrInstance != null) {
201 listWithJustFileAttr.add(corrInstance);
209 if (event.getDeletedTagInfo().getContentID() ==
content.getId()) {
212 Score value = scorePropAndDescr.getLeft();
213 String descr = scorePropAndDescr.getRight();
214 List<CorrelationAttributeInstance> listWithJustFileAttr =
new ArrayList<>();
216 if (corrInstance != null) {
217 listWithJustFileAttr.add(corrInstance);
225 if (event.getContentID() ==
content.getId()) {
226 List<CorrelationAttributeInstance> listWithJustFileAttr =
new ArrayList<>();
228 if (corrInstance != null) {
229 listWithJustFileAttr.add(corrInstance);
233 }
else if (eventType.equals(NodeSpecificEvents.TRANSLATION_AVAILABLE.toString())) {
234 this.setDisplayName(evt.getNewValue().toString());
236 this.setShortDescription(
content.getName());
239 SCOData scoData = (SCOData) evt.getNewValue();
240 if (scoData.getScoreAndDescription() != null) {
241 updateSheet(
new NodeProperty<>(SCORE.toString(), SCORE.toString(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft()));
243 if (scoData.getComment() != null) {
246 if (scoData.getCountAndDescription() != null) {
247 updateSheet(
new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
259 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(pcl, null);
269 Sheet sheet =
new Sheet();
270 Sheet.Set sheetSet = Sheet.createPropertiesSet();
275 newProperties.forEach((property) -> {
276 sheetSet.put(property);
282 @NbBundle.Messages({
"AbstractAbstractFileNode.nameColLbl=Name",
283 "AbstractAbstractFileNode.originalName=Original Name",
284 "AbstractAbstractFileNode.createSheet.score.name=S",
285 "AbstractAbstractFileNode.createSheet.comment.name=C",
286 "AbstractAbstractFileNode.createSheet.count.name=O",
287 "AbstractAbstractFileNode.locationColLbl=Location",
288 "AbstractAbstractFileNode.modifiedTimeColLbl=Modified Time",
289 "AbstractAbstractFileNode.changeTimeColLbl=Change Time",
290 "AbstractAbstractFileNode.accessTimeColLbl=Access Time",
291 "AbstractAbstractFileNode.createdTimeColLbl=Created Time",
292 "AbstractAbstractFileNode.sizeColLbl=Size",
293 "AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir)",
294 "AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta)",
295 "AbstractAbstractFileNode.modeColLbl=Mode",
296 "AbstractAbstractFileNode.useridColLbl=UserID",
297 "AbstractAbstractFileNode.groupidColLbl=GroupID",
298 "AbstractAbstractFileNode.metaAddrColLbl=Meta Addr.",
299 "AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr.",
300 "AbstractAbstractFileNode.typeDirColLbl=Type(Dir)",
301 "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)",
302 "AbstractAbstractFileNode.knownColLbl=Known",
303 "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash",
304 "AbstractAbstractFileNode.sha256HashColLbl=SHA-256 Hash",
305 "AbstractAbstractFileNode.objectId=Object ID",
306 "AbstractAbstractFileNode.mimeType=MIME Type",
307 "AbstractAbstractFileNode.extensionColLbl=Extension"})
310 NAME(AbstractAbstractFileNode_nameColLbl()),
312 SCORE(AbstractAbstractFileNode_createSheet_score_name()),
313 COMMENT(AbstractAbstractFileNode_createSheet_comment_name()),
315 LOCATION(AbstractAbstractFileNode_locationColLbl()),
316 MOD_TIME(AbstractAbstractFileNode_modifiedTimeColLbl()),
320 SIZE(AbstractAbstractFileNode_sizeColLbl()),
323 MODE(AbstractAbstractFileNode_modeColLbl()),
324 USER_ID(AbstractAbstractFileNode_useridColLbl()),
325 GROUP_ID(AbstractAbstractFileNode_groupidColLbl()),
328 TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
330 KNOWN(AbstractAbstractFileNode_knownColLbl()),
331 MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
340 this.displayString = displayString;
345 return displayString;
353 List<NodeProperty<?>> properties =
new ArrayList<>();
372 backgroundTasksPool.submit(
new GetSCOTask(
373 new WeakReference<>(
this), weakPcl));
386 properties.add(
new NodeProperty<>(SHA256HASH.toString(), SHA256HASH.toString(),
NO_DESCR, StringUtils.defaultString(
content.getSha256Hash())));
402 @NbBundle.Messages(
"AbstractAbstractFileNode.tagsProperty.displayName=Tags")
405 List<ContentTag> tags = getContentTagsFromDatabase();
406 sheetSet.put(
new NodeProperty<>(
"Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
407 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
409 .collect(Collectors.joining(
", "))));
425 return StringUtils.join(file.getHashSetNames(),
", ");
426 }
catch (TskCoreException tskCoreException) {
427 logger.log(Level.WARNING,
"Error getting hashset hits: ", tskCoreException);
433 "AbstractAbstractFileNode.createSheet.count.displayName=O",
434 "AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated",
435 "# {0} - occurrenceCount",
436 "AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the MD5 correlation value"})
440 String description = defaultDescription;
443 if (attributeInstance != null && StringUtils.isNotBlank(attributeInstance.
getCorrelationValue())) {
445 description = Bundle.AbstractAbstractFileNode_createSheet_count_description(count);
446 }
else if (attributeInstance != null) {
447 description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
450 logger.log(Level.SEVERE,
"Error getting count of datasources with correlation attribute", ex);
452 logger.log(Level.WARNING,
"Unable to normalize data to get count of datasources with correlation attribute", ex);
454 return Pair.of(count, description);
458 "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
462 for (Tag tag : tags) {
463 if (!StringUtils.isBlank(tag.getComment())) {
482 logger.log(Level.SEVERE,
"Attempted to Query CR for presence of comments in a file node and was unable to perform query, comment column will only reflect caseDB", ex);
493 String getTranslatedFileName() {
496 }
catch (NoServiceProviderException | TranslationException ex) {
497 logger.log(Level.WARNING, MessageFormat.format(
"Error translating file name (objID={0}))",
content.getId()), ex);
507 List<ContentTag> getContentTagsFromDatabase() {
508 List<ContentTag> tags =
new ArrayList<>();
510 tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(
content));
511 }
catch (TskCoreException | NoCurrentCaseException ex) {
512 logger.log(Level.SEVERE,
"Failed to get tags for content " +
content.getName(), ex);
519 return new ArrayList<>(getContentTagsFromDatabase());
522 static String getContentPath(AbstractFile file) {
524 return file.getUniquePath();
525 }
catch (TskCoreException ex) {
526 logger.log(Level.SEVERE,
"Except while calling Content.getUniquePath() on " + file.getName(), ex);
531 static String getContentDisplayName(AbstractFile file) {
532 String name = file.getName();
535 return DirectoryNode.DOTDOTDIR;
537 return DirectoryNode.DOTDIR;
554 map.put(NAME.toString(), getContentDisplayName(content));
555 map.put(LOCATION.toString(), getContentPath(content));
560 map.put(SIZE.toString(), content.getSize());
561 map.put(FLAGS_DIR.toString(), content.getDirFlagAsString());
562 map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());
563 map.put(KNOWN.toString(), content.getKnown().getName());
564 map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
565 map.put(SHA256HASH.toString(), StringUtils.defaultString(content.getSha256Hash()));
566 map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
567 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 List< String > getArchiveExtensions()
final String displayString
static synchronized IngestManager getInstance()
synchronized Sheet createSheet()
static String getFormattedTime(long epochTime)
HasCommentStatus getCommentProperty(List< Tag > tags, List< CorrelationAttributeInstance > attributes)
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
List< Tag > getAllTagsFromDatabase()
String getCorrelationValue()
static void fillPropertyMap(Map< String, Object > map, AbstractFile content)
static String translate(String fileName)
Pair< Long, String > getCountPropertyAndDescription(CorrelationAttributeInstance attributeInstance, String defaultDescription)
static final Set< Case.Events > CASE_EVENTS_OF_INTEREST
static TextTranslationService getInstance()
static boolean displayTranslatedFileNames()
static boolean commentExistsOnAttributes(List< CorrelationAttributeInstance > attributes)
static CorrelationAttributeInstance getCorrAttrForFile(AbstractFile file)
static boolean getHideSCOColumns()
Pair< Score, String > getScorePropertyAndDescription()
AbstractFilePropertyType(String displayString)
synchronized boolean hasProvider()
static void post(String nodeName, Object event)
Long getCountCasesWithOtherInstances(CorrelationAttributeInstance instance)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
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()
static String getHashSetHitsCsvList(AbstractFile file)
void addTagProperty(Sheet.Set sheetSet)
static boolean isEnabled()
final PropertyChangeListener weakPcl
static final String NO_DESCR