19package org.sleuthkit.autopsy.contentviewers.artifactviewers;
21import java.awt.Dimension;
22import java.awt.Insets;
23import java.awt.Toolkit;
24import java.awt.datatransfer.StringSelection;
25import java.awt.event.ActionEvent;
26import java.awt.event.ActionListener;
27import java.awt.event.MouseAdapter;
28import java.awt.event.MouseEvent;
29import java.util.ArrayList;
30import java.util.Collection;
32import java.util.concurrent.CancellationException;
33import java.util.concurrent.ExecutionException;
34import java.util.logging.Level;
35import javax.swing.GroupLayout;
36import javax.swing.GroupLayout.Alignment;
37import javax.swing.GroupLayout.ParallelGroup;
38import javax.swing.GroupLayout.SequentialGroup;
39import javax.swing.JButton;
40import javax.swing.JLabel;
41import javax.swing.JMenuItem;
42import javax.swing.JPanel;
43import javax.swing.JPopupMenu;
44import javax.swing.JTextPane;
45import javax.swing.LayoutStyle.ComponentPlacement;
46import javax.swing.SwingUtilities;
47import javax.swing.SwingWorker;
48import javax.swing.border.EmptyBorder;
49import org.openide.util.NbBundle;
50import org.openide.util.NbBundle.Messages;
51import org.sleuthkit.autopsy.casemodule.Case;
52import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
53import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
54import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
55import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
56import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
57import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
58import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
59import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
60import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
61import org.sleuthkit.autopsy.contentviewers.layout.ContentViewerDefaults;
62import org.sleuthkit.autopsy.coreutils.Logger;
63import org.sleuthkit.autopsy.guiutils.ContactCache;
64import org.sleuthkit.datamodel.Account;
65import org.sleuthkit.datamodel.BlackboardArtifact;
66import org.sleuthkit.datamodel.BlackboardAttribute;
67import org.sleuthkit.datamodel.CommunicationsManager;
68import org.sleuthkit.datamodel.InvalidAccountIDException;
69import org.sleuthkit.datamodel.DataSource;
70import org.sleuthkit.datamodel.TskCoreException;
76final class MessageAccountPanel
extends JPanel {
78 private static final long serialVersionUID = 1L;
79 private final static Logger logger = Logger.getLogger(MessageAccountPanel.class.getName());
81 private AccountFetcher currentFetcher =
null;
88 MessageAccountPanel() {
89 this.setBorder(
new EmptyBorder(ContentViewerDefaults.getPanelInsets()));
99 void setArtifact(BlackboardArtifact artifact) {
104 if (artifact ==
null) {
108 if (currentFetcher !=
null && !currentFetcher.isDone()) {
109 currentFetcher.cancel(
true);
112 currentFetcher =
new AccountFetcher(artifact);
113 currentFetcher.execute();
119 class AccountFetcher
extends SwingWorker<List<AccountContainer>, Void> {
121 private final BlackboardArtifact artifact;
128 AccountFetcher(BlackboardArtifact artifact) {
129 this.artifact = artifact;
133 protected List<AccountContainer> doInBackground() throws Exception {
134 List<AccountContainer> dataList =
new ArrayList<>();
136 CommunicationsManager commManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
137 List<Account> accountList = commManager.getAccountsRelatedToArtifact(artifact);
138 for (Account account : accountList) {
140 return new ArrayList<>();
143 if (!((DataSource) (artifact.getDataSource())).getDeviceId().equals(account.getTypeSpecificID())) {
144 List<BlackboardArtifact> contactList = ContactCache.getContacts(account);
145 BlackboardArtifact contact =
null;
147 if (contactList !=
null && !contactList.isEmpty()) {
148 contact = contactList.get(0);
151 if (CentralRepository.isEnabled()) {
152 Collection<PersonaAccount> personAccounts = PersonaAccount.getPersonaAccountsForAccount(account);
153 if (personAccounts !=
null && !personAccounts.isEmpty()) {
154 for (PersonaAccount personaAccount : PersonaAccount.getPersonaAccountsForAccount(account)) {
155 dataList.add(
new AccountContainer(account, personaAccount, contact));
158 dataList.add(
new AccountContainer(account,
null, contact));
161 dataList.add(
new AccountContainer(account,
null, contact));
170 "MessageAccountPanel_no_matches=No matches found.",})
172 protected void done() {
174 List<AccountContainer> dataList =
get();
176 if (!dataList.isEmpty()) {
177 dataList.forEach(container -> {
178 container.initalizeSwingControls();
181 GroupLayout layout =
new GroupLayout(MessageAccountPanel.this);
182 layout.setHorizontalGroup(
183 layout.createParallelGroup(Alignment.LEADING)
184 .addGroup(layout.createSequentialGroup()
185 .addGroup(getMainHorizontalGroup(layout, dataList))));
187 layout.setVerticalGroup(getMainVerticalGroup(layout, dataList));
192 JPanel messagePanel =
new javax.swing.JPanel();
193 JLabel messageLabel =
new javax.swing.JLabel();
195 messagePanel.setLayout(
new java.awt.BorderLayout());
197 messageLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
198 messageLabel.setText(Bundle.MessageAccountPanel_no_matches());
199 messageLabel.setFont(ContentViewerDefaults.getMessageFont());
200 messageLabel.setEnabled(
false);
201 messagePanel.add(messageLabel, java.awt.BorderLayout.CENTER);
203 setLayout(
new javax.swing.OverlayLayout(MessageAccountPanel.this));
208 }
catch (CancellationException ex) {
209 logger.log(Level.INFO,
"MessageAccoutPanel thread cancelled", ex);
210 }
catch (InterruptedException | ExecutionException ex) {
211 logger.log(Level.WARNING,
"Failed to get account list for MessageAccountPanel", ex);
221 private ParallelGroup getMainHorizontalGroup(GroupLayout layout, List<AccountContainer> data) {
222 ParallelGroup group = layout.createParallelGroup(Alignment.LEADING);
223 for (AccountContainer o : data) {
224 group.addComponent(o.getAccountLabel());
226 group.addGroup(getPersonaHorizontalGroup(layout, data));
235 private ParallelGroup getMainVerticalGroup(GroupLayout layout, List<AccountContainer> data) {
236 SequentialGroup group = layout.createSequentialGroup();
237 for (AccountContainer o : data) {
238 group.addComponent(o.getAccountLabel())
239 .addGroup(o.getContactLineVerticalGroup(layout))
240 .addGroup(o.getPersonLineVerticalGroup(layout));
241 group.addGap(ContentViewerDefaults.getSectionSpacing());
244 return layout.createParallelGroup().addGroup(group);
254 private ParallelGroup getButtonGroup(GroupLayout layout, List<AccountContainer> data) {
255 ParallelGroup group = layout.createParallelGroup(Alignment.LEADING);
256 for (AccountContainer o : data) {
257 group.addComponent(o.getButton());
268 private SequentialGroup getPersonaHorizontalGroup(GroupLayout layout, List<AccountContainer> data) {
269 SequentialGroup group = layout.createSequentialGroup();
270 ParallelGroup pgroup = layout.createParallelGroup(Alignment.LEADING);
271 for (AccountContainer o : data) {
272 pgroup.addGroup(o.getPersonaSequentialGroup(layout));
273 pgroup.addGroup(o.getContactSequentialGroup(layout));
275 group.addGap(ContentViewerDefaults.getSectionIndent())
277 .addPreferredGap(ComponentPlacement.RELATED)
278 .addGroup(getButtonGroup(layout, data));
289 private class AccountContainer {
305 JPopupMenu contactPopupMenu =
new JPopupMenu();
306 JPopupMenu personaPopupMenu =
new JPopupMenu();
307 JPopupMenu accountPopupMenu =
new JPopupMenu();
315 AccountContainer(Account
account,
PersonaAccount personaAccount, BlackboardArtifact contactArtifact)
throws TskCoreException {
316 if (contactArtifact !=
null && contactArtifact.getArtifactTypeID() != BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) {
317 throw new IllegalArgumentException(
"Failed to create AccountContainer object, passed in artifact was not a TSK_CONTACT");
321 this.persona = personaAccount !=
null ? personaAccount.getPersona() :
null;
326 "MessageAccountPanel_persona_label=Persona:",
327 "MessageAccountPanel_unknown_label=Unknown",
328 "MessageAccountPanel_button_view_label=View",
329 "MessageAccountPanel_button_create_label=Create",
330 "MessageAccountPanel_contact_label=Contact:",
331 "MessageAccountPanel_copy_label=Copy"
340 personaHeader =
new JLabel(Bundle.MessageAccountPanel_persona_label());
341 contactHeader =
new JLabel(Bundle.MessageAccountPanel_contact_label());
365 button.setText(
persona !=
null ? Bundle.MessageAccountPanel_button_view_label() : Bundle.MessageAccountPanel_button_create_label());
383 public void mouseClicked(MouseEvent evt) {
384 if (SwingUtilities.isRightMouseButton(evt)) {
392 public void actionPerformed(ActionEvent e) {
393 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(
personaDisplayName.getText()),
null);
399 public void mouseClicked(MouseEvent evt) {
400 if (SwingUtilities.isRightMouseButton(evt)) {
408 public void actionPerformed(ActionEvent e) {
409 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(
contactDisplayName.getText()),
null);
415 public void mouseClicked(MouseEvent evt) {
416 if (SwingUtilities.isRightMouseButton(evt)) {
417 accountPopupMenu.show(
accountLabel, evt.getX(), evt.getY());
424 public void actionPerformed(ActionEvent e) {
425 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
new StringSelection(
accountLabel.getText()),
null);
432 if (contactArtifact !=
null) {
433 BlackboardAttribute attribute = contactArtifact.getAttribute(
new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME));
434 if (attribute !=
null) {
435 return attribute.getValueString();
439 return Bundle.MessageAccountPanel_unknown_label();
451 SwingUtilities.invokeLater(
new Runnable() {
455 button.setText(
persona !=
null ? Bundle.MessageAccountPanel_button_view_label() : Bundle.MessageAccountPanel_button_create_label());
509 SequentialGroup group =
layout.createSequentialGroup();
513 .addPreferredGap(ComponentPlacement.RELATED)
520 SequentialGroup group =
layout.createSequentialGroup();
524 .addPreferredGap(ComponentPlacement.RELATED)
538 return layout.createParallelGroup(Alignment.CENTER)
552 return layout.createParallelGroup(Alignment.CENTER)
561 private class PersonaButtonListener
implements ActionListener {
575 "MessageAccountPanel.account.justification=Account found in Message artifact",
576 "# {0} - accountIdentifer",
577 "MessageAccountPanel_id_not_found_in_cr=Unable to find an account with identifier {0} in the Central Repository."
582 if (persona ==
null) {
584 MessageAccountPanel.this,
599 boolean showErrorMessage =
true;
605 if (account !=
null) {
607 showErrorMessage =
false;
609 }
catch (InvalidAccountIDException ex2) {
613 if(showErrorMessage) {
617 logger.log(Level.SEVERE,
"Error looking up account types in the central repository", ex);
PersonaDetailsPanel getDetailsPanel()
void setStartupPopupMessage(String message)
void setPersonaName(String name)
boolean addAccount(CentralRepoAccount account, String justification, Persona.Confidence confidence)
JTextPane personaDisplayName
JMenuItem personaCopyMenuItem
JMenuItem accountCopyMenuItem
JTextPane getAccountLabel()
void setPersona(Persona persona)
SequentialGroup getPersonaSequentialGroup(GroupLayout layout)
JMenuItem contactCopyMenuItem
ParallelGroup getContactLineVerticalGroup(GroupLayout layout)
void initalizeSwingControls()
void initalizePopupMenus()
JTextPane contactDisplayName
ParallelGroup getPersonLineVerticalGroup(GroupLayout layout)
SequentialGroup getContactSequentialGroup(GroupLayout layout)
String getNameFromContactArtifact(BlackboardArtifact contactArtifact)
void actionPerformed(ActionEvent e)
final AccountContainer accountContainer
final AccountContainer accountContainer
void callback(Persona persona)
static Font getHeaderFont()
static CentralRepository getInstance()
Collection< CentralRepoAccountType > getAllAccountTypes()
CentralRepoAccount getAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)