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();
192 if (event.getDeletedTagInfo().getContentID() ==
content.getId()) {
195 Score value = scorePropAndDescr.getLeft();
196 String descr = scorePropAndDescr.getRight();
204 if (event.getContentID() ==
content.getId()) {
209 }
else if (eventType.equals(NodeSpecificEvents.TRANSLATION_AVAILABLE.toString())) {
210 this.setDisplayName(evt.getNewValue().toString());
212 this.setShortDescription(
content.getName());
215 SCOData scoData = (SCOData) evt.getNewValue();
216 if (scoData.getScoreAndDescription() != null) {
217 updateSheet(
new NodeProperty<>(SCORE.toString(), SCORE.toString(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft()));
219 if (scoData.getComment() != null) {
222 if (scoData.getCountAndDescription() != null) {
223 updateSheet(
new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
235 private final PropertyChangeListener
weakPcl = WeakListeners.propertyChange(pcl, null);
245 Sheet sheet =
new Sheet();
246 Sheet.Set sheetSet = Sheet.createPropertiesSet();
251 newProperties.forEach((property) -> {
252 sheetSet.put(property);
258 @NbBundle.Messages({
"AbstractAbstractFileNode.nameColLbl=Name",
259 "AbstractAbstractFileNode.originalName=Original Name",
260 "AbstractAbstractFileNode.createSheet.score.name=S",
261 "AbstractAbstractFileNode.createSheet.comment.name=C",
262 "AbstractAbstractFileNode.createSheet.count.name=O",
263 "AbstractAbstractFileNode.locationColLbl=Location",
264 "AbstractAbstractFileNode.modifiedTimeColLbl=Modified Time",
265 "AbstractAbstractFileNode.changeTimeColLbl=Change Time",
266 "AbstractAbstractFileNode.accessTimeColLbl=Access Time",
267 "AbstractAbstractFileNode.createdTimeColLbl=Created Time",
268 "AbstractAbstractFileNode.sizeColLbl=Size",
269 "AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir)",
270 "AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta)",
271 "AbstractAbstractFileNode.modeColLbl=Mode",
272 "AbstractAbstractFileNode.useridColLbl=UserID",
273 "AbstractAbstractFileNode.groupidColLbl=GroupID",
274 "AbstractAbstractFileNode.metaAddrColLbl=Meta Addr.",
275 "AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr.",
276 "AbstractAbstractFileNode.typeDirColLbl=Type(Dir)",
277 "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)",
278 "AbstractAbstractFileNode.knownColLbl=Known",
279 "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash",
280 "AbstractAbstractFileNode.sha256HashColLbl=SHA-256 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()),
316 this.displayString = displayString;
321 return displayString;
329 List<NodeProperty<?>> properties =
new ArrayList<>();
348 backgroundTasksPool.submit(
new GetSCOTask(
349 new WeakReference<>(
this), weakPcl));
362 properties.add(
new NodeProperty<>(SHA256HASH.toString(), SHA256HASH.toString(),
NO_DESCR, StringUtils.defaultString(
content.getSha256Hash())));
378 @NbBundle.Messages(
"AbstractAbstractFileNode.tagsProperty.displayName=Tags")
381 List<ContentTag> tags = getContentTagsFromDatabase();
382 sheetSet.put(
new NodeProperty<>(
"Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
383 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
385 .collect(Collectors.joining(
", "))));
401 return StringUtils.join(file.getHashSetNames(),
", ");
402 }
catch (TskCoreException tskCoreException) {
403 logger.log(Level.WARNING,
"Error getting hashset hits: ", tskCoreException);
409 "AbstractAbstractFileNode.createSheet.count.displayName=O",
410 "AbstractAbstractFileNode.createSheet.count.hashLookupNotRun.description=Hash lookup had not been run on this file when the column was populated",
411 "# {0} - occurrenceCount",
412 "AbstractAbstractFileNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the MD5 correlation value"})
415 String defaultDescription) {
417 String description = defaultDescription;
420 if (attributeType != null && StringUtils.isNotBlank(attributeValue)) {
422 description = Bundle.AbstractAbstractFileNode_createSheet_count_description(count);
423 }
else if (attributeType != null) {
424 description = Bundle.AbstractAbstractFileNode_createSheet_count_hashLookupNotRun_description();
427 logger.log(Level.WARNING,
"Error getting count of datasources with correlation attribute", ex);
429 logger.log(Level.WARNING,
"Unable to normalize data to get count of datasources with correlation attribute", ex);
431 return Pair.of(count, description);
435 "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
441 for (Tag tag : tags) {
442 if (!StringUtils.isBlank(tag.getComment())) {
448 if (attribute != null && !StringUtils.isBlank(attribute.
getComment())) {
464 String getTranslatedFileName() {
467 }
catch (NoServiceProviderException | TranslationException ex) {
468 logger.log(Level.WARNING, MessageFormat.format(
"Error translating file name (objID={0}))",
content.getId()), ex);
478 List<ContentTag> getContentTagsFromDatabase() {
479 List<ContentTag> tags =
new ArrayList<>();
481 tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(
content));
482 }
catch (TskCoreException | NoCurrentCaseException ex) {
483 logger.log(Level.SEVERE,
"Failed to get tags for content " +
content.getName(), ex);
490 return new ArrayList<>(getContentTagsFromDatabase());
502 static String getContentPath(AbstractFile file) {
504 return file.getUniquePath();
505 }
catch (TskCoreException ex) {
506 logger.log(Level.SEVERE,
"Except while calling Content.getUniquePath() on " + file.getName(), ex);
511 static String getContentDisplayName(AbstractFile file) {
512 String name = file.getName();
515 return DirectoryNode.DOTDOTDIR;
517 return DirectoryNode.DOTDIR;
534 map.put(NAME.toString(), getContentDisplayName(content));
535 map.put(LOCATION.toString(), getContentPath(content));
540 map.put(SIZE.toString(), content.getSize());
541 map.put(FLAGS_DIR.toString(), content.getDirFlagAsString());
542 map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());
543 map.put(KNOWN.toString(), content.getKnown().getName());
544 map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
545 map.put(SHA256HASH.toString(), StringUtils.defaultString(content.getSha256Hash()));
546 map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
547 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()
CorrelationAttributeInstance getCorrelationAttributeInstance()
synchronized Sheet createSheet()
static String getFormattedTime(long epochTime)
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
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()
Pair< Score, String > getScorePropertyAndDescription(List< Tag > tags)
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