mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge pull request #6545 from kellykelly3/7078-cvt-tooltips
7078 Added contact and person information to callog and message viewer too…
This commit is contained in:
commit
7891b70643
@ -20,27 +20,21 @@ package org.sleuthkit.autopsy.communications;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.NbBundle.Messages;
|
|
||||||
import org.openide.util.lookup.Lookups;
|
import org.openide.util.lookup.Lookups;
|
||||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
|
import org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
import org.sleuthkit.datamodel.Account;
|
import org.sleuthkit.datamodel.Account;
|
||||||
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
import org.sleuthkit.datamodel.AccountDeviceInstance;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
|
||||||
import org.sleuthkit.datamodel.CommunicationsFilter;
|
import org.sleuthkit.datamodel.CommunicationsFilter;
|
||||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node to represent an Account Device Instance in the CVT
|
* Node to represent an Account Device Instance in the CVT
|
||||||
@ -118,48 +112,8 @@ final class AccountDeviceInstanceNode extends AbstractNode {
|
|||||||
return actions.toArray(new Action[actions.size()]);
|
return actions.toArray(new Action[actions.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Messages({
|
|
||||||
"# {0} - Contact Name",
|
|
||||||
"# {1} - Persona Name",
|
|
||||||
"AccountInstanceNode_Tooltip_Template=Contact: {0} - Persona: {1}",
|
|
||||||
"# {0} - PersonaAccount count",
|
|
||||||
"AccountInstanceNode_Tooltip_suffix=(1 of {0})"
|
|
||||||
})
|
|
||||||
@Override
|
@Override
|
||||||
public String getShortDescription() {
|
public String getShortDescription() {
|
||||||
List<PersonaAccount> personaList;
|
return RelationshipsNodeUtilities.getAccoutToolTipText(getDisplayName(), account);
|
||||||
List<BlackboardArtifact> contactArtifactList;
|
|
||||||
try {
|
|
||||||
personaList = CVTPersonaCache.getPersonaAccounts(account);
|
|
||||||
contactArtifactList = ContactCache.getContacts(account);
|
|
||||||
} catch (ExecutionException ex) {
|
|
||||||
logger.log(Level.WARNING, "Failed to retrieve Persona details for node.", ex);
|
|
||||||
return getDisplayName();
|
|
||||||
}
|
|
||||||
|
|
||||||
String personaName;
|
|
||||||
if (personaList != null && !personaList.isEmpty()) {
|
|
||||||
personaName = personaList.get(0).getPersona().getName();
|
|
||||||
if (personaList.size() > 1) {
|
|
||||||
personaName += Bundle.AccountInstanceNode_Tooltip_suffix(Integer.toString(personaList.size()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
personaName = "None";
|
|
||||||
}
|
|
||||||
|
|
||||||
String contactName = getDisplayName();
|
|
||||||
if (contactArtifactList != null && !contactArtifactList.isEmpty()) {
|
|
||||||
try {
|
|
||||||
BlackboardArtifact contactArtifact = contactArtifactList.get(0);
|
|
||||||
BlackboardAttribute attribute = contactArtifact.getAttribute(NAME_ATTRIBUTE);
|
|
||||||
if (attribute != null) {
|
|
||||||
contactName = attribute.getValueString();
|
|
||||||
}
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.WARNING, "Failed to retrive name attribute from contact artifact.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Bundle.AccountInstanceNode_Tooltip_Template(contactName, personaName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
# {0} - PersonaAccount count
|
|
||||||
AccountInstanceNode_Tooltip_suffix=(1 of {0})
|
|
||||||
# {0} - Contact Name
|
|
||||||
# {1} - Persona Name
|
|
||||||
AccountInstanceNode_Tooltip_Template=Contact: {0} - Persona: {1}
|
|
||||||
AccountNode.accountName=Account
|
AccountNode.accountName=Account
|
||||||
AccountNode.accountType=Type
|
AccountNode.accountType=Type
|
||||||
AccountNode.device=Device
|
AccountNode.device=Device
|
||||||
|
@ -38,7 +38,7 @@ import org.sleuthkit.datamodel.Account;
|
|||||||
* PersonaAccounts for a given Account typeSpecificID retrieved on first access
|
* PersonaAccounts for a given Account typeSpecificID retrieved on first access
|
||||||
* and evicted from the cache after 5 minutes.
|
* and evicted from the cache after 5 minutes.
|
||||||
*/
|
*/
|
||||||
final class CVTPersonaCache {
|
final public class CVTPersonaCache {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(CVTPersonaCache.class.getName());
|
private static final Logger logger = Logger.getLogger(CVTPersonaCache.class.getName());
|
||||||
private final LoadingCache<Account, List<PersonaAccount>> accountMap;
|
private final LoadingCache<Account, List<PersonaAccount>> accountMap;
|
||||||
@ -90,7 +90,7 @@ final class CVTPersonaCache {
|
|||||||
*
|
*
|
||||||
* @throws ExecutionException
|
* @throws ExecutionException
|
||||||
*/
|
*/
|
||||||
static synchronized List<PersonaAccount> getPersonaAccounts(Account account) throws ExecutionException {
|
static public synchronized List<PersonaAccount> getPersonaAccounts(Account account) throws ExecutionException {
|
||||||
return getInstance().accountMap.get(account);
|
return getInstance().accountMap.get(account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* expires after 10 of non-use.
|
* expires after 10 of non-use.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class ContactCache {
|
final public class ContactCache {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ContactCache.class.getName());
|
private static final Logger logger = Logger.getLogger(ContactCache.class.getName());
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ final class ContactCache {
|
|||||||
*
|
*
|
||||||
* @throws ExecutionException
|
* @throws ExecutionException
|
||||||
*/
|
*/
|
||||||
static synchronized List<BlackboardArtifact> getContacts(Account account) throws ExecutionException {
|
static public synchronized List<BlackboardArtifact> getContacts(Account account) throws ExecutionException {
|
||||||
return getInstance().accountMap.get("realMap").get(account.getTypeSpecificID());
|
return getInstance().accountMap.get("realMap").get(account.getTypeSpecificID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 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.relationships;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
|
import org.sleuthkit.datamodel.Account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A subclass of NodeProperty that stores an account object for use with looking
|
||||||
|
* up personas.
|
||||||
|
*/
|
||||||
|
class AccountNodeProperty<T> extends NodeProperty<T> {
|
||||||
|
|
||||||
|
private final Account account;
|
||||||
|
|
||||||
|
AccountNodeProperty(String name, String displayName, T value, Account account) {
|
||||||
|
super(name, displayName, "", value);
|
||||||
|
this.account = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getShortDescription() {
|
||||||
|
try {
|
||||||
|
if (account != null) {
|
||||||
|
return RelationshipsNodeUtilities.getAccoutToolTipText(getValue().toString(), account);
|
||||||
|
}
|
||||||
|
return getValue().toString();
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
@ -35,6 +35,11 @@ MessageViewer_viewMessage_all=All
|
|||||||
MessageViewer_viewMessage_calllogs=Call Logs
|
MessageViewer_viewMessage_calllogs=Call Logs
|
||||||
MessageViewer_viewMessage_selected=Selected
|
MessageViewer_viewMessage_selected=Selected
|
||||||
MessageViewer_viewMessage_unthreaded=Unthreaded
|
MessageViewer_viewMessage_unthreaded=Unthreaded
|
||||||
|
# {0} - PersonaAccount count
|
||||||
|
RelationshipsNodeUtilities_Tooltip_suffix=(1 of {0})
|
||||||
|
# {0} - Contact Name
|
||||||
|
# {1} - Persona Name
|
||||||
|
RelationshipsNodeUtilities_Tooltip_Template=Contact: {0} - Persona: {1}
|
||||||
# {0} - accountIdentifer
|
# {0} - accountIdentifer
|
||||||
SummaryPersonaPane_not_account_in_cr=Unable to find an account with identifier {0} in the Central Repository.
|
SummaryPersonaPane_not_account_in_cr=Unable to find an account with identifier {0} in the Central Repository.
|
||||||
SummaryViewer.countsPanel.border.title=Communications
|
SummaryViewer.countsPanel.border.title=Communications
|
||||||
|
@ -77,7 +77,16 @@ final class CallLogNode extends BlackboardArtifactNode {
|
|||||||
|
|
||||||
sheetSet.put(createNode(TSK_DATETIME_START, artifact));
|
sheetSet.put(createNode(TSK_DATETIME_START, artifact));
|
||||||
sheetSet.put(createNode(TSK_DIRECTION, artifact));
|
sheetSet.put(createNode(TSK_DIRECTION, artifact));
|
||||||
sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", getPhoneNumber(artifact)));
|
|
||||||
|
String phoneNumber = getPhoneNumber(artifact);
|
||||||
|
Account account = null;
|
||||||
|
try {
|
||||||
|
account = artifact.getSleuthkitCase().getCommunicationsManager().getAccount(Account.Type.PHONE, phoneNumber);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to get instance of communications manager", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
sheetSet.put(new AccountNodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), phoneNumber, account));
|
||||||
if(duration != -1) {
|
if(duration != -1) {
|
||||||
sheetSet.put(new NodeProperty<>("duration", "Duration", "", Long.toString(duration)));
|
sheetSet.put(new NodeProperty<>("duration", "Duration", "", Long.toString(duration)));
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import java.beans.PropertyChangeEvent;
|
|||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import static javax.swing.SwingUtilities.isDescendingFrom;
|
import static javax.swing.SwingUtilities.isDescendingFrom;
|
||||||
|
import javax.swing.table.TableColumn;
|
||||||
import org.netbeans.swing.outline.DefaultOutlineModel;
|
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||||
import org.netbeans.swing.outline.Outline;
|
import org.netbeans.swing.outline.Outline;
|
||||||
import org.openide.explorer.ExplorerManager;
|
import org.openide.explorer.ExplorerManager;
|
||||||
@ -82,6 +83,8 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie
|
|||||||
|
|
||||||
outlineViewPanel.hideOutlineView(Bundle.CallLogViewer_noCallLogs());
|
outlineViewPanel.hideOutlineView(Bundle.CallLogViewer_noCallLogs());
|
||||||
|
|
||||||
|
// If changing the order of these columns effects the location of the
|
||||||
|
// phone number column be sure to adjust the renderer code below.
|
||||||
outlineViewPanel.getOutlineView().setPropertyColumns(
|
outlineViewPanel.getOutlineView().setPropertyColumns(
|
||||||
TSK_DIRECTION.getLabel(), TSK_DIRECTION.getDisplayName(),
|
TSK_DIRECTION.getLabel(), TSK_DIRECTION.getDisplayName(),
|
||||||
TSK_PHONE_NUMBER.getLabel(), Bundle.CallLogViewer_recipient_label(),
|
TSK_PHONE_NUMBER.getLabel(), Bundle.CallLogViewer_recipient_label(),
|
||||||
@ -117,6 +120,9 @@ final class CallLogViewer extends javax.swing.JPanel implements RelationshipsVie
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TableColumn column = outline.getColumnModel().getColumn(2);
|
||||||
|
column.setCellRenderer(new NodeTableCellRenderer() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,7 +24,9 @@ import javax.swing.AbstractAction;
|
|||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
@ -38,9 +40,11 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUB
|
|||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import static org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities.getAttributeDisplayString;
|
import static org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities.getAttributeDisplayString;
|
||||||
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
|
||||||
|
import org.sleuthkit.datamodel.Account;
|
||||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
|
||||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||||
import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
|
import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil;
|
||||||
import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments;
|
import org.sleuthkit.datamodel.blackboardutils.attributes.MessageAttachments;
|
||||||
|
|
||||||
@ -114,21 +118,47 @@ class MessageNode extends BlackboardArtifactNode {
|
|||||||
String msg_to = getAttributeDisplayString(artifact, TSK_EMAIL_TO);
|
String msg_to = getAttributeDisplayString(artifact, TSK_EMAIL_TO);
|
||||||
String date = getAttributeDisplayString(artifact, TSK_DATETIME_SENT);
|
String date = getAttributeDisplayString(artifact, TSK_DATETIME_SENT);
|
||||||
|
|
||||||
if (msg_from.isEmpty()) {
|
Account account_from = null;
|
||||||
msg_from = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM);
|
Account account_to = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
CommunicationsManager manager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
|
||||||
|
|
||||||
|
if (msg_from.isEmpty()) {
|
||||||
|
msg_from = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM);
|
||||||
|
if(manager != null && !msg_from.isEmpty()) {
|
||||||
|
account_from = manager.getAccount(Account.Type.PHONE, msg_from);
|
||||||
|
}
|
||||||
|
} else if(manager != null) {
|
||||||
|
// To email address sometime is in the format <name>: <email>
|
||||||
|
String toStr = msg_to;
|
||||||
|
String[] strSplit = msg_to.split(":");
|
||||||
|
if(strSplit.length > 0) {
|
||||||
|
toStr = strSplit[strSplit.length-1].trim();
|
||||||
|
}
|
||||||
|
account_from = manager.getAccount(Account.Type.EMAIL, toStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg_to.isEmpty()) {
|
||||||
|
msg_to = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO);
|
||||||
|
if(manager != null && !msg_to.isEmpty()) {
|
||||||
|
account_to = manager.getAccount(Account.Type.PHONE, msg_to);
|
||||||
|
}
|
||||||
|
} else if(manager != null) {
|
||||||
|
account_to = manager.getAccount(Account.Type.EMAIL, msg_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date.isEmpty()) {
|
||||||
|
date = getAttributeDisplayString(artifact, TSK_DATETIME);
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
|
||||||
}
|
}
|
||||||
if (msg_to.isEmpty()) {
|
|
||||||
msg_to = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO);
|
|
||||||
}
|
|
||||||
if (date.isEmpty()) {
|
|
||||||
date = getAttributeDisplayString(artifact, TSK_DATETIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
sheetSet.put(new NodeProperty<>("From", Bundle.MessageNode_Node_Property_From(), "",
|
sheetSet.put(new AccountNodeProperty<>("From", Bundle.MessageNode_Node_Property_From(),
|
||||||
msg_from)); //NON-NLS
|
msg_from, account_from)); //NON-NLS
|
||||||
sheetSet.put(new NodeProperty<>("To", Bundle.MessageNode_Node_Property_To(), "",
|
sheetSet.put(new AccountNodeProperty<>("To", Bundle.MessageNode_Node_Property_To(),
|
||||||
msg_to)); //NON-NLS
|
msg_to, account_to)); //NON-NLS
|
||||||
sheetSet.put(new NodeProperty<>("Date", Bundle.MessageNode_Node_Property_Date(), "",
|
sheetSet.put(new NodeProperty<>("Date", Bundle.MessageNode_Node_Property_Date(), "",
|
||||||
date)); //NON-NLS
|
date)); //NON-NLS
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2019 Basis Technology Corp.
|
* Copyright 2019-2020 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -25,6 +25,7 @@ import java.beans.PropertyChangeListener;
|
|||||||
import static javax.swing.SwingUtilities.isDescendingFrom;
|
import static javax.swing.SwingUtilities.isDescendingFrom;
|
||||||
import javax.swing.event.TableModelEvent;
|
import javax.swing.event.TableModelEvent;
|
||||||
import javax.swing.event.TableModelListener;
|
import javax.swing.event.TableModelListener;
|
||||||
|
import javax.swing.table.TableColumn;
|
||||||
import org.netbeans.swing.outline.DefaultOutlineModel;
|
import org.netbeans.swing.outline.DefaultOutlineModel;
|
||||||
import org.netbeans.swing.outline.Outline;
|
import org.netbeans.swing.outline.Outline;
|
||||||
import org.openide.explorer.ExplorerManager;
|
import org.openide.explorer.ExplorerManager;
|
||||||
@ -65,6 +66,8 @@ class MessagesPanel extends javax.swing.JPanel implements Lookup.Provider {
|
|||||||
proxyLookup = new ModifiableProxyLookup(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
|
proxyLookup = new ModifiableProxyLookup(createLookup(outlineViewPanel.getExplorerManager(), getActionMap()));
|
||||||
|
|
||||||
outline = outlineViewPanel.getOutlineView().getOutline();
|
outline = outlineViewPanel.getOutlineView().getOutline();
|
||||||
|
// When changing this column this, if the from and to columns pos is
|
||||||
|
// effected make sure to modify the renderer code below.
|
||||||
outlineViewPanel.getOutlineView().setPropertyColumns(
|
outlineViewPanel.getOutlineView().setPropertyColumns(
|
||||||
"From", Bundle.MessageViewer_columnHeader_From(),
|
"From", Bundle.MessageViewer_columnHeader_From(),
|
||||||
"To", Bundle.MessageViewer_columnHeader_To(),
|
"To", Bundle.MessageViewer_columnHeader_To(),
|
||||||
@ -99,6 +102,12 @@ class MessagesPanel extends javax.swing.JPanel implements Lookup.Provider {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TableColumn column = outline.getColumnModel().getColumn(1);
|
||||||
|
column.setCellRenderer(new NodeTableCellRenderer());
|
||||||
|
|
||||||
|
column = outline.getColumnModel().getColumn(2);
|
||||||
|
column.setCellRenderer(new NodeTableCellRenderer());
|
||||||
|
|
||||||
splitPane.setResizeWeight(0.5);
|
splitPane.setResizeWeight(0.5);
|
||||||
splitPane.setDividerLocation(0.5);
|
splitPane.setDividerLocation(0.5);
|
||||||
outlineViewPanel.setTableColumnsWidth(5, 10, 10, 15, 50, 10);
|
outlineViewPanel.setTableColumnsWidth(5, 10, 10, 15, 50, 10);
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 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.relationships;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.beans.FeatureDescriptor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TableCellRenderer for NodeProperty with custom tooltip data.
|
||||||
|
*/
|
||||||
|
final class NodeTableCellRenderer extends DefaultTableCellRenderer {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(NodeTableCellRenderer.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getTableCellRendererComponent(JTable table,
|
||||||
|
Object value,
|
||||||
|
boolean isSelected,
|
||||||
|
boolean hasFocus,
|
||||||
|
int row,
|
||||||
|
int column) {
|
||||||
|
|
||||||
|
String descr = "";
|
||||||
|
Object theRealValue = value;
|
||||||
|
if (value instanceof NodeProperty) {
|
||||||
|
descr = ((FeatureDescriptor) value).getShortDescription();
|
||||||
|
try {
|
||||||
|
theRealValue = ((Node.Property<?>) value).getValue();
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to get NodeProperty cell value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.getTableCellRendererComponent(table, theRealValue, isSelected, hasFocus, row, column);
|
||||||
|
|
||||||
|
setToolTipText(descr);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -19,12 +19,21 @@
|
|||||||
|
|
||||||
package org.sleuthkit.autopsy.communications.relationships;
|
package org.sleuthkit.autopsy.communications.relationships;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
|
||||||
|
import org.sleuthkit.autopsy.communications.CVTPersonaCache;
|
||||||
|
import org.sleuthkit.autopsy.communications.ContactCache;
|
||||||
import org.sleuthkit.autopsy.communications.Utils;
|
import org.sleuthkit.autopsy.communications.Utils;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.Account;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME;
|
||||||
import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME;
|
import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME;
|
||||||
import org.sleuthkit.datamodel.TimeUtilities;
|
import org.sleuthkit.datamodel.TimeUtilities;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
@ -33,9 +42,11 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
* A set of reusable utility functions for the Relationships package.
|
* A set of reusable utility functions for the Relationships package.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class RelationshipsNodeUtilities {
|
final public class RelationshipsNodeUtilities {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(RelationshipsNodeUtilities.class.getName());
|
private static final Logger logger = Logger.getLogger(RelationshipsNodeUtilities.class.getName());
|
||||||
|
private static final BlackboardAttribute.Type NAME_ATTRIBUTE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(TSK_NAME.getTypeID()));
|
||||||
|
|
||||||
|
|
||||||
// Here to make codacy happy
|
// Here to make codacy happy
|
||||||
private RelationshipsNodeUtilities(){
|
private RelationshipsNodeUtilities(){
|
||||||
@ -69,4 +80,52 @@ final class RelationshipsNodeUtilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"# {0} - Contact Name",
|
||||||
|
"# {1} - Persona Name",
|
||||||
|
"RelationshipsNodeUtilities_Tooltip_Template=Contact: {0} - Persona: {1}",
|
||||||
|
"# {0} - PersonaAccount count",
|
||||||
|
"RelationshipsNodeUtilities_Tooltip_suffix=(1 of {0})"
|
||||||
|
})
|
||||||
|
static public String getAccoutToolTipText(String displayName, Account account) {
|
||||||
|
if(account == null) {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PersonaAccount> personaList;
|
||||||
|
List<BlackboardArtifact> contactArtifactList;
|
||||||
|
try {
|
||||||
|
personaList = CVTPersonaCache.getPersonaAccounts(account);
|
||||||
|
contactArtifactList = ContactCache.getContacts(account);
|
||||||
|
} catch (ExecutionException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to retrieve Persona details for node.", ex);
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String personaName;
|
||||||
|
if (personaList != null && !personaList.isEmpty()) {
|
||||||
|
personaName = personaList.get(0).getPersona().getName();
|
||||||
|
if (personaList.size() > 1) {
|
||||||
|
personaName += Bundle.RelationshipsNodeUtilities_Tooltip_suffix(Integer.toString(personaList.size()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
personaName = "None";
|
||||||
|
}
|
||||||
|
|
||||||
|
String contactName = displayName;
|
||||||
|
if (contactArtifactList != null && !contactArtifactList.isEmpty()) {
|
||||||
|
try {
|
||||||
|
BlackboardArtifact contactArtifact = contactArtifactList.get(0);
|
||||||
|
BlackboardAttribute attribute = contactArtifact.getAttribute(NAME_ATTRIBUTE);
|
||||||
|
if (attribute != null) {
|
||||||
|
contactName = attribute.getValueString();
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to retrive name attribute from contact artifact.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bundle.RelationshipsNodeUtilities_Tooltip_Template(contactName, personaName);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user