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.HashMap;
27 import java.util.LinkedHashMap;
28 import java.util.List;
30 import java.util.Observable;
31 import java.util.Observer;
33 import java.util.logging.Level;
34 import org.openide.nodes.ChildFactory;
35 import org.openide.nodes.Children;
36 import org.openide.nodes.Node;
37 import org.openide.nodes.Sheet;
38 import org.openide.util.NbBundle;
39 import org.openide.util.lookup.Lookups;
47 import org.
sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
58 private static final String
LABEL_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getLabel();
59 private static final String
DISPLAY_NAME = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getDisplayName();
73 public static final Map<String, String>
parsePath(String path) {
74 Map<String, String> parsed =
new HashMap<>();
75 String[] split = path.split(MAIL_PATH_SEPARATOR);
76 if (split.length < 4) {
77 parsed.put(MAIL_ACCOUNT, NbBundle.getMessage(
EmailExtracted.class,
"EmailExtracted.defaultAcct.text"));
78 parsed.put(MAIL_FOLDER, NbBundle.getMessage(
EmailExtracted.class,
"EmailExtracted.defaultFolder.text"));
81 parsed.put(MAIL_ACCOUNT, split[2]);
82 parsed.put(MAIL_FOLDER, split[3]);
102 private final Map<String, Map<String, List<Long>>>
accounts =
new LinkedHashMap<>();
110 return accounts.keySet();
116 return accounts.get(account).keySet();
122 return accounts.get(account).get(folder);
126 @SuppressWarnings(
"deprecation")
131 if (skCase == null) {
135 int artId = BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID();
136 int pathAttrId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID();
137 String query =
"SELECT value_text,blackboard_attributes.artifact_id,attribute_type_id "
138 +
"FROM blackboard_attributes,blackboard_artifacts WHERE "
139 +
"attribute_type_id=" + pathAttrId
140 +
" AND blackboard_attributes.artifact_id=blackboard_artifacts.artifact_id"
141 +
" AND blackboard_artifacts.artifact_type_id=" + artId;
143 try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
144 ResultSet resultSet = dbQuery.getResultSet();
146 while (resultSet.next()) {
147 final String path = resultSet.getString(
"value_text");
148 final long artifactId = resultSet.getLong(
"artifact_id");
149 final Map<String, String> parsedPath =
parsePath(path);
150 final String account = parsedPath.get(MAIL_ACCOUNT);
151 final String folder = parsedPath.get(MAIL_FOLDER);
153 Map<String, List<Long>> folders = accounts.get(account);
154 if (folders == null) {
155 folders =
new LinkedHashMap<>();
156 accounts.put(account, folders);
158 List<Long> messages = folders.get(folder);
159 if (messages == null) {
160 messages =
new ArrayList<>();
161 folders.put(folder, messages);
163 messages.add(artifactId);
166 }
catch (TskCoreException | SQLException ex) {
167 logger.log(Level.WARNING,
"Cannot initialize email extraction: ", ex);
181 super(Children.create(
new AccountFactory(),
true), Lookups.singleton(DISPLAY_NAME));
182 super.setName(LABEL_NAME);
183 super.setDisplayName(DISPLAY_NAME);
184 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/mail-icon-16.png");
195 return v.
visit(
this);
200 Sheet s = super.createSheet();
201 Sheet.Set ss = s.get(Sheet.PROPERTIES);
203 ss = Sheet.createPropertiesSet();
207 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
208 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
209 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
217 return getClass().getName();
224 private class AccountFactory extends ChildFactory.Detachable<String> implements Observer {
230 private final PropertyChangeListener
pcl =
new PropertyChangeListener() {
232 public void propertyChange(PropertyChangeEvent evt) {
233 String eventType = evt.getPropertyName();
250 if (null != eventData && eventData.
getBlackboardArtifactType().getTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
253 }
catch (IllegalStateException notUsed) {
269 }
catch (IllegalStateException notUsed) {
276 if (evt.getNewValue() == null) {
290 emailResults.addObserver(
this);
298 emailResults.deleteObserver(
this);
313 public void update(Observable o, Object arg) {
326 super(Children.create(
new FolderFactory(accountName),
true), Lookups.singleton(accountName));
327 super.setName(accountName);
329 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/account-icon-16.png");
331 emailResults.addObserver(
this);
335 super.setDisplayName(accountName +
" (" + emailResults.
getFolders(accountName) +
")");
340 Sheet s = super.createSheet();
341 Sheet.Set ss = s.get(Sheet.PROPERTIES);
343 ss = Sheet.createPropertiesSet();
347 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
348 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
349 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
362 return v.
visit(
this);
366 public void update(Observable o, Object arg) {
372 return getClass().getName();
379 private class FolderFactory extends ChildFactory<String> implements Observer {
386 emailResults.addObserver(
this);
391 list.addAll(emailResults.
getFolders(accountName));
397 return new FolderNode(accountName, folderName);
401 public void update(Observable o, Object arg) {
415 super(Children.create(
new MessageFactory(accountName, folderName),
true), Lookups.singleton(accountName));
416 super.setName(folderName);
417 this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/folder-icon-16.png");
421 emailResults.addObserver(
this);
425 super.setDisplayName(folderName +
" (" + emailResults.
getArtifactIds(accountName, folderName).size() +
")");
436 Sheet s = super.createSheet();
437 Sheet.Set ss = s.get(Sheet.PROPERTIES);
439 ss = Sheet.createPropertiesSet();
443 ss.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.name"),
444 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.displayName"),
445 NbBundle.getMessage(
this.getClass(),
"EmailExtracted.createSheet.name.desc"),
453 return v.
visit(
this);
457 public void update(Observable o, Object arg) {
463 return getClass().getName();
479 emailResults.addObserver(
this);
484 list.addAll(emailResults.
getArtifactIds(accountName, folderName));
490 if (skCase == null) {
494 BlackboardArtifact artifact = skCase.getBlackboardArtifact(artifactId);
496 }
catch (TskCoreException ex) {
497 logger.log(Level.WARNING,
"Error creating mail messages nodes", ex);
503 public void update(Observable o, Object arg) {
BlackboardArtifact.Type getBlackboardArtifactType()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized IngestManager getInstance()
static void removePropertyChangeListener(PropertyChangeListener listener)
T visit(DataSourcesNode in)
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
static void addPropertyChangeListener(PropertyChangeListener listener)
void addIngestModuleEventListener(final PropertyChangeListener listener)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)