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.WeakListeners;
 
   41 import org.openide.util.lookup.Lookups;
 
   48 import static org.
sleuthkit.datamodel.BlackboardArtifact.Type.TSK_EMAIL_MSG;
 
   51 import org.
sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
 
   64     private static final String 
LABEL_NAME = BlackboardArtifact.Type.TSK_EMAIL_MSG.getTypeName();
 
   81     public static final Map<String, String> 
parsePath(String path) {
 
   82         Map<String, String> parsed = 
new HashMap<>();
 
   83         String[] split = path == null ? 
new String[0] : path.split(MAIL_PATH_SEPARATOR);
 
   84         if (split.length < 4) {
 
   85             parsed.put(MAIL_ACCOUNT, NbBundle.getMessage(
EmailExtracted.class, 
"EmailExtracted.defaultAcct.text"));
 
   86             parsed.put(MAIL_FOLDER, NbBundle.getMessage(
EmailExtracted.class, 
"EmailExtracted.defaultFolder.text"));
 
   89         parsed.put(MAIL_ACCOUNT, split[2]);
 
   90         parsed.put(MAIL_FOLDER, split[3]);
 
  115         this.filteringDSObjId = objId;
 
  121         return visitor.
visit(
this);
 
  127         private final Map<String, Map<String, List<Long>>> 
accounts = 
new LinkedHashMap<>();
 
  135                 return accounts.keySet();
 
  141                 return accounts.get(account).keySet();
 
  147                 return accounts.get(account).get(folder);
 
  151         @SuppressWarnings(
"deprecation")
 
  154             if (skCase == null) {
 
  162             int emailArtifactId = BlackboardArtifact.Type.TSK_EMAIL_MSG.getTypeID();
 
  163             int pathAttrId = BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID();
 
  165             String query = 
"SELECT \n" 
  166                     + 
" art.artifact_obj_id AS artifact_obj_id,\n" 
  167                     + 
" (SELECT value_text FROM blackboard_attributes attr\n" 
  168                     + 
" WHERE attr.artifact_id = art.artifact_id AND attr.attribute_type_id = " + pathAttrId + 
"\n" 
  169                     + 
" LIMIT 1) AS value_text\n" 
  171                     + 
" blackboard_artifacts art\n" 
  172                     + 
" WHERE art.artifact_type_id = " + emailArtifactId + 
"\n" 
  173                     + ((filteringDSObjId > 0) ? 
"       AND art.data_source_obj_id = " + filteringDSObjId : 
"");
 
  176             Map<String, Map<String, List<Long>>> newMapping = 
new HashMap<>();
 
  178             try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
 
  179                 ResultSet resultSet = dbQuery.getResultSet();
 
  180                 while (resultSet.next()) {
 
  181                     Long artifactObjId = resultSet.getLong(
"artifact_obj_id");
 
  182                     Map<String, String> accountFolderMap = 
parsePath(resultSet.getString(
"value_text"));
 
  183                     String account = accountFolderMap.get(MAIL_ACCOUNT);
 
  184                     String folder = accountFolderMap.get(MAIL_FOLDER);
 
  186                     Map<String, List<Long>> folders = newMapping.computeIfAbsent(account, (str) -> 
new LinkedHashMap<>());
 
  187                     List<Long> messages = folders.computeIfAbsent(folder, (str) -> 
new ArrayList<>());
 
  188                     messages.add(artifactObjId);
 
  190             } 
catch (TskCoreException | SQLException ex) {
 
  191                 logger.log(Level.WARNING, 
"Cannot initialize email extraction: ", ex); 
 
  196                 accounts.putAll(newMapping);
 
  212                     Lookups.singleton(TSK_EMAIL_MSG.getDisplayName()),
 
  213                     TSK_EMAIL_MSG.getDisplayName(),
 
  217             super.setName(LABEL_NAME);
 
  218             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/mail-icon-16.png"); 
 
  229             return visitor.
visit(
this);
 
  234             Sheet sheet = super.createSheet();
 
  235             Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
 
  236             if (sheetSet == null) {
 
  237                 sheetSet = Sheet.createPropertiesSet();
 
  241             sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.name"),
 
  242                     NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.displayName"),
 
  243                     NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.desc"),
 
  251             return getClass().getName();
 
  258     private class AccountFactory extends ChildFactory.Detachable<String> implements Observer {
 
  264         private final PropertyChangeListener 
pcl = 
new PropertyChangeListener() {
 
  266             public void propertyChange(PropertyChangeEvent evt) {
 
  267                 String eventType = evt.getPropertyName();
 
  284                         if (null != eventData && eventData.
getBlackboardArtifactType().getTypeID() == BlackboardArtifact.Type.TSK_EMAIL_MSG.getTypeID()) {
 
  310                     if (evt.getNewValue() == null) {
 
  318         private final PropertyChangeListener 
weakPcl = WeakListeners.propertyChange(pcl, null);
 
  326             emailResults.addObserver(
this);
 
  335             emailResults.deleteObserver(
this);
 
  350         public void update(Observable o, Object arg) {
 
  363             super(Children.create(
new FolderFactory(accountName), 
true), Lookups.singleton(accountName));
 
  364             super.setName(accountName);
 
  366             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/account-icon-16.png"); 
 
  368             emailResults.addObserver(
this);
 
  372             super.setDisplayName(accountName + 
" (" + emailResults.
getFolders(accountName) + 
")");
 
  377             Sheet sheet = super.createSheet();
 
  378             Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
 
  379             if (sheetSet == null) {
 
  380                 sheetSet = Sheet.createPropertiesSet();
 
  384             sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.name"),
 
  385                     NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.displayName"),
 
  386                     NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.desc"),
 
  399             return visitor.
visit(
this);
 
  403         public void update(Observable o, Object arg) {
 
  409             return getClass().getName();
 
  416     private class FolderFactory extends ChildFactory<String> implements Observer {
 
  423             emailResults.addObserver(
this);
 
  428             list.addAll(emailResults.
getFolders(accountName));
 
  434             return new FolderNode(accountName, folderName);
 
  438         public void update(Observable o, Object arg) {
 
  456     private static String 
getFolderKey(String accountName, String folderName) {
 
  457         return accountName + 
"_" + folderName;
 
  469             super(Children.create(
new MessageFactory(accountName, folderName), 
true), Lookups.singleton(accountName));
 
  471             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/folder-icon-16.png"); 
 
  475             emailResults.addObserver(
this);
 
  479             super.setDisplayName(folderName + 
" (" + emailResults.
getArtifactIds(accountName, folderName).size() + 
")");
 
  490             Sheet sheet = super.createSheet();
 
  491             Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
 
  492             if (sheetSet == null) {
 
  493                 sheetSet = Sheet.createPropertiesSet();
 
  497             sheetSet.put(
new NodeProperty<>(NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.name"),
 
  498                     NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.displayName"),
 
  499                     NbBundle.getMessage(
this.getClass(), 
"EmailExtracted.createSheet.name.desc"),
 
  507             return visitor.
visit(
this);
 
  511         public void update(Observable o, Object arg) {
 
  517             return getClass().getName();
 
  533             emailResults.addObserver(
this);
 
  542         public void update(Observable o, Object arg) {
 
  548             List<DataArtifact> keys = 
new ArrayList<>();
 
  550             if (skCase != null) {
 
  551                 emailResults.
getArtifactIds(accountName, folderName).forEach((
id) -> {
 
  553                         DataArtifact art = skCase.getBlackboard().getDataArtifactById(
id);
 
  558                     } 
catch (TskCoreException ex) {
 
  559                         logger.log(Level.WARNING, 
"Error getting mail messages keys", ex); 
 
BlackboardArtifact.Type getBlackboardArtifactType()
void removeIngestModuleEventListener(final PropertyChangeListener listener)
final long filteringDSObjId
static synchronized IngestManager getInstance()
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
T visit(DataSourceFilesNode in)
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)