Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
AbstractAbstractFileNode.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2012-2021 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.datamodel;
20
21import java.beans.PropertyChangeEvent;
22import java.beans.PropertyChangeListener;
23import java.lang.ref.WeakReference;
24import java.text.MessageFormat;
25import java.util.ArrayList;
26import java.util.EnumSet;
27import java.util.List;
28import java.util.Map;
29import java.util.Set;
30import java.util.logging.Level;
31import java.util.stream.Collectors;
32import org.apache.commons.lang3.StringUtils;
33import org.apache.commons.lang3.tuple.Pair;
34import org.openide.nodes.Sheet;
35import org.openide.util.NbBundle;
36import org.openide.util.WeakListeners;
37import org.sleuthkit.autopsy.casemodule.Case;
38import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
39import org.sleuthkit.autopsy.casemodule.events.CommentChangedEvent;
40import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
41import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
42import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil;
43import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
44import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeNormalizationException;
45import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeUtil;
46import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
47import org.sleuthkit.autopsy.core.UserPreferences;
48import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
49import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus;
50import org.sleuthkit.autopsy.coreutils.Logger;
51import static org.sleuthkit.autopsy.datamodel.Bundle.*;
52import static org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType.*;
53import org.sleuthkit.autopsy.datamodel.BaseChildFactory.NoSuchEventBusException;
54import org.sleuthkit.autopsy.datamodel.BaseChildFactory.RefreshKeysEvent;
55import org.sleuthkit.autopsy.ingest.IngestManager;
56import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.CONTENT_CHANGED;
57import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
58import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
59import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
60import org.sleuthkit.autopsy.texttranslation.TranslationException;
61import org.sleuthkit.datamodel.AbstractFile;
62import org.sleuthkit.datamodel.Content;
63import org.sleuthkit.datamodel.ContentTag;
64import org.sleuthkit.datamodel.Tag;
65import org.sleuthkit.datamodel.TskCoreException;
66import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
67import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
68import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil;
69import org.sleuthkit.datamodel.Score;
70import org.sleuthkit.datamodel.VirtualDirectory;
71
77public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends AbstractContentNode<T> {
78
79 private static final Logger logger = Logger.getLogger(AbstractAbstractFileNode.class.getName());
80
81 private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
83 private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(CONTENT_CHANGED);
84
88 AbstractAbstractFileNode(T abstractFile) {
89 super(abstractFile);
90 String ext = abstractFile.getNameExtension();
91 if (StringUtils.isNotBlank(ext)) {
92 ext = "." + ext;
93 // If this is an archive file we will listen for ingest events
94 // that will notify us when new content has been identified.
95 if (FileTypeExtensions.getArchiveExtensions().contains(ext)) {
97 }
98 }
99
100 // Add listener if this is the carved files base directory.
101 if (VirtualDirectory.NAME_CARVED.equals(abstractFile.getName())) {
103 }
104
105 try {
106 //See JIRA-5971
107 //Attempt to cache file path during construction of this UI component.
108 this.content.getUniquePath();
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);
113 }
114
116 backgroundTasksPool.submit(new TranslationTask(
117 new WeakReference<>(this), weakPcl));
118 }
119
120 // Listen for case events so that we can detect when the case is closed
121 // or when tags are added.
123 }
124
134 @Override
135 protected void finalize() throws Throwable {
136 super.finalize();
138 }
139
144
145 private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
146 String eventType = evt.getPropertyName();
147
148 // Is this a content changed event?
149 if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
150 if ((evt.getOldValue() instanceof ModuleContentEvent) == false) {
151 return;
152 }
153 ModuleContentEvent moduleContentEvent = (ModuleContentEvent) evt.getOldValue();
154 if ((moduleContentEvent.getSource() instanceof Content) == false) {
155 return;
156 }
157 Content newContent = (Content) moduleContentEvent.getSource();
158
159 // Does the event indicate that content has been added to *this* file?
160 if (getContent().getId() == newContent.getId()) {
161 // If so, refresh our children.
162 try {
163 // We only want to refresh our parents children if we are in the
164 // data sources branch of the tree. The parent nodes in other
165 // branches of the tree (e.g. File Types and Deleted Files) do
166 // not need to be refreshed.
167 if (VirtualDirectory.NAME_CARVED.equals(getContent().getName())) {
168 // If the current node is the carved files directory, we need to refresh it
170 } else {
171 // Otherwise we need to refresh the parent node
172 BaseChildFactory.post(getParentNode().getName(), new RefreshKeysEvent());
173 }
174 } catch (NullPointerException ex) {
175 // Skip
176 } catch (NoSuchEventBusException ex) {
177 logger.log(Level.WARNING, "Failed to post key refresh event", ex); //NON-NLS
178 }
179 }
180 } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
181 if (evt.getNewValue() == null) {
182 // case was closed. Remove listeners so that we don't get called with a stale case handle
184 }
185 /*
186 * No need to do any asynchrony around tag added, deleted or CR
187 * change events, they are so infrequent and user driven that we can
188 * just keep a simple blocking approach, where we go out to the
189 * database ourselves.
190 */
191 } else if (eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())) {
193 if (event.getAddedTag().getContent().equals(content)) {
194
195 Pair<Score, String> scorePropAndDescr = getScorePropertyAndDescription();
196 Score value = scorePropAndDescr.getLeft();
197 String descr = scorePropAndDescr.getRight();
198 List<CorrelationAttributeInstance> listWithJustFileAttr = new ArrayList<>();
200 if (corrInstance != null) {
201 listWithJustFileAttr.add(corrInstance);
202 }
203 updateSheet(new NodeProperty<>(SCORE.toString(), SCORE.toString(), descr, value),
204 new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, getCommentProperty(getAllTagsFromDatabase(), listWithJustFileAttr))
205 );
206 }
207 } else if (eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) {
209 if (event.getDeletedTagInfo().getContentID() == content.getId()) {
210 List<Tag> tags = getAllTagsFromDatabase();
211 Pair<Score, String> scorePropAndDescr = getScorePropertyAndDescription();
212 Score value = scorePropAndDescr.getLeft();
213 String descr = scorePropAndDescr.getRight();
214 List<CorrelationAttributeInstance> listWithJustFileAttr = new ArrayList<>();
216 if (corrInstance != null) {
217 listWithJustFileAttr.add(corrInstance);
218 }
219 updateSheet(new NodeProperty<>(SCORE.toString(), SCORE.toString(), descr, value),
220 new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, getCommentProperty(getAllTagsFromDatabase(), listWithJustFileAttr))
221 );
222 }
223 } else if (eventType.equals(Case.Events.CR_COMMENT_CHANGED.toString())) {
225 if (event.getContentID() == content.getId()) {
226 List<CorrelationAttributeInstance> listWithJustFileAttr = new ArrayList<>();
228 if (corrInstance != null) {
229 listWithJustFileAttr.add(corrInstance);
230 }
231 updateSheet(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, getCommentProperty(getAllTagsFromDatabase(), listWithJustFileAttr)));
232 }
233 } else if (eventType.equals(NodeSpecificEvents.TRANSLATION_AVAILABLE.toString())) {
234 this.setDisplayName(evt.getNewValue().toString());
235 //Set the tooltip
236 this.setShortDescription(content.getName());
237 updateSheet(new NodeProperty<>(ORIGINAL_NAME.toString(), ORIGINAL_NAME.toString(), NO_DESCR, content.getName()));
238 } else if (eventType.equals(NodeSpecificEvents.SCO_AVAILABLE.toString()) && !UserPreferences.getHideSCOColumns()) {
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()));
242 }
243 if (scoData.getComment() != null) {
244 updateSheet(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), NO_DESCR, scoData.getComment()));
245 }
246 if (scoData.getCountAndDescription() != null) {
247 updateSheet(new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft()));
248 }
249 }
250 };
251
259 private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
260
261 /*
262 * This is called when the node is first initialized. Any new updates or
263 * changes happen by directly manipulating the sheet. That means we can fire
264 * off background events everytime this method is called and not worry about
265 * duplicated jobs.
266 */
267 @Override
268 protected synchronized Sheet createSheet() {
269 Sheet sheet = new Sheet();
270 Sheet.Set sheetSet = Sheet.createPropertiesSet();
271 sheet.put(sheetSet);
272
273 //This will fire off fresh background tasks.
274 List<NodeProperty<?>> newProperties = getProperties();
275 newProperties.forEach((property) -> {
276 sheetSet.put(property);
277 });
278
279 return sheet;
280 }
281
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"})
309
310 NAME(AbstractAbstractFileNode_nameColLbl()),
311 ORIGINAL_NAME(AbstractAbstractFileNode_originalName()),
312 SCORE(AbstractAbstractFileNode_createSheet_score_name()),
313 COMMENT(AbstractAbstractFileNode_createSheet_comment_name()),
314 OCCURRENCES(AbstractAbstractFileNode_createSheet_count_name()),
315 LOCATION(AbstractAbstractFileNode_locationColLbl()),
316 MOD_TIME(AbstractAbstractFileNode_modifiedTimeColLbl()),
317 CHANGED_TIME(AbstractAbstractFileNode_changeTimeColLbl()),
318 ACCESS_TIME(AbstractAbstractFileNode_accessTimeColLbl()),
319 CREATED_TIME(AbstractAbstractFileNode_createdTimeColLbl()),
320 SIZE(AbstractAbstractFileNode_sizeColLbl()),
321 FLAGS_DIR(AbstractAbstractFileNode_flagsDirColLbl()),
322 FLAGS_META(AbstractAbstractFileNode_flagsMetaColLbl()),
323 MODE(AbstractAbstractFileNode_modeColLbl()),
324 USER_ID(AbstractAbstractFileNode_useridColLbl()),
325 GROUP_ID(AbstractAbstractFileNode_groupidColLbl()),
326 META_ADDR(AbstractAbstractFileNode_metaAddrColLbl()),
327 ATTR_ADDR(AbstractAbstractFileNode_attrAddrColLbl()),
328 TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
329 TYPE_META(AbstractAbstractFileNode_typeMetaColLbl()),
330 KNOWN(AbstractAbstractFileNode_knownColLbl()),
331 MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
332 SHA256HASH(AbstractAbstractFileNode_sha256HashColLbl()),
333 ObjectID(AbstractAbstractFileNode_objectId()),
334 MIMETYPE(AbstractAbstractFileNode_mimeType()),
335 EXTENSION(AbstractAbstractFileNode_extensionColLbl());
336
337 final private String displayString;
338
340 this.displayString = displayString;
341 }
342
343 @Override
344 public String toString() {
345 return displayString;
346 }
347 }
348
352 private List<NodeProperty<?>> getProperties() {
353 List<NodeProperty<?>> properties = new ArrayList<>();
354 properties.add(new NodeProperty<>(NAME.toString(), NAME.toString(), NO_DESCR, getContentDisplayName(content)));
355 /*
356 * Initialize an empty place holder value. At the bottom, we kick off a
357 * background task that promises to update these values.
358 */
359
361 properties.add(new NodeProperty<>(ORIGINAL_NAME.toString(), ORIGINAL_NAME.toString(), NO_DESCR, ""));
362 }
363
364 // Create place holders for S C O
366 properties.add(new NodeProperty<>(SCORE.toString(), SCORE.toString(), VALUE_LOADING, ""));
367 properties.add(new NodeProperty<>(COMMENT.toString(), COMMENT.toString(), VALUE_LOADING, ""));
369 properties.add(new NodeProperty<>(OCCURRENCES.toString(), OCCURRENCES.toString(), VALUE_LOADING, ""));
370 }
371 // Get the SCO columns data in a background task
372 backgroundTasksPool.submit(new GetSCOTask(
373 new WeakReference<>(this), weakPcl));
374 }
375
376 properties.add(new NodeProperty<>(MOD_TIME.toString(), MOD_TIME.toString(), NO_DESCR, TimeZoneUtils.getFormattedTime(content.getMtime())));
377 properties.add(new NodeProperty<>(CHANGED_TIME.toString(), CHANGED_TIME.toString(), NO_DESCR, TimeZoneUtils.getFormattedTime(content.getCtime())));
378 properties.add(new NodeProperty<>(ACCESS_TIME.toString(), ACCESS_TIME.toString(), NO_DESCR, TimeZoneUtils.getFormattedTime(content.getAtime())));
379 properties.add(new NodeProperty<>(CREATED_TIME.toString(), CREATED_TIME.toString(), NO_DESCR, TimeZoneUtils.getFormattedTime(content.getCrtime())));
380 properties.add(new NodeProperty<>(SIZE.toString(), SIZE.toString(), NO_DESCR, content.getSize()));
381 properties.add(new NodeProperty<>(FLAGS_DIR.toString(), FLAGS_DIR.toString(), NO_DESCR, content.getDirFlagAsString()));
382 properties.add(new NodeProperty<>(FLAGS_META.toString(), FLAGS_META.toString(), NO_DESCR, content.getMetaFlagsAsString()));
383 properties.add(new NodeProperty<>(KNOWN.toString(), KNOWN.toString(), NO_DESCR, content.getKnown().getName()));
384 properties.add(new NodeProperty<>(LOCATION.toString(), LOCATION.toString(), NO_DESCR, getContentPath(content)));
385 properties.add(new NodeProperty<>(MD5HASH.toString(), MD5HASH.toString(), NO_DESCR, StringUtils.defaultString(content.getMd5Hash())));
386 properties.add(new NodeProperty<>(SHA256HASH.toString(), SHA256HASH.toString(), NO_DESCR, StringUtils.defaultString(content.getSha256Hash())));
387 properties.add(new NodeProperty<>(MIMETYPE.toString(), MIMETYPE.toString(), NO_DESCR, StringUtils.defaultString(content.getMIMEType())));
388 properties.add(new NodeProperty<>(EXTENSION.toString(), EXTENSION.toString(), NO_DESCR, content.getNameExtension()));
389
390 return properties;
391 }
392
402 @NbBundle.Messages("AbstractAbstractFileNode.tagsProperty.displayName=Tags")
403 @Deprecated
404 protected void addTagProperty(Sheet.Set sheetSet) {
405 List<ContentTag> tags = getContentTagsFromDatabase();
406 sheetSet.put(new NodeProperty<>("Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
407 NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
408 .distinct()
409 .collect(Collectors.joining(", "))));
410 }
411
422 @Deprecated
423 protected static String getHashSetHitsCsvList(AbstractFile file) {
424 try {
425 return StringUtils.join(file.getHashSetNames(), ", ");
426 } catch (TskCoreException tskCoreException) {
427 logger.log(Level.WARNING, "Error getting hashset hits: ", tskCoreException); //NON-NLS
428 return "";
429 }
430 }
431
432 @NbBundle.Messages({
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"})
437 @Override
438 protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance attributeInstance, String defaultDescription) {
439 Long count = -1L; //The column renderer will not display negative values, negative value used when count unavailble to preserve sorting
440 String description = defaultDescription;
441 try {
442 //don't perform the query if there is no correlation value
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();
448 }
449 } catch (CentralRepoException ex) {
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);
453 }
454 return Pair.of(count, description);
455 }
456
457 @NbBundle.Messages({
458 "AbstractAbstractFileNode.createSheet.comment.displayName=C"})
459 @Override
460 protected HasCommentStatus getCommentProperty(List<Tag> tags, List<CorrelationAttributeInstance> attributes) {
462 for (Tag tag : tags) {
463 if (!StringUtils.isBlank(tag.getComment())) {
464 //if the tag is null or empty or contains just white space it will indicate there is not a comment
466 break;
467 }
468 }
469 /*
470 * Is there a comment in the CR for anything that matches the value and
471 * type of the specified attributes.
472 */
473 try {
477 } else {
479 }
480 }
481 } catch (CentralRepoException ex) {
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);
483 }
484 return status;
485 }
486
493 String getTranslatedFileName() {
494 try {
495 return FileNameTranslationUtil.translate(content.getName());
496 } catch (NoServiceProviderException | TranslationException ex) {
497 logger.log(Level.WARNING, MessageFormat.format("Error translating file name (objID={0}))", content.getId()), ex);
498 return "";
499 }
500 }
501
507 List<ContentTag> getContentTagsFromDatabase() {
508 List<ContentTag> tags = new ArrayList<>();
509 try {
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);
513 }
514 return tags;
515 }
516
517 @Override
518 protected List<Tag> getAllTagsFromDatabase() {
519 return new ArrayList<>(getContentTagsFromDatabase());
520 }
521
522 static String getContentPath(AbstractFile file) {
523 try {
524 return file.getUniquePath();
525 } catch (TskCoreException ex) {
526 logger.log(Level.SEVERE, "Except while calling Content.getUniquePath() on " + file.getName(), ex); //NON-NLS
527 return ""; //NON-NLS
528 }
529 }
530
531 static String getContentDisplayName(AbstractFile file) {
532 String name = file.getName();
533 switch (name) {
534 case "..":
535 return DirectoryNode.DOTDOTDIR;
536 case ".":
537 return DirectoryNode.DOTDIR;
538 default:
539 return name;
540 }
541 }
542
553 static public void fillPropertyMap(Map<String, Object> map, AbstractFile content) {
554 map.put(NAME.toString(), getContentDisplayName(content));
555 map.put(LOCATION.toString(), getContentPath(content));
556 map.put(MOD_TIME.toString(), TimeZoneUtils.getFormattedTime(content.getMtime()));
557 map.put(CHANGED_TIME.toString(), TimeZoneUtils.getFormattedTime(content.getCtime()));
558 map.put(ACCESS_TIME.toString(), TimeZoneUtils.getFormattedTime(content.getAtime()));
559 map.put(CREATED_TIME.toString(), TimeZoneUtils.getFormattedTime(content.getCrtime()));
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());
568 }
569}
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition Case.java:757
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition Case.java:712
static boolean commentExistsOnAttributes(List< CorrelationAttributeInstance > attributes)
static CorrelationAttributeInstance getCorrAttrForFile(AbstractFile file)
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static String getFormattedTime(long epochTime)
Pair< Long, String > getCountPropertyAndDescription(CorrelationAttributeInstance attributeInstance, String defaultDescription)
static void fillPropertyMap(Map< String, Object > map, AbstractFile content)
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
HasCommentStatus getCommentProperty(List< Tag > tags, List< CorrelationAttributeInstance > attributes)
synchronized void updateSheet(NodeProperty<?>... newProps)
static void post(String nodeName, Object event)
static synchronized IngestManager getInstance()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
void addIngestModuleEventListener(final PropertyChangeListener listener)
Long getCountCasesWithOtherInstances(CorrelationAttributeInstance instance)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.