mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 11:07:43 +00:00
rewire explorermanagers and views to support multiple selection on account table.
This commit is contained in:
parent
d961ea6062
commit
0630f46897
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017 Basis Technology Corp.
|
||||
* Copyright 2017-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -19,23 +19,30 @@
|
||||
package org.sleuthkit.autopsy.communications;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Key for AccountDeviceInstance node.
|
||||
*
|
||||
* Encapsulates a AccountDeviceInstance, and CommunicationsFilter.
|
||||
* Encapsulates a AccountDeviceInstanc,some meta data about it, and
|
||||
* CommunicationsFilter.
|
||||
*/
|
||||
class AccountDeviceInstanceKey {
|
||||
final class AccountDeviceInstanceKey {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AccountDeviceInstanceKey.class.getName());
|
||||
|
||||
private final AccountDeviceInstance accountDeviceInstance;
|
||||
private final CommunicationsFilter filter;
|
||||
private final long messageCount;
|
||||
private final String dataSourceName;
|
||||
|
||||
|
||||
|
||||
AccountDeviceInstanceKey(AccountDeviceInstance accountDeviceInstance, CommunicationsFilter filter, long msgCount, String dataSourceName) {
|
||||
this.accountDeviceInstance = accountDeviceInstance;
|
||||
this.filter = filter;
|
||||
@ -43,6 +50,13 @@ class AccountDeviceInstanceKey {
|
||||
this.dataSourceName = dataSourceName;
|
||||
}
|
||||
|
||||
AccountDeviceInstanceKey(AccountDeviceInstance accountDeviceInstance, CommunicationsFilter filter, long msgCount) {
|
||||
this.accountDeviceInstance = accountDeviceInstance;
|
||||
this.filter = filter;
|
||||
this.messageCount = msgCount;
|
||||
this.dataSourceName = getDataSourceName(accountDeviceInstance, Case.getCurrentCase().getSleuthkitCase());
|
||||
}
|
||||
|
||||
AccountDeviceInstance getAccountDeviceInstance() {
|
||||
return accountDeviceInstance;
|
||||
}
|
||||
@ -54,7 +68,7 @@ class AccountDeviceInstanceKey {
|
||||
long getMessageCount() {
|
||||
return messageCount;
|
||||
}
|
||||
|
||||
|
||||
String getDataSourceName() {
|
||||
return dataSourceName;
|
||||
}
|
||||
@ -96,5 +110,17 @@ class AccountDeviceInstanceKey {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static String getDataSourceName(AccountDeviceInstance accountDeviceInstance, SleuthkitCase db) {
|
||||
try {
|
||||
for (DataSource dataSource : db.getDataSources()) {
|
||||
if (dataSource.getDeviceId().equals(accountDeviceInstance.getDeviceId())) {
|
||||
return db.getContentById(dataSource.getId()).getName();
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting datasource name, falling back on device ID.", ex);
|
||||
}
|
||||
return accountDeviceInstance.getDeviceId();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.communications;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
|
||||
/**
|
||||
* Node to represent an Account Device Instance in the CVT
|
||||
*/
|
||||
final class AccountDeviceInstanceNode extends AbstractNode {
|
||||
|
||||
private final AccountDeviceInstanceKey accountDeviceInstanceKey;
|
||||
private final CommunicationsManager commsManager;
|
||||
private final Account account;
|
||||
|
||||
AccountDeviceInstanceNode(AccountDeviceInstanceKey accountDeviceInstanceKey, CommunicationsManager commsManager) {
|
||||
super(Children.LEAF, Lookups.fixed(accountDeviceInstanceKey, commsManager));
|
||||
this.accountDeviceInstanceKey = accountDeviceInstanceKey;
|
||||
this.commsManager = commsManager;
|
||||
this.account = accountDeviceInstanceKey.getAccountDeviceInstance().getAccount();
|
||||
setName(account.getTypeSpecificID());
|
||||
setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + Utils.getIconFileName(account.getAccountType()));
|
||||
}
|
||||
|
||||
public AccountDeviceInstance getAccountDeviceInstance() {
|
||||
return accountDeviceInstanceKey.getAccountDeviceInstance();
|
||||
}
|
||||
|
||||
public AccountDeviceInstanceKey getAccountDeviceInstanceKey() {
|
||||
return accountDeviceInstanceKey;
|
||||
}
|
||||
|
||||
public CommunicationsManager getCommsManager() {
|
||||
return commsManager;
|
||||
}
|
||||
|
||||
public long getMessageCount() {
|
||||
return accountDeviceInstanceKey.getMessageCount();
|
||||
}
|
||||
|
||||
public CommunicationsFilter getFilter() {
|
||||
return accountDeviceInstanceKey.getCommunicationsFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages(value = {"AccountNode.device=Device", "AccountNode.accountName=Account", "AccountNode.accountType=Type", "AccountNode.messageCount=Msgs"})
|
||||
protected Sheet createSheet() {
|
||||
Sheet s = super.createSheet();
|
||||
Sheet.Set properties = s.get(Sheet.PROPERTIES);
|
||||
if (properties == null) {
|
||||
properties = Sheet.createPropertiesSet();
|
||||
s.put(properties);
|
||||
}
|
||||
properties.put(new NodeProperty<>("type",
|
||||
Bundle.AccountNode_accountType(),
|
||||
"type",
|
||||
account.getAccountType().getDisplayName())); // NON-NLS
|
||||
properties.put(new NodeProperty<>("count",
|
||||
Bundle.AccountNode_messageCount(),
|
||||
"count",
|
||||
accountDeviceInstanceKey.getMessageCount())); // NON-NLS
|
||||
properties.put(new NodeProperty<>("device",
|
||||
Bundle.AccountNode_device(),
|
||||
"device",
|
||||
accountDeviceInstanceKey.getDataSourceName())); // NON-NLS
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action[] getActions(boolean context) {
|
||||
ArrayList<Action> actions = new ArrayList<>(Arrays.asList(super.getActions(context)));
|
||||
actions.add(PinAccountsAction.getInstance());
|
||||
return actions.toArray(new Action[actions.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action that pins the selected AccountDeviceInstances to the
|
||||
* visualization.
|
||||
*/
|
||||
static private class PinAccountsAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static PinAccountsAction instance = new PinAccountsAction();
|
||||
|
||||
private static PinAccountsAction getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private PinAccountsAction() {
|
||||
super("Visualize Account");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Collection<? extends AccountDeviceInstanceKey> lookupAll =
|
||||
Utilities.actionsGlobalContext().lookupAll(AccountDeviceInstanceKey.class);
|
||||
CVTEvents.getCVTEventBus().post(new PinAccountEvent(lookupAll));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.communications;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* ChildFactory that creates AccountDeviceInstanceKeys and
|
||||
* AccountDeviceInstanceNodes using a provided CommunicationsManager and
|
||||
* CommunicationsFilter
|
||||
*/
|
||||
final class AccountDeviceInstanceNodeFactory extends ChildFactory<AccountDeviceInstanceKey> {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AccountDeviceInstanceNodeFactory.class.getName());
|
||||
|
||||
private final CommunicationsManager commsManager;
|
||||
private final CommunicationsFilter commsFilter;
|
||||
|
||||
AccountDeviceInstanceNodeFactory(CommunicationsManager commsManager, CommunicationsFilter commsFilter) {
|
||||
this.commsManager = commsManager;
|
||||
this.commsFilter = commsFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<AccountDeviceInstanceKey> list) {
|
||||
List<AccountDeviceInstanceKey> accountDeviceInstanceKeys = new ArrayList<>();
|
||||
try {
|
||||
final List<AccountDeviceInstance> accountDeviceInstancesWithRelationships =
|
||||
commsManager.getAccountDeviceInstancesWithRelationships(commsFilter);
|
||||
for (AccountDeviceInstance accountDeviceInstance : accountDeviceInstancesWithRelationships) {
|
||||
long communicationsCount = commsManager.getRelationshipSourcesCount(accountDeviceInstance, commsFilter);
|
||||
accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(accountDeviceInstance, commsFilter, communicationsCount));
|
||||
};
|
||||
} catch (TskCoreException tskCoreException) {
|
||||
logger.log(Level.SEVERE, "Error getting filtered account device instances", tskCoreException);
|
||||
}
|
||||
list.addAll(accountDeviceInstanceKeys);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(AccountDeviceInstanceKey key) {
|
||||
return new AccountDeviceInstanceNode(key, commsManager);
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-76,0,0,2,68"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017 Basis Technology Corp.
|
||||
* Copyright 2017-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -26,22 +26,34 @@ import javax.swing.table.TableCellRenderer;
|
||||
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||
import org.netbeans.swing.outline.Outline;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.explorer.ExplorerUtils;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.lookup.ProxyLookup;
|
||||
|
||||
/**
|
||||
* A panel that goes in the Browse tab of the Communications Visualization Tool.
|
||||
* Hosts an OutlineView that shows information about Accounts.
|
||||
* Hosts an OutlineView that shows information about Accounts, and a
|
||||
* MessageBrowser for viewing details of communications.
|
||||
*
|
||||
* The Lookup provided by getLookup will be proxied by the lookup of the
|
||||
* CVTTopComponent when this tab is active allowing for context sensitive
|
||||
* actions to work correctly.
|
||||
*/
|
||||
public class AccountsBrowser extends JPanel implements ExplorerManager.Provider, CVTTopComponent.ProxiedExplorerManagerProvider {
|
||||
public class AccountsBrowser extends JPanel implements ExplorerManager.Provider, Lookup.Provider {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Outline outline;
|
||||
private final ExplorerManager gacEM = new ExplorerManager();
|
||||
private ExplorerManager tableEM;
|
||||
|
||||
/**
|
||||
* Creates new form AccountsBrowser
|
||||
private final ExplorerManager messageBrowserEM = new ExplorerManager();
|
||||
private ExplorerManager accountsTableEM;
|
||||
|
||||
/*
|
||||
* This lookup proxies the selection lookup of both he accounts table and
|
||||
* the messages table.
|
||||
*/
|
||||
private ProxyLookup proxyLookup;
|
||||
|
||||
public AccountsBrowser() {
|
||||
initComponents();
|
||||
outline = outlineView.getOutline();
|
||||
@ -59,7 +71,7 @@ public class AccountsBrowser extends JPanel implements ExplorerManager.Provider,
|
||||
}
|
||||
|
||||
void init(ExplorerManager tableExplorerManager) {
|
||||
this.tableEM = tableExplorerManager;
|
||||
this.accountsTableEM = tableExplorerManager;
|
||||
tableExplorerManager.addPropertyChangeListener(evt -> {
|
||||
if (ExplorerManager.PROP_ROOT_CONTEXT.equals(evt.getPropertyName())) {
|
||||
SwingUtilities.invokeLater(this::setColumnWidths);
|
||||
@ -68,7 +80,11 @@ public class AccountsBrowser extends JPanel implements ExplorerManager.Provider,
|
||||
}
|
||||
});
|
||||
|
||||
jSplitPane1.setRightComponent(new MessageBrowser(tableExplorerManager, gacEM));
|
||||
jSplitPane1.setRightComponent(new MessageBrowser(tableExplorerManager, messageBrowserEM));
|
||||
|
||||
proxyLookup = new ProxyLookup(
|
||||
ExplorerUtils.createLookup(messageBrowserEM, getActionMap()),
|
||||
ExplorerUtils.createLookup(accountsTableEM, getActionMap()));
|
||||
}
|
||||
|
||||
private void setColumnWidths() {
|
||||
@ -122,11 +138,11 @@ public class AccountsBrowser extends JPanel implements ExplorerManager.Provider,
|
||||
|
||||
@Override
|
||||
public ExplorerManager getExplorerManager() {
|
||||
return tableEM;
|
||||
return accountsTableEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExplorerManager getProxiedExplorerManager() {
|
||||
return gacEM;
|
||||
public Lookup getLookup() {
|
||||
return proxyLookup;
|
||||
}
|
||||
}
|
||||
|
@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.communications;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
class AccountsRootChildren extends ChildFactory<AccountDeviceInstanceKey> {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AccountsRootChildren.class.getName());
|
||||
|
||||
private final CommunicationsManager commsManager;
|
||||
private final CommunicationsFilter commsFilter;
|
||||
|
||||
AccountsRootChildren(CommunicationsManager commsManager, CommunicationsFilter commsFilter) {
|
||||
super();
|
||||
this.commsManager = commsManager;
|
||||
this.commsFilter = commsFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<AccountDeviceInstanceKey> list) {
|
||||
List<AccountDeviceInstanceKey> accountDeviceInstanceKeys = new ArrayList<>();
|
||||
try {
|
||||
for (AccountDeviceInstance accountDeviceInstance : commsManager.getAccountDeviceInstancesWithRelationships(commsFilter)) {
|
||||
long communicationsCount = commsManager.getRelationshipSourcesCount(accountDeviceInstance, commsFilter);
|
||||
String dataSourceName = getDataSourceName(accountDeviceInstance);
|
||||
accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(accountDeviceInstance, commsFilter, communicationsCount, dataSourceName));
|
||||
};
|
||||
} catch (TskCoreException tskCoreException) {
|
||||
logger.log(Level.SEVERE, "Error getting filtered account device instances", tskCoreException);
|
||||
}
|
||||
list.addAll(accountDeviceInstanceKeys);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(AccountDeviceInstanceKey key) {
|
||||
return new AccountDeviceInstanceNode(key, commsManager);
|
||||
}
|
||||
|
||||
static String getDataSourceName(AccountDeviceInstance accountDeviceInstance) {
|
||||
try {
|
||||
final SleuthkitCase sleuthkitCase = Case.getCurrentCase().getSleuthkitCase();
|
||||
for (DataSource dataSource : sleuthkitCase.getDataSources()) {
|
||||
if (dataSource.getDeviceId().equals(accountDeviceInstance.getDeviceId())) {
|
||||
return sleuthkitCase.getContentById(dataSource.getId()).getName();
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting datasource name, falling back on device ID.", ex);
|
||||
}
|
||||
return accountDeviceInstance.getDeviceId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Node to represent an Account in the AccountsBrowser
|
||||
*/
|
||||
static class AccountDeviceInstanceNode extends AbstractNode {
|
||||
|
||||
private final AccountDeviceInstanceKey accountDeviceInstanceKey;
|
||||
|
||||
private final CommunicationsManager commsManager;
|
||||
private final Account account;
|
||||
|
||||
AccountDeviceInstanceNode(AccountDeviceInstanceKey accountDeviceInstanceKey, CommunicationsManager commsManager) {
|
||||
super(Children.LEAF, Lookups.fixed(accountDeviceInstanceKey, commsManager));
|
||||
this.accountDeviceInstanceKey = accountDeviceInstanceKey;
|
||||
this.commsManager = commsManager;
|
||||
this.account = accountDeviceInstanceKey.getAccountDeviceInstance().getAccount();
|
||||
setName(account.getTypeSpecificID());
|
||||
setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + Utils.getIconFileName(account.getAccountType()));
|
||||
}
|
||||
|
||||
public AccountDeviceInstance getAccountDeviceInstance() {
|
||||
return accountDeviceInstanceKey.getAccountDeviceInstance();
|
||||
}
|
||||
|
||||
public AccountDeviceInstanceKey getAccountDeviceInstanceKey() {
|
||||
return accountDeviceInstanceKey;
|
||||
}
|
||||
|
||||
public CommunicationsManager getCommsManager() {
|
||||
return commsManager;
|
||||
}
|
||||
|
||||
public long getMessageCount() {
|
||||
return accountDeviceInstanceKey.getMessageCount();
|
||||
}
|
||||
|
||||
public CommunicationsFilter getFilter() {
|
||||
return accountDeviceInstanceKey.getCommunicationsFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages(value = {"AccountNode.device=Device",
|
||||
"AccountNode.accountName=Account",
|
||||
"AccountNode.accountType=Type",
|
||||
"AccountNode.messageCount=Msgs"})
|
||||
protected Sheet createSheet() {
|
||||
Sheet s = super.createSheet();
|
||||
Sheet.Set properties = s.get(Sheet.PROPERTIES);
|
||||
if (properties == null) {
|
||||
properties = Sheet.createPropertiesSet();
|
||||
s.put(properties);
|
||||
}
|
||||
|
||||
properties.put(new NodeProperty<>("type", Bundle.AccountNode_accountType(), "type",
|
||||
account.getAccountType().getDisplayName())); // NON-NLS
|
||||
properties.put(new NodeProperty<>("count", Bundle.AccountNode_messageCount(), "count",
|
||||
accountDeviceInstanceKey.getMessageCount())); // NON-NLS
|
||||
properties.put(new NodeProperty<>("device", Bundle.AccountNode_device(), "device",
|
||||
accountDeviceInstanceKey.getDataSourceName())); // NON-NLS
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action[] getActions(boolean context) {
|
||||
ArrayList<Action> actions = new ArrayList<>(Arrays.asList(super.getActions(context)));
|
||||
actions.add(new PinAccountAction());
|
||||
return actions.toArray(new Action[actions.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private class PinAccountAction extends AbstractAction {
|
||||
|
||||
public PinAccountAction() {
|
||||
super("Visualize Account");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CVTEvents.getCVTEventBus().post(new PinAccountEvent(AccountDeviceInstanceNode.this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +1,34 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.communications;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
*
|
||||
* Provide he singleton EventBus.
|
||||
*/
|
||||
public class CVTEvents {
|
||||
final class CVTEvents {
|
||||
|
||||
private final static EventBus cvtEventBus = new EventBus();
|
||||
private final static EventBus cvtEventBus = new EventBus();
|
||||
|
||||
public static EventBus getCVTEventBus() {
|
||||
return cvtEventBus;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017 Basis Technology Corp.
|
||||
* Copyright 2017-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -22,7 +22,6 @@ import com.google.common.eventbus.Subscribe;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import static org.openide.explorer.ExplorerUtils.createLookup;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ProxyLookup;
|
||||
@ -48,35 +47,29 @@ public final class CVTTopComponent extends TopComponent {
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
public CVTTopComponent() {
|
||||
initComponents();
|
||||
filtersPane.setExplorerManager(filterToTableEXplorerManager);
|
||||
setName(Bundle.CVTTopComponent_name());
|
||||
/*
|
||||
* Connect the filtersPane and the accountsBrowser via a shared
|
||||
* ExplorerMmanager
|
||||
*/
|
||||
filtersPane.setExplorerManager(filterToTableEXplorerManager);
|
||||
accountsBrowser.init(filterToTableEXplorerManager);
|
||||
|
||||
|
||||
/*
|
||||
* Associate an explorer manager with the GlobalActionContext (GAC) for
|
||||
* use by the messages browsers so that selections in the messages
|
||||
* browser can be exposed to context-sensitive actions.
|
||||
* Associate an Lookup with the GlobalActionContext (GAC) so that
|
||||
* selections in the sub views can be exposed to context-sensitive
|
||||
* actions.
|
||||
*/
|
||||
// ExplorerManager browserExplorerManager = new ExplorerManager();
|
||||
// ExplorerManager vizExplorerManager = new ExplorerManager();
|
||||
ProxyLookupImpl proxyLookup = new ProxyLookupImpl();
|
||||
ProxyLookupImpl proxyLookup = new ProxyLookupImpl(accountsBrowser.getLookup());
|
||||
associateLookup(proxyLookup);
|
||||
accountsBrowser.init(filterToTableEXplorerManager);
|
||||
// browseSplitPane.setRightComponent(new MessageBrowser(browserExplorerManager));
|
||||
// vizSplitPane.setRightComponent(new MessageBrowser(vizExplorerManager));
|
||||
// /*
|
||||
// * Create a second explorer manager to be discovered by the accounts
|
||||
// * browser and the message browser so that the browsers can both listen
|
||||
// * for explorer manager property events for the outline view of the
|
||||
// * accounts browser. This provides a mechanism for pushing selected
|
||||
// * Nodes from the accounts browser to the messages browser.
|
||||
// */
|
||||
// acctsBrowserExplorerManager = new ExplorerManager();
|
||||
|
||||
// Make sure the GAC is proxying the selection of the active tab.
|
||||
browseVisualizeTabPane.addChangeListener(changeEvent -> {
|
||||
ProxiedExplorerManagerProvider selectedComponent = (ProxiedExplorerManagerProvider) browseVisualizeTabPane.getSelectedComponent();
|
||||
proxyLookup.changeLookup(createLookup(selectedComponent.getProxiedExplorerManager(), getActionMap()));
|
||||
Lookup.Provider selectedComponent = (Lookup.Provider) browseVisualizeTabPane.getSelectedComponent();
|
||||
proxyLookup.changeLookups(selectedComponent.getLookup());
|
||||
});
|
||||
|
||||
vizPanel.setFilterProvider(filtersPane);
|
||||
CVTEvents.getCVTEventBus().register(this);
|
||||
|
||||
}
|
||||
@ -169,16 +162,12 @@ public final class CVTTopComponent extends TopComponent {
|
||||
|
||||
private static class ProxyLookupImpl extends ProxyLookup {
|
||||
|
||||
ProxyLookupImpl() {
|
||||
ProxyLookupImpl(Lookup... l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
void changeLookup(Lookup l) {
|
||||
void changeLookups(Lookup... l) {
|
||||
setLookups(l);
|
||||
}
|
||||
}
|
||||
|
||||
static interface ProxiedExplorerManagerProvider {
|
||||
|
||||
ExplorerManager getProxiedExplorerManager();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2018 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.communications;
|
||||
|
||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||
|
||||
interface FilterProvider {
|
||||
|
||||
CommunicationsFilter getFilter();
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017 Basis Technology Corp.
|
||||
* Copyright 2017-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -57,13 +57,13 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Panel that holds the Filter control widgets and translates user filtering
|
||||
* changes into queries against the CommunicationsManager.
|
||||
* Panel that holds the Filter control widgets and triggers queries against the
|
||||
* CommunicationsManager on user filtering changes.
|
||||
*/
|
||||
final public class FiltersPanel extends JPanel {
|
||||
final public class FiltersPanel extends JPanel implements FilterProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName());
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(FiltersPanel.class.getName());
|
||||
|
||||
private ExplorerManager em;
|
||||
|
||||
@ -134,6 +134,10 @@ final public class FiltersPanel extends JPanel {
|
||||
refreshButton.addActionListener(e -> applyFilters());
|
||||
}
|
||||
|
||||
void setExplorerManager(ExplorerManager explorerManager) {
|
||||
em = explorerManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that filters are in a consistent state and will result in some
|
||||
* results. Checks that at least one device and at least one account type is
|
||||
@ -166,6 +170,9 @@ final public class FiltersPanel extends JPanel {
|
||||
dateRangeLabel.setText("Date Range ( " + Utils.getUserPreferredZoneId().toString() + "):");
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the filter widgets to reflect he data sources/types in the case.
|
||||
*/
|
||||
private void updateFilters() {
|
||||
updateAccountTypeFilter();
|
||||
updateDeviceFilter();
|
||||
@ -176,6 +183,7 @@ final public class FiltersPanel extends JPanel {
|
||||
super.addNotify();
|
||||
IngestManager.getInstance().addIngestModuleEventListener(ingestListener);
|
||||
Case.addEventTypeSubscriber(EnumSet.of(CURRENT_CASE), evt -> {
|
||||
//clear the device filter widget when the case changes.
|
||||
devicesMap.clear();
|
||||
devicesPane.removeAll();
|
||||
});
|
||||
@ -482,20 +490,17 @@ final public class FiltersPanel extends JPanel {
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
/**
|
||||
* Query for accounts using the selected filters, and send the results to
|
||||
* the AccountsBrowser via the ExplorerManager.
|
||||
* Push a new root AccountDeviceInstanceNodeFactory with he current filters
|
||||
* into the explorer manager. The factory will do he actual queries.
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void applyFilters() {
|
||||
CommunicationsFilter commsFilter = new CommunicationsFilter();
|
||||
commsFilter.addAndFilter(getDeviceFilter());
|
||||
commsFilter.addAndFilter(getAccountTypeFilter());
|
||||
commsFilter.addAndFilter(getDateRangeFilter());
|
||||
commsFilter.addAndFilter(new CommunicationsFilter.RelationshipTypeFilter(
|
||||
ImmutableSet.of(CALL_LOG, MESSAGE)));
|
||||
CommunicationsFilter commsFilter = getFilter();
|
||||
|
||||
try {
|
||||
final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
|
||||
em.setRootContext(new AbstractNode(Children.create(new AccountsRootChildren(commsManager, commsFilter), true)));
|
||||
em.setRootContext(new AbstractNode(Children.create(new AccountDeviceInstanceNodeFactory(commsManager, commsFilter), true)));
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "There was an error getting the CommunicationsManager for the current case.", ex);
|
||||
}
|
||||
@ -504,6 +509,17 @@ final public class FiltersPanel extends JPanel {
|
||||
validateFilters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommunicationsFilter getFilter() {
|
||||
CommunicationsFilter commsFilter = new CommunicationsFilter();
|
||||
commsFilter.addAndFilter(getDeviceFilter());
|
||||
commsFilter.addAndFilter(getAccountTypeFilter());
|
||||
commsFilter.addAndFilter(getDateRangeFilter());
|
||||
commsFilter.addAndFilter(new CommunicationsFilter.RelationshipTypeFilter(
|
||||
ImmutableSet.of(CALL_LOG, MESSAGE)));
|
||||
return commsFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a DeviceFilter that matches the state of the UI widgets.
|
||||
*
|
||||
@ -532,6 +548,11 @@ final public class FiltersPanel extends JPanel {
|
||||
return accountTypeFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an DateRangeFilter that matches the state of the UI widgets
|
||||
*
|
||||
* @return an DateRangeFilter
|
||||
*/
|
||||
private DateRangeFilter getDateRangeFilter() {
|
||||
ZoneId zone = Utils.getUserPreferredZoneId();
|
||||
long start = startDatePicker.isEnabled() ? startDatePicker.getDate().atStartOfDay(zone).toEpochSecond() : 0;
|
||||
@ -622,7 +643,4 @@ final public class FiltersPanel extends JPanel {
|
||||
private final javax.swing.JButton unCheckAllDevicesButton = new javax.swing.JButton();
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
void setExplorerManager(ExplorerManager explorerManager) {
|
||||
em = explorerManager;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2017 Basis Technology Corp.
|
||||
* Copyright 2017-18 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -25,7 +25,6 @@ import java.util.stream.Stream;
|
||||
import javax.swing.JPanel;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.nodes.Node;
|
||||
import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
|
||||
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
|
||||
@ -50,6 +49,8 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
||||
* Constructs the right hand side of the Communications Visualization Tool
|
||||
* (CVT).
|
||||
*
|
||||
* @param tableEM An explorer manager to listen to as the driver
|
||||
* of the Message Table.
|
||||
* @param gacExplorerManager An explorer manager associated with the
|
||||
* GlobalActionsContext (GAC) so that selections
|
||||
* in the messages browser can be exposed to
|
||||
@ -63,11 +64,9 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
||||
messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, messageDataContent);
|
||||
splitPane.setTopComponent(messagesResultPanel);
|
||||
splitPane.setBottomComponent(messageDataContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
dataResultViewerTable = new DataResultViewerTable(gacExplorerManager, "Messages");
|
||||
messagesResultPanel.addResultViewer(dataResultViewerTable);
|
||||
messagesResultPanel.open();
|
||||
|
||||
tableEM.addPropertyChangeListener(pce -> {
|
||||
if (pce.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) {
|
||||
@ -107,13 +106,11 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//add the required result viewers and THEN open the panel
|
||||
if (null == dataResultViewerTable) {
|
||||
dataResultViewerTable = new DataResultViewerTable(gacExplorerManager, "Messages");
|
||||
messagesResultPanel.addResultViewer(dataResultViewerTable);
|
||||
}
|
||||
messagesResultPanel.open();
|
||||
@Override
|
||||
public ExplorerManager getExplorerManager() {
|
||||
return gacExplorerManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,8 +154,4 @@ public final class MessageBrowser extends JPanel implements ExplorerManager.Prov
|
||||
private javax.swing.JSplitPane splitPane;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
public ExplorerManager getExplorerManager() {
|
||||
return gacExplorerManager;
|
||||
}
|
||||
}
|
||||
|
@ -5,20 +5,21 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.communications;
|
||||
|
||||
import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class PinAccountEvent {
|
||||
|
||||
private final AccountDeviceInstanceNode accountDeviceInstance;
|
||||
private final ImmutableSet<AccountDeviceInstanceKey> accountDeviceInstances;
|
||||
|
||||
public AccountDeviceInstanceNode getAccountDeviceInstanceNode() {
|
||||
return accountDeviceInstance;
|
||||
public ImmutableSet<AccountDeviceInstanceKey> getAccountDeviceInstances() {
|
||||
return accountDeviceInstances;
|
||||
}
|
||||
|
||||
PinAccountEvent(AccountDeviceInstanceNode accountDeviceInstance) {
|
||||
this.accountDeviceInstance = accountDeviceInstance;
|
||||
PinAccountEvent(Collection<? extends AccountDeviceInstanceKey> accountDeviceInstances) {
|
||||
this.accountDeviceInstances = ImmutableSet.copyOf(accountDeviceInstances);
|
||||
}
|
||||
}
|
||||
|
@ -29,21 +29,25 @@ import com.mxgraph.view.mxStylesheet;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JPanel;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.explorer.ExplorerUtils;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.lookup.ProxyLookup;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.communications.AccountsRootChildren.AccountDeviceInstanceNode;
|
||||
import org.sleuthkit.autopsy.communications.CVTTopComponent.ProxiedExplorerManagerProvider;
|
||||
import static org.sleuthkit.autopsy.casemodule.Case.Events.CURRENT_CASE;
|
||||
import static org.sleuthkit.autopsy.communications.RelationshipNode.getAttributeDisplayString;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||
@ -57,25 +61,43 @@ import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* * A panel that goes in the Visualize tab of the Communications Visualization
|
||||
* Tool. Hosts an JGraphX mxGraphComponent that host the communications network
|
||||
* visualization and a MessageBrowser for viewing details of communications.
|
||||
*
|
||||
* The Lookup provided by getLookup will be proxied by the lookup of the
|
||||
* CVTTopComponent when this tab is active allowing for context sensitive
|
||||
* actions to work correctly.
|
||||
*/
|
||||
public class VisualizationPanel extends JPanel implements ProxiedExplorerManagerProvider {
|
||||
final public class VisualizationPanel extends JPanel implements Lookup.Provider {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Logger logger = Logger.getLogger(VisualizationPanel.class.getName());
|
||||
|
||||
static final private mxStylesheet mxStylesheet = new mxStylesheet();
|
||||
|
||||
static {
|
||||
//initialize defaul cell (Vertex and/or Edge) properties
|
||||
mxStylesheet.getDefaultVertexStyle().put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ELLIPSE);
|
||||
mxStylesheet.getDefaultEdgeStyle().put(mxConstants.STYLE_NOLABEL, true);
|
||||
}
|
||||
|
||||
private final ExplorerManager vizEM = new ExplorerManager();
|
||||
private final ExplorerManager gacEM = new ExplorerManager();
|
||||
private final ProxyLookup proxyLookup = new ProxyLookup(
|
||||
ExplorerUtils.createLookup(gacEM, getActionMap()),
|
||||
ExplorerUtils.createLookup(vizEM, getActionMap()));
|
||||
|
||||
private final mxGraphComponent graphComponent;
|
||||
private final mxGraph graph;
|
||||
private final Map<String, mxCell> nodeMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
//initialize defaul cell properties
|
||||
mxStylesheet.getDefaultVertexStyle().put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ELLIPSE);
|
||||
mxStylesheet.getDefaultEdgeStyle().put(mxConstants.STYLE_NOLABEL, true);
|
||||
private CommunicationsManager commsManager;
|
||||
|
||||
void setFilterProvider(FilterProvider filterProvider) {
|
||||
this.filterProvider = filterProvider;
|
||||
}
|
||||
private FilterProvider filterProvider;
|
||||
|
||||
public VisualizationPanel() {
|
||||
initComponents();
|
||||
@ -103,7 +125,6 @@ public class VisualizationPanel extends JPanel implements ProxiedExplorerManager
|
||||
if (selectionCells.length == 1) {
|
||||
mxCell selectionCell = (mxCell) selectionCells[0];
|
||||
try {
|
||||
CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
|
||||
|
||||
if (selectionCell.isVertex()) {
|
||||
final AccountDeviceInstanceNode accountDeviceInstanceNode =
|
||||
@ -116,19 +137,16 @@ public class VisualizationPanel extends JPanel implements ProxiedExplorerManager
|
||||
System.out.println(selectionCell.getId());
|
||||
// explorerManager.setRootContext(new CommunicationsBundleNode(adiKey, commsManager));
|
||||
}
|
||||
} catch (TskCoreException tskCoreException) {
|
||||
Logger.getLogger(VisualizationPanel.class.getName()).log(Level.SEVERE,
|
||||
"Could not get communications manager for current case", tskCoreException);
|
||||
} catch (PropertyVetoException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
logger.log(Level.SEVERE, "Account selection vetoed.", ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExplorerManager getProxiedExplorerManager() {
|
||||
return gacEM;
|
||||
public Lookup getLookup() {
|
||||
return proxyLookup;
|
||||
}
|
||||
|
||||
private void addEdge(mxCell pinnedAccountVertex, mxCell relatedAccountVertex) {
|
||||
@ -192,29 +210,29 @@ public class VisualizationPanel extends JPanel implements ProxiedExplorerManager
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void pinAccount(PinAccountEvent pinEvent) {
|
||||
public void pinAccounts(PinAccountEvent pinEvent) {
|
||||
|
||||
final AccountDeviceInstanceNode adiNode = pinEvent.getAccountDeviceInstanceNode();
|
||||
final AccountDeviceInstanceKey adiKey = adiNode.getAccountDeviceInstanceKey();
|
||||
final Set<AccountDeviceInstanceKey> adiKeys = pinEvent.getAccountDeviceInstances();
|
||||
final CommunicationsFilter commsFilter = filterProvider.getFilter();
|
||||
|
||||
graph.getModel().beginUpdate();
|
||||
try {
|
||||
nodeMap.clear();
|
||||
graph.removeCells(graph.getChildCells(graph.getDefaultParent(), true, true));
|
||||
|
||||
mxCell pinnedAccountVertex = getOrCreateVertex(adiKey);
|
||||
CommunicationsManager commsManager = adiNode.getCommsManager();
|
||||
final CommunicationsFilter commsFilter = adiNode.getFilter();
|
||||
List<AccountDeviceInstance> relatedAccountDeviceInstances =
|
||||
commsManager.getRelatedAccountDeviceInstances(adiNode.getAccountDeviceInstance(), commsFilter);
|
||||
for (AccountDeviceInstanceKey adiKey : adiKeys) {
|
||||
mxCell pinnedAccountVertex = getOrCreateVertex(adiKey);
|
||||
|
||||
for (AccountDeviceInstance relatedADI : relatedAccountDeviceInstances) {
|
||||
long communicationsCount = commsManager.getRelationshipSourcesCount(relatedADI, commsFilter);
|
||||
String dataSourceName = AccountsRootChildren.getDataSourceName(relatedADI);
|
||||
AccountDeviceInstanceKey relatedADIKey = new AccountDeviceInstanceKey(relatedADI, commsFilter, communicationsCount, dataSourceName);
|
||||
mxCell relatedAccountVertex = getOrCreateVertex(relatedADIKey);
|
||||
List<AccountDeviceInstance> relatedAccountDeviceInstances =
|
||||
commsManager.getRelatedAccountDeviceInstances(adiKey.getAccountDeviceInstance(), commsFilter);
|
||||
|
||||
addEdge(pinnedAccountVertex, relatedAccountVertex);
|
||||
for (AccountDeviceInstance relatedADI : relatedAccountDeviceInstances) {
|
||||
long communicationsCount = commsManager.getRelationshipSourcesCount(relatedADI, commsFilter);
|
||||
AccountDeviceInstanceKey relatedADIKey = new AccountDeviceInstanceKey(relatedADI, commsFilter, communicationsCount);
|
||||
mxCell relatedAccountVertex = getOrCreateVertex(relatedADIKey);
|
||||
|
||||
addEdge(pinnedAccountVertex, relatedAccountVertex);
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
@ -265,6 +283,49 @@ public class VisualizationPanel extends JPanel implements ProxiedExplorerManager
|
||||
return vertex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
// IngestManager.getInstance().addIngestModuleEventListener(ingestListener);
|
||||
try {
|
||||
commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
|
||||
|
||||
} catch (IllegalStateException ex) {
|
||||
logger.log(Level.SEVERE, "Can't get CommunicationsManager when there is no case open.", ex);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting CommunicationsManager for the current case.", ex);
|
||||
|
||||
}
|
||||
|
||||
Case.addEventTypeSubscriber(EnumSet.of(CURRENT_CASE), evt -> {
|
||||
graph.getModel().beginUpdate();
|
||||
try {
|
||||
nodeMap.clear();
|
||||
graph.removeCells(graph.getChildCells(graph.getDefaultParent(), true, true));
|
||||
} finally {
|
||||
graph.getModel().endUpdate();
|
||||
}
|
||||
if (evt.getNewValue() != null) {
|
||||
Case currentCase = (Case) evt.getNewValue();
|
||||
try {
|
||||
commsManager = currentCase.getSleuthkitCase().getCommunicationsManager();
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error getting CommunicationsManager for the current case.", ex);
|
||||
}
|
||||
} else {
|
||||
commsManager = null;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
// IngestManager.getInstance().removeIngestModuleEventListener(ingestListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
|
Loading…
x
Reference in New Issue
Block a user