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;
88 String ext = abstractFile.getNameExtension();
89 if (StringUtils.isNotBlank(ext)) {
102 }
catch (TskCoreException ex) {
103 logger.log(Level.SEVERE, String.format(
"Failed attempt to cache the "
104 +
"unique path of the abstract file instance. Name: %s (objID=%d)",
105 this.content.getName(), this.
content.getId()), ex);
109 backgroundTasksPool.submit(
new TranslationTask(
110 new WeakReference<>(
this),
weakPcl));
138 private final PropertyChangeListener
pcl = (PropertyChangeEvent evt) -> {
139 String eventType = evt.getPropertyName();
147 if ((moduleContentEvent.getSource() instanceof Content) ==
false) {
150 Content newContent = (Content) moduleContentEvent.getSource();
153 if (
getContent().getId() == newContent.getId()) {
161 }
catch (NullPointerException ex) {
164 logger.log(Level.WARNING,
"Failed to post key refresh event", ex);
168 if (evt.getNewValue() == null) {
180 if (event.getAddedTag().getContent().equals(
content)) {
183 Score value = scorePropAndDescr.getLeft();
184 String descr = scorePropAndDescr.getRight();
185 List<CorrelationAttributeInstance> listWithJustFileAttr =
new ArrayList<>();
187 if (corrInstance != null) {
188 listWithJustFileAttr.add(corrInstance);
196 if (event.getDeletedTagInfo().getContentID() ==
content.getId()) {
199 Score value = scorePropAndDescr.getLeft();
200 String descr = scorePropAndDescr.getRight();
201 List<CorrelationAttributeInstance> listWithJustFileAttr =
new ArrayList<>();
203 if (corrInstance != null) {
204 listWithJustFileAttr.add(corrInstance);
212 if (event.getContentID() ==
content.getId()) {
214 List<CorrelationAttributeInstance> listWithJustFileAttr =
new ArrayList<>();
216 if (corrInstance != null) {
217 listWithJustFileAttr.add(corrInstance);
221 }
else if (eventType.equals(NodeSpecificEvents.TRANSLATION_AVAILABLE.toString())) {
222 this.setDisplayName(evt.getNewValue().toString());
224 this.setShortDescription(
content.getName());
227 SCOData scoData = (SCOData) evt.getNewValue();
228 if (scoData.getScoreAndDescription() != null) {
229 updateSheet(
new NodeProperty<>(SCORE.toString(), SCORE.toString(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft()));
231 if (scoData.getComment() != null) {
234 if (scoData.getCountAndDescription() != null) {
235 updateSheet(
new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
247 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(pcl, null);
257 Sheet sheet =
new Sheet();
258 Sheet.Set sheetSet = Sheet.createPropertiesSet();
263 newProperties.forEach((property) -> {
264 sheetSet.put(property);
270 @NbBundle.Messages({
"AbstractAbstractFileNode.nameColLbl=Name",
271 "AbstractAbstractFileNode.originalName=Original Name",
272 "AbstractAbstractFileNode.createSheet.score.name=S",
273 "AbstractAbstractFileNode.createSheet.comment.name=C",
274 "AbstractAbstractFileNode.createSheet.count.name=O",
275 "AbstractAbstractFileNode.locationColLbl=Location",
276 "AbstractAbstractFileNode.modifiedTimeColLbl=Modified Time",
277 "AbstractAbstractFileNode.changeTimeColLbl=Change Time",
278 "AbstractAbstractFileNode.accessTimeColLbl=Access Time",
279 "AbstractAbstractFileNode.createdTimeColLbl=Created Time",
280 "AbstractAbstractFileNode.sizeColLbl=Size",
281 "AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir)",
282 "AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta)",
283 "AbstractAbstractFileNode.modeColLbl=Mode",
284 "AbstractAbstractFileNode.useridColLbl=UserID",
285 "AbstractAbstractFileNode.groupidColLbl=GroupID",
286 "AbstractAbstractFileNode.metaAddrColLbl=Meta Addr.",
287 "AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr.",
288 "AbstractAbstractFileNode.typeDirColLbl=Type(Dir)",
289 "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)",
290 "AbstractAbstractFileNode.knownColLbl=Known",
291 "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash",
292 "AbstractAbstractFileNode.sha256HashColLbl=SHA-256 Hash",
293 "AbstractAbstractFileNode.objectId=Object ID",
294 "AbstractAbstractFileNode.mimeType=MIME Type",
295 "AbstractAbstractFileNode.extensionColLbl=Extension"})
298 NAME(AbstractAbstractFileNode_nameColLbl()),
300 SCORE(AbstractAbstractFileNode_createSheet_score_name()),
301 COMMENT(AbstractAbstractFileNode_createSheet_comment_name()),
303 LOCATION(AbstractAbstractFileNode_locationColLbl()),
304 MOD_TIME(AbstractAbstractFileNode_modifiedTimeColLbl()),
308 SIZE(AbstractAbstractFileNode_sizeColLbl()),
311 MODE(AbstractAbstractFileNode_modeColLbl()),
312 USER_ID(AbstractAbstractFileNode_useridColLbl()),
313 GROUP_ID(AbstractAbstractFileNode_groupidColLbl()),
316 TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
318 KNOWN(AbstractAbstractFileNode_knownColLbl()),
319 MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
328 this.displayString = displayString;
333 return displayString;
341 List<NodeProperty<?>> properties =
new ArrayList<>();
360 backgroundTasksPool.submit(
new GetSCOTask(
361 new WeakReference<>(
this), weakPcl));
374 properties.add(
new NodeProperty<>(SHA256HASH.toString(), SHA256HASH.toString(),
NO_DESCR, StringUtils.defaultString(
content.getSha256Hash())));
390 @NbBundle.Messages(
"AbstractAbstractFileNode.tagsProperty.displayName=Tags")
393 List<ContentTag> tags = getContentTagsFromDatabase();
394 sheetSet.put(
new NodeProperty<>(
"Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
395 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
397 .collect(Collectors.joining(
", "))));
413 return StringUtils.join(file.getHashSetNames(),
", ");
414 }
catch (TskCoreException tskCoreException) {
415 logger.log(Level.WARNING,
"Error getting hashset hits: ", tskCoreException);
421 "AbstractAbstractFileNode.createSheet.count.displayName=O",
422 "AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated",
423 "# {0} - occurrenceCount",
424 "AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the MD5 correlation value"})
428 String description = defaultDescription;
431 if (attributeInstance != null && StringUtils.isNotBlank(attributeInstance.
getCorrelationValue())) {
433 description = Bundle.AbstractAbstractFileNode_createSheet_count_description(count);
434 }
else if (attributeInstance != null) {
435 description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
438 logger.log(Level.WARNING,
"Error getting count of datasources with correlation attribute", ex);
440 logger.log(Level.WARNING,
"Unable to normalize data to get count of datasources with correlation attribute", ex);
442 return Pair.of(count, description);
446 "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
452 for (Tag tag : tags) {
453 if (!StringUtils.isBlank(tag.getComment())) {
459 if (attributes != null && !attributes.isEmpty()) {
461 if (attribute != null && !StringUtils.isBlank(attribute.getComment())) {
480 String getTranslatedFileName() {
483 }
catch (NoServiceProviderException | TranslationException ex) {
484 logger.log(Level.WARNING, MessageFormat.format(
"Error translating file name (objID={0}))",
content.getId()), ex);
494 List<ContentTag> getContentTagsFromDatabase() {
495 List<ContentTag> tags =
new ArrayList<>();
497 tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(
content));
498 }
catch (TskCoreException | NoCurrentCaseException ex) {
499 logger.log(Level.SEVERE,
"Failed to get tags for content " +
content.getName(), ex);
506 return new ArrayList<>(getContentTagsFromDatabase());
509 static String getContentPath(AbstractFile file) {
511 return file.getUniquePath();
512 }
catch (TskCoreException ex) {
513 logger.log(Level.SEVERE,
"Except while calling Content.getUniquePath() on " + file.getName(), ex);
518 static String getContentDisplayName(AbstractFile file) {
519 String name = file.getName();
522 return DirectoryNode.DOTDOTDIR;
524 return DirectoryNode.DOTDIR;
541 map.put(NAME.toString(), getContentDisplayName(content));
542 map.put(LOCATION.toString(), getContentPath(content));
547 map.put(SIZE.toString(), content.getSize());
548 map.put(FLAGS_DIR.toString(), content.getDirFlagAsString());
549 map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());
550 map.put(KNOWN.toString(), content.getKnown().getName());
551 map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
552 map.put(SHA256HASH.toString(), StringUtils.defaultString(content.getSha256Hash()));
553 map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
554 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 CorrelationAttributeInstance getCorrAttrForFile(AbstractFile file)
static boolean getHideSCOColumns()
Pair< Score, String > getScorePropertyAndDescription(List< Tag > tags)
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