19 package org.sleuthkit.autopsy.datamodel;
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.util.ArrayList;
26 import java.util.EnumSet;
27 import java.util.HashMap;
28 import java.util.LinkedHashMap;
29 import java.util.List;
31 import java.util.Observable;
32 import java.util.Observer;
34 import java.util.logging.Level;
35 import org.openide.nodes.ChildFactory;
36 import org.openide.nodes.Children;
37 import org.openide.nodes.Node;
38 import org.openide.nodes.Sheet;
39 import org.openide.util.NbBundle;
40 import org.openide.util.lookup.Lookups;
49 import org.
sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
60 private static final String
LABEL_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getLabel();
61 private static final String
DISPLAY_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getDisplayName();
78 public static final Map<String, String>
parsePath(String path) {
79 Map<String, String> parsed =
new HashMap<>();
80 String[] split = path.split(MAIL_PATH_SEPARATOR);
81 if (split.length < 4) {
82 parsed.put(MAIL_ACCOUNT, NbBundle.getMessage(
EmailExtracted.class,
"EmailExtracted.defaultAcct.text"));
83 parsed.put(MAIL_FOLDER, NbBundle.getMessage(
EmailExtracted.class,
"EmailExtracted.defaultFolder.text"));
86 parsed.put(MAIL_ACCOUNT, split[2]);
87 parsed.put(MAIL_FOLDER, split[3]);
112 this.filteringDSObjId = objId;
118 return visitor.
visit(
this);
124 private final Map<String, Map<String, List<Long>>>
accounts =
new LinkedHashMap<>();
132 return accounts.keySet();
138 return accounts.get(account).keySet();
144 return accounts.get(account).get(folder);
148 @SuppressWarnings(
"deprecation")
153 if (skCase == null) {
157 int artId = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID();
158 int pathAttrId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID();
159 String query =
"SELECT value_text,blackboard_attributes.artifact_id,attribute_type_id "
160 +
"FROM blackboard_attributes,blackboard_artifacts WHERE "
161 +
"attribute_type_id=" + pathAttrId
162 +
" AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id"
163 +
" AND blackboard_artifacts.artifact_type_id=" + artId;
164 if (filteringDSObjId > 0) {
165 query +=
" AND blackboard_artifacts.data_source_obj_id = " +
filteringDSObjId;
168 try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
169 ResultSet resultSet = dbQuery.getResultSet();
171 while (resultSet.next()) {
172 final String path = resultSet.getString(
"value_text");
173 final long artifactId = resultSet.getLong(
"artifact_id");
174 final Map<String, String> parsedPath =
parsePath(path);
175 final String account = parsedPath.get(MAIL_ACCOUNT);
176 final String folder = parsedPath.get(MAIL_FOLDER);
178 Map<String, List<Long>> folders = accounts.get(account);
179 if (folders == null) {
180 folders =
new LinkedHashMap<>();
181 accounts.put(account, folders);
183 List<Long> messages = folders.get(folder);
184 if (messages == null) {
185 messages =
new ArrayList<>();
186 folders.put(folder, messages);
188 messages.add(artifactId);
191 }
catch (TskCoreException | SQLException ex) {
192 logger.log(Level.WARNING,
"Cannot initialize email extraction: ", ex);
206 super(Children.create(
new AccountFactory(),
true), Lookups.singleton(DISPLAY_NAME));
207 super.setName(LABEL_NAME);
208 super.setDisplayName(DISPLAY_NAME);
209 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/mail-icon-16.png");
220 return visitor.
visit(
this);
225 Sheet sheet = super.createSheet();
226 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
227 if (sheetSet == null) {
228 sheetSet = Sheet.createPropertiesSet();
232 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
233 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
234 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
242 return getClass().getName();
249 private class AccountFactory extends ChildFactory.Detachable<String> implements Observer {
255 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
257 public void propertyChange(PropertyChangeEvent evt) {
258 String eventType = evt.getPropertyName();
275 if (null != eventData && eventData.
getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
301 if (evt.getNewValue() == null) {
315 emailResults.addObserver(
this);
323 emailResults.deleteObserver(
this);
338 public void update(Observable o, Object arg) {
351 super(Children.create(
new FolderFactory(accountName),
true), Lookups.singleton(accountName));
352 super.setName(accountName);
354 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/account-icon-16.png");
356 emailResults.addObserver(
this);
360 super.setDisplayName(accountName +
" (" + emailResults.
getFolders(accountName) +
")");
365 Sheet sheet = super.createSheet();
366 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
367 if (sheetSet == null) {
368 sheetSet = Sheet.createPropertiesSet();
372 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
373 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
374 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
387 return visitor.
visit(
this);
391 public void update(Observable o, Object arg) {
397 return getClass().getName();
404 private class FolderFactory extends ChildFactory<String> implements Observer {
411 emailResults.addObserver(
this);
416 list.addAll(emailResults.
getFolders(accountName));
422 return new FolderNode(accountName, folderName);
426 public void update(Observable o, Object arg) {
440 super(Children.create(
new MessageFactory(accountName, folderName),
true), Lookups.singleton(accountName));
441 super.setName(folderName);
442 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/folder-icon-16.png");
446 emailResults.addObserver(
this);
450 super.setDisplayName(folderName +
" (" + emailResults.
getArtifactIds(accountName, folderName).size() +
")");
461 Sheet sheet = super.createSheet();
462 Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
463 if (sheetSet == null) {
464 sheetSet = Sheet.createPropertiesSet();
468 sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
469 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
470 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
478 return visitor.
visit(
this);
482 public void update(Observable o, Object arg) {
488 return getClass().getName();
501 super(accountName +
"_" + folderName);
504 emailResults.addObserver(
this);
513 public void update(Observable o, Object arg) {
519 List<BlackboardArtifact> keys =
new ArrayList<>();
521 if (skCase != null) {
522 emailResults.
getArtifactIds(accountName, folderName).forEach((
id) -> {
524 keys.add(skCase.getBlackboardArtifact(
id));
525 }
catch (TskCoreException ex) {
526 logger.log(Level.WARNING,
"Error getting mail messages keys", ex);
BlackboardArtifact.Type getBlackboardArtifactType()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized IngestManager getInstance()
T visit(DataSourcesNode in)
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)