19 package org.sleuthkit.autopsy.datamodel.accounts;
 
   21 import com.google.common.collect.Range;
 
   22 import com.google.common.collect.RangeMap;
 
   23 import com.google.common.collect.TreeRangeMap;
 
   24 import com.google.common.eventbus.EventBus;
 
   25 import com.google.common.eventbus.Subscribe;
 
   26 import java.awt.event.ActionEvent;
 
   27 import java.beans.PropertyChangeEvent;
 
   28 import java.beans.PropertyChangeListener;
 
   29 import java.sql.ResultSet;
 
   30 import java.sql.SQLException;
 
   31 import java.util.ArrayList;
 
   32 import java.util.Arrays;
 
   33 import java.util.Collection;
 
   34 import java.util.Collections;
 
   35 import java.util.EnumSet;
 
   36 import java.util.HashMap;
 
   37 import java.util.HashSet;
 
   38 import java.util.List;
 
   40 import java.util.Objects;
 
   41 import java.util.Optional;
 
   43 import java.util.function.Function;
 
   44 import java.util.logging.Level;
 
   45 import java.util.stream.Collectors;
 
   46 import java.util.stream.Stream;
 
   47 import javax.annotation.Nonnull;
 
   48 import javax.annotation.concurrent.Immutable;
 
   49 import javax.swing.AbstractAction;
 
   50 import javax.swing.Action;
 
   51 import javax.swing.SwingUtilities;
 
   52 import org.apache.commons.lang3.StringUtils;
 
   53 import org.openide.nodes.ChildFactory;
 
   54 import org.openide.nodes.Children;
 
   55 import org.openide.nodes.Node;
 
   56 import org.openide.nodes.NodeNotFoundException;
 
   57 import org.openide.nodes.NodeOp;
 
   58 import org.openide.nodes.Sheet;
 
   59 import org.openide.util.NbBundle;
 
   60 import org.openide.util.Utilities;
 
   61 import org.openide.util.WeakListeners;
 
   62 import org.openide.util.lookup.Lookups;
 
   98     private static final String 
ICON_BASE_PATH = 
"/org/sleuthkit/autopsy/images/"; 
 
  101     private static final String 
DISPLAY_NAME = Bundle.Accounts_RootNode_displayName();
 
  103     @NbBundle.Messages(
"AccountsRootNode.name=Accounts")  
 
  104     final public static String 
NAME = Bundle.AccountsRootNode_name();
 
  137         this.filteringDSObjId = objId;
 
  146         return visitor.
