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

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