Autopsy  4.6.0
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 2011-2018 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  */
19 package org.sleuthkit.autopsy.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.ArrayList;
24 import java.util.EnumSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.logging.Level;
29 import java.util.stream.Collectors;
30 import org.apache.commons.lang3.StringUtils;
31 import org.openide.nodes.Children;
32 import org.openide.nodes.Sheet;
33 import org.openide.util.NbBundle;
34 import org.openide.util.WeakListeners;
41 import static org.sleuthkit.autopsy.datamodel.Bundle.*;
44 import org.sleuthkit.datamodel.AbstractFile;
45 import org.sleuthkit.datamodel.Content;
46 import org.sleuthkit.datamodel.ContentTag;
47 import org.sleuthkit.datamodel.TskCoreException;
48 
54 public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends AbstractContentNode<T> {
55 
56  private static final Logger logger = Logger.getLogger(AbstractAbstractFileNode.class.getName());
57  @NbBundle.Messages("AbstractAbstractFileNode.addFileProperty.desc=no description")
58  private static final String NO_DESCR = AbstractAbstractFileNode_addFileProperty_desc();
59 
60  private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
62 
66  AbstractAbstractFileNode(T abstractFile) {
67  super(abstractFile);
68  String ext = abstractFile.getNameExtension();
69  if (StringUtils.isNotBlank(ext)) {
70  ext = "." + ext;
71  // If this is an archive file we will listen for ingest events
72  // that will notify us when new content has been identified.
73  if (FileTypeExtensions.getArchiveExtensions().contains(ext)) {
75  }
76  }
77  // Listen for case events so that we can detect when the case is closed
78  // or when tags are added.
80  }
81 
91  @Override
92  protected void finalize() throws Throwable {
93  super.finalize();
95  }
96 
97  private void removeListeners() {
100  }
101 
102  private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
103  String eventType = evt.getPropertyName();
104 
105  // Is this a content changed event?
106  if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString())) {
107  if ((evt.getOldValue() instanceof ModuleContentEvent) == false) {
108  return;
109  }
110  ModuleContentEvent moduleContentEvent = (ModuleContentEvent) evt.getOldValue();
111  if ((moduleContentEvent.getSource() instanceof Content) == false) {
112  return;
113  }
114  Content newContent = (Content) moduleContentEvent.getSource();
115 
116  // Does the event indicate that content has been added to *this* file?
117  if (getContent().getId() == newContent.getId()) {
118  // If so, refresh our children.
119  try {
120  Children parentsChildren = getParentNode().getChildren();
121  // We only want to refresh our parents children if we are in the
122  // data sources branch of the tree. The parent nodes in other
123  // branches of the tree (e.g. File Types and Deleted Files) do
124  // not need to be refreshed.
125  if (parentsChildren instanceof ContentChildren) {
126  ((ContentChildren) parentsChildren).refreshChildren();
127  parentsChildren.getNodesCount();
128  }
129  } catch (NullPointerException ex) {
130  // Skip
131  }
132  }
133  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
134  if (evt.getNewValue() == null) {
135  // case was closed. Remove listeners so that we don't get called with a stale case handle
136  removeListeners();
137  }
138  } else if (eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())) {
140  if (event.getAddedTag().getContent().equals(content)) {
141  updateSheet();
142  }
143  } else if (eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) {
145  if (event.getDeletedTagInfo().getContentID() == content.getId()) {
146  updateSheet();
147  }
148  }
149  };
150 
159  private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
160 
161  private void updateSheet() {
162  this.setSheet(createSheet());
163  }
164 
165  @NbBundle.Messages({"AbstractAbstractFileNode.nameColLbl=Name",
166  "AbstractAbstractFileNode.locationColLbl=Location",
167  "AbstractAbstractFileNode.modifiedTimeColLbl=Modified Time",
168  "AbstractAbstractFileNode.changeTimeColLbl=Change Time",
169  "AbstractAbstractFileNode.accessTimeColLbl=Access Time",
170  "AbstractAbstractFileNode.createdTimeColLbl=Created Time",
171  "AbstractAbstractFileNode.sizeColLbl=Size",
172  "AbstractAbstractFileNode.flagsDirColLbl=Flags(Dir)",
173  "AbstractAbstractFileNode.flagsMetaColLbl=Flags(Meta)",
174  "AbstractAbstractFileNode.modeColLbl=Mode",
175  "AbstractAbstractFileNode.useridColLbl=UserID",
176  "AbstractAbstractFileNode.groupidColLbl=GroupID",
177  "AbstractAbstractFileNode.metaAddrColLbl=Meta Addr.",
178  "AbstractAbstractFileNode.attrAddrColLbl=Attr. Addr.",
179  "AbstractAbstractFileNode.typeDirColLbl=Type(Dir)",
180  "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)",
181  "AbstractAbstractFileNode.knownColLbl=Known",
182  "AbstractAbstractFileNode.inHashsetsColLbl=In Hashsets",
183  "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash",
184  "AbstractAbstractFileNode.objectId=Object ID",
185  "AbstractAbstractFileNode.mimeType=MIME Type",
186  "AbstractAbstractFileNode.extensionColLbl=Extension"})
188 
189  NAME(AbstractAbstractFileNode_nameColLbl()),
190  LOCATION(AbstractAbstractFileNode_locationColLbl()),
191  MOD_TIME(AbstractAbstractFileNode_modifiedTimeColLbl()),
192  CHANGED_TIME(AbstractAbstractFileNode_changeTimeColLbl()),
193  ACCESS_TIME(AbstractAbstractFileNode_accessTimeColLbl()),
194  CREATED_TIME(AbstractAbstractFileNode_createdTimeColLbl()),
195  SIZE(AbstractAbstractFileNode_sizeColLbl()),
196  FLAGS_DIR(AbstractAbstractFileNode_flagsDirColLbl()),
197  FLAGS_META(AbstractAbstractFileNode_flagsMetaColLbl()),
198  MODE(AbstractAbstractFileNode_modeColLbl()),
199  USER_ID(AbstractAbstractFileNode_useridColLbl()),
200  GROUP_ID(AbstractAbstractFileNode_groupidColLbl()),
201  META_ADDR(AbstractAbstractFileNode_metaAddrColLbl()),
202  ATTR_ADDR(AbstractAbstractFileNode_attrAddrColLbl()),
203  TYPE_DIR(AbstractAbstractFileNode_typeDirColLbl()),
204  TYPE_META(AbstractAbstractFileNode_typeMetaColLbl()),
205  KNOWN(AbstractAbstractFileNode_knownColLbl()),
206  HASHSETS(AbstractAbstractFileNode_inHashsetsColLbl()),
207  MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
208  ObjectID(AbstractAbstractFileNode_objectId()),
209  MIMETYPE(AbstractAbstractFileNode_mimeType()),
210  EXTENSION(AbstractAbstractFileNode_extensionColLbl());
211 
212  final private String displayString;
213 
214  private AbstractFilePropertyType(String displayString) {
215  this.displayString = displayString;
216  }
217 
218  @Override
219  public String toString() {
220  return displayString;
221  }
222  }
223 
231  static public void fillPropertyMap(Map<String, Object> map, AbstractFile content) {
232  map.put(NAME.toString(), getContentDisplayName(content));
233  map.put(LOCATION.toString(), getContentPath(content));
234  map.put(MOD_TIME.toString(), ContentUtils.getStringTime(content.getMtime(), content));
235  map.put(CHANGED_TIME.toString(), ContentUtils.getStringTime(content.getCtime(), content));
236  map.put(ACCESS_TIME.toString(), ContentUtils.getStringTime(content.getAtime(), content));
237  map.put(CREATED_TIME.toString(), ContentUtils.getStringTime(content.getCrtime(), content));
238  map.put(SIZE.toString(), content.getSize());
239  map.put(FLAGS_DIR.toString(), content.getDirFlagAsString());
240  map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());
241  map.put(MODE.toString(), content.getModesAsString());
242  map.put(USER_ID.toString(), content.getUid());
243  map.put(GROUP_ID.toString(), content.getGid());
244  map.put(META_ADDR.toString(), content.getMetaAddr());
245  map.put(ATTR_ADDR.toString(), content.getAttrType().getValue() + "-" + content.getAttributeId());
246  map.put(TYPE_DIR.toString(), content.getDirType().getLabel());
247  map.put(TYPE_META.toString(), content.getMetaType().toString());
248  map.put(KNOWN.toString(), content.getKnown().getName());
249  map.put(HASHSETS.toString(), getHashSetHitsForFile(content));
250  map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
251  map.put(ObjectID.toString(), content.getId());
252  map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
253  map.put(EXTENSION.toString(), content.getNameExtension());
254  }
255 
263  @NbBundle.Messages("AbstractAbstractFileNode.tagsProperty.displayName=Tags")
264  protected void addTagProperty(Sheet.Set sheetSet) {
265  List<ContentTag> tags = new ArrayList<>();
266  try {
268  } catch (TskCoreException | NoCurrentCaseException ex) {
269  logger.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex);
270  }
271  sheetSet.put(new NodeProperty<>("Tags", AbstractAbstractFileNode_tagsProperty_displayName(),
272  NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName())
273  .distinct()
274  .collect(Collectors.joining(", "))));
275  }
276 
277  private static String getContentPath(AbstractFile file) {
278  try {
279  return file.getUniquePath();
280  } catch (TskCoreException ex) {
281  logger.log(Level.SEVERE, "Except while calling Content.getUniquePath() on " + file, ex); //NON-NLS
282  return ""; //NON-NLS
283  }
284  }
285 
286  static String getContentDisplayName(AbstractFile file) {
287  String name = file.getName();
288  switch (name) {
289  case "..":
290  return DirectoryNode.DOTDOTDIR;
291 
292  case ".":
293  return DirectoryNode.DOTDIR;
294  default:
295  return name;
296  }
297  }
298 
299  public static String getHashSetHitsForFile(AbstractFile file) {
300  try {
301  return StringUtils.join(file.getHashSetNames(), ", ");
302  } catch (TskCoreException tskCoreException) {
303  logger.log(Level.WARNING, "Error getting hashset hits: ", tskCoreException); //NON-NLS
304  return "";
305  }
306  }
307 }
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static String getStringTime(long epochSeconds, TimeZone tzone)
static synchronized IngestManager getInstance()
List< ContentTag > getContentTagsByContent(Content content)
static void fillPropertyMap(Map< String, Object > map, AbstractFile content)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:420
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:465

Copyright © 2012-2016 Basis Technology. Generated on: Mon May 7 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.