visit(
this);
 
  167         if (filteringDSObjId > 0) {
 
  168             return "  AND blackboard_artifacts.data_source_obj_id = " + filteringDSObjId + 
" ";
 
  207         abstract protected boolean createKeys(List<X> list);
 
  237     @NbBundle.Messages({
"Accounts.RootNode.displayName=Communication Accounts"})
 
  248             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/accounts.png");    
 
  258             return visitor.
visit(
this);
 
  263             return getClass().getName();
 
  268             String accountTypesInUseQuery
 
  269                     = 
"SELECT COUNT(*) AS count\n" 
  271                     + 
"  SELECT MIN(blackboard_attributes.value_text) AS account_type\n" 
  272                     + 
"  FROM blackboard_artifacts\n" 
  273                     + 
"  LEFT JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id\n" 
  274                     + 
"  WHERE blackboard_artifacts.artifact_type_id = " + TSK_ACCOUNT.getTypeID() + 
"\n" 
  276                     + 
"  AND blackboard_attributes.value_text IS NOT NULL\n" 
  278                     + 
"  -- group by artifact_id to ensure only one account type per artifact\n" 
  279                     + 
"  GROUP BY blackboard_artifacts.artifact_id\n" 
  285                 if (resultSet.next()) {
 
  286                     return resultSet.getLong(
"count");
 
  290                 LOGGER.log(Level.SEVERE, 
"Error querying for count of all account types", ex);
 
  303         private final Map<String, Long> 
counts = 
new HashMap<>();
 
  317         Long getCount(String accountType) {
 
  318             return counts.get(accountType);
 
  326         List<String> getTypes() {
 
  327             List<String> types = 
new ArrayList<>(counts.keySet());
 
  328             Collections.sort(types);
 
  336             String accountTypesInUseQuery
 
  337                     = 
"SELECT res.account_type, COUNT(*) AS count\n" 
  339                     + 
"  SELECT MIN(blackboard_attributes.value_text) AS account_type\n" 
  340                     + 
"  FROM blackboard_artifacts\n" 
  341                     + 
"  LEFT JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id\n" 
  342                     + 
"  WHERE blackboard_artifacts.artifact_type_id = " + TSK_ACCOUNT.getTypeID() + 
"\n" 
  345                     + 
"  -- group by artifact_id to ensure only one account type per artifact\n" 
  346                     + 
"  GROUP BY blackboard_artifacts.artifact_id\n" 
  348                     + 
"GROUP BY res.account_type";
 
  354                 while (resultSet.next()) {
 
  355                     String accountType = resultSet.getString(
"account_type");
 
  356                     Long count = resultSet.getLong(
"count");
 
  357                     counts.put(accountType, count);
 
  360                 LOGGER.log(Level.SEVERE, 
"Error querying for account_types", ex);
 
  374         private final PropertyChangeListener 
pcl = 
new PropertyChangeListener() {
 
  376             public void propertyChange(PropertyChangeEvent evt) {
 
  377                 String eventType = evt.getPropertyName();
 
  394                         if (null != eventData
 
  396                             accountTypeResults.
update();
 
  397                             reviewStatusBus.post(eventData);
 
  412                         accountTypeResults.
update();
 
  421         private final PropertyChangeListener 
weakPcl = WeakListeners.propertyChange(pcl, null);
 
  437             list.addAll(accountTypeResults.getTypes());
 
  450             reviewStatusBus.register(node);
 
  451             return new Node[]{node};
 
  463                     if (accountType != null) {
 
  467                         LOGGER.log(Level.SEVERE, 
"Unknown account type '" + accountTypeName + 
"' found - account will not be displayed.\n" 
  468                                 + 
"Account type names must match an entry in the display_name column of the account_types table.\n" 
  469                                 + 
"Accounts should be created using the CommunicationManager API.");
 
  472                     LOGGER.log(Level.SEVERE, 
"Error getting display name for account type. ", ex);
 
  506         private final PropertyChangeListener pcl = 
new PropertyChangeListener() {
 
  508             public void propertyChange(PropertyChangeEvent evt) {
 
  509                 String eventType = evt.getPropertyName();
 
  526                         if (null != eventData
 
  528                             reviewStatusBus.post(eventData);
 
  552         private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
 
  572                     = 
"SELECT blackboard_artifacts.artifact_obj_id "  
  573                     + 
" FROM blackboard_artifacts "  
  574                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "  
  577                     + 
"     AND blackboard_attributes.value_text = '" + accountType.getTypeName() + 
"'"  
  582                 List<Long> tempList = 
new ArrayList<>();
 
  584                     tempList.add(rs.getLong(
"artifact_obj_id")); 
 
  586                 list.addAll(tempList);
 
  588                 LOGGER.log(Level.SEVERE, 
"Error querying for account artifacts.", ex); 
 
  599                 LOGGER.log(Level.SEVERE, 
"Error get black board artifact with id " + t, ex);
 
  626             super(Children.create(
new DefaultAccountFactory(accountType), 
true), Lookups.singleton(accountType));
 
  629             this.setIconBaseWithExtension(iconPath != null && iconPath.charAt(0) == 
'/' ? iconPath.substring(1) : iconPath);   
 
  630             setName(accountType.getTypeName());
 
  641             return visitor.
visit(
this);
 
  646             return getClass().getName();
 
  664             setDisplayName(String.format(
"%s (%d)", accountType.getDisplayName(), accountTypeResults.getCount(accountType.getTypeName())));
 
  678         private final PropertyChangeListener pcl = 
new PropertyChangeListener() {
 
  680             public void propertyChange(PropertyChangeEvent evt) {
 
  681                 String eventType = evt.getPropertyName();
 
  698                         if (null != eventData
 
  700                             reviewStatusBus.post(eventData);
 
  724         private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
 
  752             super.removeNotify();
 
  759         protected boolean createKeys(List<CreditCardViewMode> list) {
 
  790             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/credit-cards.png");   
 
  818             return visitor.
visit(
this);
 
  823             return getClass().getName();
 
  829         private final PropertyChangeListener pcl = 
new PropertyChangeListener() {
 
  831             public void propertyChange(PropertyChangeEvent evt) {
 
  832                 String eventType = evt.getPropertyName();
 
  849                         if (null != eventData
 
  851                             reviewStatusBus.post(eventData);
 
  875         private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
 
  909                         = 
"SELECT blackboard_artifacts.obj_id,"  
  910                         + 
"      solr_attribute.value_text AS solr_document_id, "; 
 
  912                     query += 
"      string_agg(blackboard_artifacts.artifact_id::character varying, ',') AS artifact_IDs, "  
  913                             + 
"      string_agg(blackboard_artifacts.review_status_id::character varying, ',') AS review_status_ids, ";
 
  915                     query += 
"      GROUP_CONCAT(blackboard_artifacts.artifact_id) AS artifact_IDs, "  
  916                             + 
"      GROUP_CONCAT(blackboard_artifacts.review_status_id) AS review_status_ids, ";
 
  918                 query += 
"      COUNT( blackboard_artifacts.artifact_id) AS hits  "  
  919                         + 
" FROM blackboard_artifacts "  
  920                         + 
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "  
  922                         + 
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "  
  928                         + 
" GROUP BY blackboard_artifacts.obj_id, solr_document_id "  
  929                         + 
" ORDER BY hits DESC ";  
 
  932                     while (resultSet.next()) {
 
  933                         long file_id = resultSet.getLong(
"obj_id");
 
  935                         if (abstractFileById != null) {
 
  939                                     resultSet.getString(
"solr_document_id"), 
 
  940                                     unGroupConcat(resultSet.getString(
"artifact_IDs"), Long::valueOf), 
 
  941                                     resultSet.getLong(
"hits"), 
 
  946                     LOGGER.log(Level.SEVERE, 
"Error querying for files with ccn hits.", ex); 
 
  950                 LOGGER.log(Level.SEVERE, 
"Error getting case.", ex);
 
  959                 List<Object> lookupContents = 
new ArrayList<>();
 
  964                 lookupContents.add(abstractFileById);
 
  965                 return new Node[]{
new FileWithCCNNode(key, abstractFileById, lookupContents.toArray())};
 
  967                 LOGGER.log(Level.SEVERE, 
"Error getting content for file with ccn hits.", ex); 
 
  986             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/file-icon.png");   
 
  987             reviewStatusBus.register(
this);
 
  991             "# {0} - number of children",
 
  992             "Accounts.ByFileNode.displayName=By File ({0})"})
 
  995                     = 
"SELECT count(*) FROM ( SELECT count(*) AS documents " 
  996                     + 
" FROM blackboard_artifacts "  
  997                     + 
" LEFT JOIN blackboard_attributes as solr_attribute ON blackboard_artifacts.artifact_id = solr_attribute.artifact_id "  
  999                     + 
" LEFT JOIN blackboard_attributes as account_type ON blackboard_artifacts.artifact_id = account_type.artifact_id "  
 1005                     + 
" GROUP BY blackboard_artifacts.obj_id, solr_attribute.value_text ) AS foo";
 
 1008                 while (resultSet.next()) {
 
 1010                         setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count")));
 
 1012                         setDisplayName(Bundle.Accounts_ByFileNode_displayName(resultSet.getLong(
"count(*)")));
 
 1016                 LOGGER.log(Level.SEVERE, 
"Error querying for files with ccn hits.", ex); 
 
 1028             return visitor.
visit(
this);
 
 1033             return getClass().getName();
 
 1038             updateDisplayName();
 
 1043             updateDisplayName();
 
 1049         private final PropertyChangeListener pcl = 
new PropertyChangeListener() {
 
 1051             public void propertyChange(PropertyChangeEvent evt) {
 
 1052                 String eventType = evt.getPropertyName();
 
 1069                         if (null != eventData
 
 1071                             reviewStatusBus.post(eventData);
 
 1095         private final PropertyChangeListener weakPcl = WeakListeners.propertyChange(pcl, null);
 
 1128             RangeMap<Integer, BinResult> binRanges = TreeRangeMap.create();
 
 1131                     = 
"SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, "  
 1132                     + 
"     COUNT(blackboard_artifacts.artifact_id) AS count "  
 1133                     + 
" FROM blackboard_artifacts "  
 1134                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"  
 1144                 while (resultSet.next()) {
 
 1145                     final Integer bin = Integer.valueOf(resultSet.getString(
"BIN"));
 
 1146                     long count = resultSet.getLong(
"count");
 
 1149                     BinResult previousResult = binRanges.get(bin);
 
 1151                     if (previousResult != null) {
 
 1152                         binRanges.remove(Range.closed(previousResult.getBINStart(), previousResult.getBINEnd()));
 
 1153                         count += previousResult.getCount();
 
 1156                     if (binRange == null) {
 
 1157                         binRanges.put(Range.closed(bin, bin), 
new BinResult(count, bin, bin));
 
 1162                 binRanges.asMapOfRanges().values().forEach(list::add);
 
 1164                 LOGGER.log(Level.SEVERE, 
"Error querying for BINs.", ex); 
 
 1172             return new Node[]{
new BINNode(key)};
 
 1185         @NbBundle.Messages(
"Accounts.ByBINNode.name=By BIN")
 
 1187             super(Children.create(
new BINFactory(), 
true), Lookups.singleton(Bundle.Accounts_ByBINNode_name()));
 
 1188             setName(Bundle.Accounts_ByBINNode_name());  
 
 1189             updateDisplayName();
 
 1190             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");   
 
 1191             reviewStatusBus.register(
this);
 
 1194         @NbBundle.Messages({
 
 1195             "# {0} - number of children",
 
 1196             "Accounts.ByBINNode.displayName=By BIN ({0})"})
 
 1199                     = 
"SELECT count(distinct SUBSTR(blackboard_attributes.value_text,1,8)) AS BINs "  
 1200                     + 
" FROM blackboard_artifacts "  
 1201                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id"  
 1208                 while (resultSet.next()) {
 
 1209                     setDisplayName(Bundle.Accounts_ByBINNode_displayName(resultSet.getLong(
"BINs")));
 
 1212                 LOGGER.log(Level.SEVERE, 
"Error querying for BINs.", ex); 
 
 1223             return visitor.
visit(
this);
 
 1228             return getClass().getName();
 
 1233             updateDisplayName();
 
 1238             updateDisplayName();
 
 1252             hash = 79 * hash + (int) (this.objID ^ (this.objID >>> 32));
 
 1253             hash = 79 * hash + Objects.hashCode(this.keywordSearchDocID);
 
 1254             hash = 79 * hash + Objects.hashCode(this.artifactIDs);
 
 1255             hash = 79 * hash + (int) (this.hits ^ (this.hits >>> 32));
 
 1256             hash = 79 * hash + Objects.hashCode(this.statuses);
 
 1268             if (getClass() != obj.getClass()) {
 
 1272             if (this.objID != other.
objID) {
 
 1275             if (this.hits != other.
hits) {
 
 1281             if (!Objects.equals(
this.artifactIDs, other.
artifactIDs)) {
 
 1284             if (!Objects.equals(
this.statuses, other.
statuses)) {
 
 1297         private FileWithCCN(
AbstractFile file, 
long objID, String solrDocID, List<Long> artifactIDs, 
long hits, Set<BlackboardArtifact.ReviewStatus> statuses) {
 
 1299             this.keywordSearchDocID = solrDocID;
 
 1300             this.artifactIDs = artifactIDs;
 
 1302             this.statuses = statuses;
 
 1322             return keywordSearchDocID;
 
 1331             return Collections.unmodifiableList(artifactIDs);
 
 1349             return Collections.unmodifiableSet(statuses);
 
 1373     static <X> List<X> unGroupConcat(String groupConcat, Function<String, X> mapper) {
 
 1374         return StringUtils.isBlank(groupConcat) ? Collections.emptyList()
 
 1375                 : Stream.of(groupConcat.split(
",")) 
 
 1377                         .collect(Collectors.toList());
 
 1397         @NbBundle.Messages({
 
 1398             "# {0} - raw file name",
 
 1399             "# {1} - solr chunk id",
 
 1400             "Accounts.FileWithCCNNode.unallocatedSpaceFile.displayName={0}_chunk_{1}"})
 
 1402             super(Children.LEAF, Lookups.fixed(lookupContents));
 
 1406                     : Bundle.Accounts_FileWithCCNNode_unallocatedSpaceFile_displayName(content.
getName(), StringUtils.substringAfter(key.
getkeywordSearchDocID(), 
"_")); 
 
 1407             setName(fileName + key.
getObjID());
 
 1408             setDisplayName(fileName);
 
 1418             return visitor.
visit(
this);
 
 1423             return getClass().getName();
 
 1427         @NbBundle.Messages({
 
 1428             "Accounts.FileWithCCNNode.nameProperty.displayName=File",
 
 1429             "Accounts.FileWithCCNNode.accountsProperty.displayName=Accounts",
 
 1430             "Accounts.FileWithCCNNode.statusProperty.displayName=Status",
 
 1431             "Accounts.FileWithCCNNode.noDescription=no description"})
 
 1433             Sheet sheet = super.createSheet();
 
 1434             Sheet.Set propSet = sheet.get(Sheet.PROPERTIES);
 
 1435             if (propSet == null) {
 
 1436                 propSet = Sheet.createPropertiesSet();
 
 1440             propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
 
 1441                     Bundle.Accounts_FileWithCCNNode_nameProperty_displayName(),
 
 1442                     Bundle.Accounts_FileWithCCNNode_noDescription(),
 
 1444             propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
 
 1445                     Bundle.Accounts_FileWithCCNNode_accountsProperty_displayName(),
 
 1446                     Bundle.Accounts_FileWithCCNNode_noDescription(),
 
 1448             propSet.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
 
 1449                     Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
 
 1450                     Bundle.Accounts_FileWithCCNNode_noDescription(),
 
 1453                             .collect(Collectors.joining(
", ")))); 
 
 1460             Action[] actions = super.getActions(context);
 
 1461             ArrayList<Action> arrayList = 
new ArrayList<>();
 
 1465                 LOGGER.log(Level.SEVERE, 
"Error gettung content by id", ex);
 
 1468             arrayList.add(approveActionInstance);
 
 1469             arrayList.add(rejectActionInstance);
 
 1470             arrayList.add(null);
 
 1471             arrayList.addAll(Arrays.asList(actions));
 
 1472             return arrayList.toArray(
new Action[arrayList.size()]);
 
 1500                     = 
"SELECT blackboard_artifacts.artifact_obj_id "  
 1501                     + 
" FROM blackboard_artifacts "  
 1502                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "  
 1505                     + 
"     AND blackboard_attributes.value_text >= '" + bin.getBINStart() + 
"' AND  blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) + 
"'"  
 1508                     + 
" ORDER BY blackboard_attributes.value_text"; 
 
 1515                 LOGGER.log(Level.SEVERE, 
"Error querying for account artifacts.", ex); 
 
 1528         if (bin.getBINStart() == bin.getBINEnd()) {
 
 1529             return Integer.toString(bin.getBINStart());
 
 1531             return bin.getBINStart() + 
"-" + StringUtils.difference(bin.getBINStart() + 
"", bin.getBINEnd() + 
"");
 
 1546             updateDisplayName();
 
 1547             this.setIconBaseWithExtension(
"org/sleuthkit/autopsy/images/bank.png");   
 
 1548             reviewStatusBus.register(
this);
 
 1553             updateDisplayName();
 
 1559             updateDisplayName();
 
 1564                     = 
"SELECT count(blackboard_artifacts.artifact_id ) AS count"  
 1565                     + 
" FROM blackboard_artifacts "  
 1566                     + 
"      JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id "  
 1569                     + 
"     AND blackboard_attributes.value_text >= '" + bin.getBINStart() + 
"' AND  blackboard_attributes.value_text < '" + (bin.getBINEnd() + 1) + 
"'"  
 1574                 while (resultSet.next()) {
 
 1575                     setDisplayName(
getBinRangeString(bin) + 
" (" + resultSet.getLong(
"count") + 
")"); 
 
 1578                 LOGGER.log(Level.SEVERE, 
"Error querying for account artifacts.", ex); 
 
 1591             return visitor.
visit(
this);
 
 1596             return getClass().getName();
 
 1600             Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
 
 1601             if (sheetSet == null) {
 
 1602                 sheetSet = Sheet.createPropertiesSet();
 
 1603                 sheet.put(sheetSet);
 
 1609         @NbBundle.Messages({
 
 1610             "Accounts.BINNode.binProperty.displayName=Bank Identifier Number",
 
 1611             "Accounts.BINNode.accountsProperty.displayName=Accounts",
 
 1612             "Accounts.BINNode.cardTypeProperty.displayName=Payment Card Type",
 
 1613             "Accounts.BINNode.schemeProperty.displayName=Credit Card Scheme",
 
 1614             "Accounts.BINNode.brandProperty.displayName=Brand",
 
 1615             "Accounts.BINNode.bankProperty.displayName=Bank",
 
 1616             "Accounts.BINNode.bankCityProperty.displayName=Bank City",
 
 1617             "Accounts.BINNode.bankCountryProperty.displayName=Bank Country",
 
 1618             "Accounts.BINNode.bankPhoneProperty.displayName=Bank Phone #",
 
 1619             "Accounts.BINNode.bankURLProperty.displayName=Bank URL",
 
 1620             "Accounts.BINNode.noDescription=no description"})
 
 1622             Sheet sheet = super.createSheet();
 
 1623             Sheet.Set properties = getPropertySet(sheet);
 
 1625             properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
 
 1626                     Bundle.Accounts_BINNode_binProperty_displayName(),
 
 1627                     Bundle.Accounts_BINNode_noDescription(),
 
 1629             properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
 
 1630                     Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1634             if (bin.hasDetails()) {
 
 1635                 bin.
getCardType().ifPresent(cardType -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_cardTypeProperty_displayName(),
 
 1636                         Bundle.Accounts_BINNode_cardTypeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1638                 bin.
getScheme().ifPresent(scheme -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_schemeProperty_displayName(),
 
 1639                         Bundle.Accounts_BINNode_schemeProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1641                 bin.
getBrand().ifPresent(brand -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_brandProperty_displayName(),
 
 1642                         Bundle.Accounts_BINNode_brandProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1644                 bin.
getBankName().ifPresent(bankName -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankProperty_displayName(),
 
 1645                         Bundle.Accounts_BINNode_bankProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1647                 bin.
getBankCity().ifPresent(bankCity -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCityProperty_displayName(),
 
 1648                         Bundle.Accounts_BINNode_bankCityProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1650                 bin.
getCountry().ifPresent(country -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankCountryProperty_displayName(),
 
 1651                         Bundle.Accounts_BINNode_bankCountryProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1654                         Bundle.Accounts_BINNode_bankPhoneProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1656                 bin.
getBankURL().ifPresent(url -> properties.put(
new NodeProperty<>(Bundle.Accounts_BINNode_bankURLProperty_displayName(),
 
 1657                         Bundle.Accounts_BINNode_bankURLProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
 
 1664             SwingUtilities.invokeLater(() -> {
 
 1665                 this.setSheet(createSheet());
 
 1681             hash = 97 * hash + this.binEnd;
 
 1682             hash = 97 * hash + this.binStart;
 
 1694             if (getClass() != obj.getClass()) {
 
 1698             if (this.binEnd != other.
binEnd) {
 
 1701             if (this.binStart != other.
binStart) {
 
 1718             this.binRange = binRange;
 
 1719             binStart = binRange.getBINstart();
 
 1720             binEnd = binRange.getBINend();
 
 1725             this.binRange = null;
 
 1742         boolean hasDetails() {
 
 1743             return binRange != null;
 
 1797             super(artifact, 
"org/sleuthkit/autopsy/images/credit-card.png");   
 
 1798             this.artifact = artifact;
 
 1799             setName(Long.toString(
this.artifact.getArtifactID()));
 
 1801             reviewStatusBus.register(
this);
 
 1806             List<Action> actionsList = 
new ArrayList<>();
 
 1807             actionsList.addAll(Arrays.asList(super.getActions(context)));
 
 1809             actionsList.add(approveActionInstance);
 
 1810             actionsList.add(rejectActionInstance);
 
 1812             return actionsList.toArray(
new Action[actionsList.size()]);
 
 1817             Sheet sheet = super.createSheet();
 
 1818             Sheet.Set properties = sheet.get(Sheet.PROPERTIES);
 
 1819             if (properties == null) {
 
 1820                 properties = Sheet.createPropertiesSet();
 
 1821                 sheet.put(properties);
 
 1823             properties.put(
new NodeProperty<>(Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
 
 1824                     Bundle.Accounts_FileWithCCNNode_statusProperty_displayName(),
 
 1825                     Bundle.Accounts_FileWithCCNNode_noDescription(),
 
 1835             event.artifacts.stream().filter((art) -> (art.getArtifactID() == this.artifact.
getArtifactID())).map((_item) -> {
 
 1837             }).forEachOrdered((_item) -> {
 
 1843             SwingUtilities.invokeLater(() -> {
 
 1844                 this.setSheet(createSheet());
 
 1853         @NbBundle.Messages(
"ToggleShowRejected.name=Show Rejected Results")
 
 1855             super(Bundle.ToggleShowRejected_name());
 
 1881             this.newStatus = newStatus;
 
 1892             List<String[]> selectedPaths = Utilities.actionsGlobalContext().lookupAll(Node.class).stream()
 
 1894                         String[] createPath;
 
 1901                             List<Node> siblings = Arrays.asList(node.getParentNode().getChildren().getNodes());
 
 1902                             if (siblings.size() > 1) {
 
 1903                                 int indexOf = siblings.indexOf(node);
 
 1905                                 Node sibling = indexOf > 0
 
 1906                                         ? siblings.get(indexOf - 1)
 
 1907                                         : siblings.get(Integer.max(indexOf + 1, siblings.size() - 1));
 
 1908                                 createPath = NodeOp.createPath(sibling, null);
 
 1918                             createPath = NodeOp.createPath(node, null);
 
 1921                         return Arrays.copyOfRange(createPath, 1, createPath.length);
 
 1923                     .filter(Objects::nonNull)
 
 1924                     .collect(Collectors.toList());
 
 1927             final Collection<? extends BlackboardArtifact> artifacts = Utilities.actionsGlobalContext().lookupAll(
BlackboardArtifact.class);
 
 1928             artifacts.forEach(artifact -> {
 
 1932                     LOGGER.log(Level.SEVERE, 
"Error changing artifact review status.", ex); 
 
 1936             reviewStatusBus.post(
new ReviewStatusChangeEvent(artifacts, newStatus));
 
 1938             final DataResultTopComponent directoryListing = DirectoryTreeTopComponent.findInstance().getDirectoryListing();
 
 1939             final Node rootNode = directoryListing.getRootNode();
 
 1942             List<Node> toArray = 
new ArrayList<>();
 
 1943             selectedPaths.forEach(path -> {
 
 1945                     toArray.add(NodeOp.findPath(rootNode, path));
 
 1946                 } 
catch (NodeNotFoundException ex) { 
 
 1951             directoryListing.setSelectedNodes(toArray.toArray(
new Node[toArray.size()]));
 
 1957         @NbBundle.Messages({
"ApproveAccountsAction.name=Approve Accounts"})
 
 1965         @NbBundle.Messages({
"RejectAccountsAction.name=Reject Accounts"})
 
 1973         Collection<? extends BlackboardArtifact> artifacts;
 
 1977             this.artifacts = artifacts;
 
 1978             this.newReviewStatus = newReviewStatus;
 
 1990             return ICON_BASE_PATH + 
"credit-card.png";
 
 1992             return ICON_BASE_PATH + 
"image.png";
 
 1994             return ICON_BASE_PATH + 
"email.png";
 
 1996             return ICON_BASE_PATH + 
"facebook.png";
 
 1998             return ICON_BASE_PATH + 
"instagram.png";
 
 2000             return ICON_BASE_PATH + 
"messaging.png";
 
 2002             return ICON_BASE_PATH + 
"phone.png";
 
 2004             return ICON_BASE_PATH + 
"twitter.png";
 
 2006             return ICON_BASE_PATH + 
"web-file.png";
 
 2008             return ICON_BASE_PATH + 
"WhatsApp.png";
 
 2011             return ICON_BASE_PATH + 
"face.png";
 
CreditCardNumberFactory(BinResult bin)
 
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
 
final BlackboardArtifact.ReviewStatus newStatus
 
final PropertyChangeListener weakPcl
 
boolean createKeys(List< CreditCardViewMode > list)
 
DefaultAccountFactory(Account.Type accountType)
 
BlackboardArtifact.Type getBlackboardArtifactType()
 
void removeIngestModuleEventListener(final PropertyChangeListener listener)
 
static final Account.Type INSTAGRAM
 
Optional< Integer > getNumberLength()
 
Node[] createNodesForKey(Long t)
 
Optional< String > getCountry()
 
CommunicationsManager getCommunicationsManager()
 
static final Account.Type MESSAGING_APP
 
final BlackboardArtifact artifact
 
static synchronized IngestManager getInstance()
 
String getBinRangeString(BinResult bin)
 
static final Logger LOGGER
 
Node[] createNodesForKey(BinResult key)
 
Optional< String > getBankPhoneNumber()
 
Set< BlackboardArtifact.ReviewStatus > getStatuses()
 
static final Type TSK_ACCOUNT_TYPE
 
void setShowRejected(boolean showRejected)
 
Optional< String > getCountry()
 
Sheet.Set getPropertySet(Sheet sheet)
 
Blackboard getBlackboard()
 
Optional< String > getBankCity()
 
final String keywordSearchDocID
 
static List< Action > getActions(File file, boolean isArtifactSource)
 
Optional< String > getBankName()
 
final EventBus reviewStatusBus
 
String getRejectedArtifactFilterClause()
 
static final Account.Type WHATSAPP
 
Node[] createNodesForKey(DataArtifact artifact)
 
org.sleuthkit.datamodel.Account.Type getAccountType(String accountTypeName)
 
boolean createKeys(List< DataArtifact > list)
 
DataArtifact getDataArtifactById(long artifactObjId)
 
static final Account.Type FACEBOOK
 
final PropertyChangeListener weakPcl
 
final RejectAccounts rejectActionInstance
 
final Account.Type accountType
 
List< Long > getArtifactIDs()
 
boolean createKeys(List< String > list)
 
Content getContentById(long id)
 
abstract boolean createKeys(List< X > list)
 
AccountArtifactNode(BlackboardArtifact artifact)
 
static synchronized BankIdentificationNumber getBINInfo(int bin)
 
Node[] getNodeArr(Node node)
 
TSK_KEYWORD_SEARCH_DOCUMENT_ID
 
Action[] getActions(boolean context)
 
Node[] createNodesForKey(FileWithCCN key)
 
static String getIconFilePath(Account.Type type)
 
boolean createKeys(List< FileWithCCN > list)
 
Node[] createNodesForKey(String accountTypeName)
 
final Account.Type accountType
 
ReviewStatus getReviewStatus()
 
Optional< String > getBankURL()
 
boolean createKeys(List< Long > list)
 
final Map< String, Long > counts
 
final ApproveAccounts approveActionInstance
 
BlackboardArtifact getBlackboardArtifact(long artifactID)
 
final long filteringDSObjId
 
Node[] createNodesForKey(CreditCardViewMode key)
 
static final Account.Type PHONE
 
AbstractFile getAbstractFileById(long id)
 
long fetchChildCount(SleuthkitCase skCase)
 
void removeIngestJobEventListener(final PropertyChangeListener listener)
 
Optional< String > getScheme()
 
final Set< BlackboardArtifact.ReviewStatus > statuses
 
Optional< String > getBrand()
 
static final String DISPLAY_NAME
 
boolean equals(Object obj)
 
CreditCardNumberAccountTypeNode()
 
void addIngestJobEventListener(final PropertyChangeListener listener)
 
static final Type TSK_ACCOUNT
 
static final Account.Type WEBSITE
 
DefaultAccountTypeNode(Account.Type accountType)
 
Optional< String > getBankURL()
 
String getkeywordSearchDocID()
 
static final Account.Type CREDIT_CARD
 
boolean equals(Object obj)
 
Optional< Integer > getNumberLength()
 
BinResult(long count,@Nonnull BINRange binRange)
 
Action newToggleShowRejectedAction()
 
Optional< String > getBrand()
 
static final Account.Type TWITTER
 
SleuthkitCase getSleuthkitCase()
 
FileWithCCNNode(FileWithCCN key, Content content, Object[] lookupContents)
 
Action[] getActions(boolean context)
 
final List< Long > artifactIDs
 
T visit(DataSourceFilesNode in)
 
void actionPerformed(ActionEvent e)
 
boolean createKeys(List< BinResult > list)
 
FileWithCCN(AbstractFile file, long objID, String solrDocID, List< Long > artifactIDs, long hits, Set< BlackboardArtifact.ReviewStatus > statuses)
 
Optional< String > getBankCity()
 
Optional< String > getCardType()
 
final FileWithCCN fileKey
 
BinResult(long count, int start, int end)
 
void addIngestModuleEventListener(final PropertyChangeListener listener)
 
synchronized static Logger getLogger(String name)
 
static Case getCurrentCaseThrows()
 
final PropertyChangeListener pcl
 
void setReviewStatus(ReviewStatus newStatus)
 
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
 
final AccountTypeResults accountTypeResults
 
static final Account.Type DEVICE
 
boolean equals(Object obj)
 
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
 
ReviewStatusAction(String displayName, BlackboardArtifact.ReviewStatus newStatus)
 
static final String ICON_BASE_PATH
 
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
 
void actionPerformed(ActionEvent e)
 
String getFilterByDataSourceClause()
 
static ReviewStatus withID(int id)
 
static final Account.Type EMAIL
 
Optional< String > getScheme()
 
Optional< String > getBankName()
 
Optional< String > getBankPhoneNumber()
 
CaseDbQuery executeQuery(String query)
 
Optional< String > getCardType()