diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java new file mode 100644 index 0000000000..34245f1a6d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountDetailsNode.java @@ -0,0 +1,88 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit 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.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.CommunicationsFilter; +import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.TskCoreException; + +class AccountDetailsNode extends AbstractNode { + + private final static Logger logger = Logger.getLogger(AccountDetailsNode.class.getName()); + private final CommunicationsFilter filter; //TODO: Use this + + AccountDetailsNode(Set accounts,CommunicationsFilter filter, CommunicationsManager commsManager) { + super(new AccountRelationshipChildren(accounts, commsManager, filter)); + this.filter = filter; + } + + /** + * Children object for the relationships that the account is a member of. + */ + private static class AccountRelationshipChildren extends Children.Keys { + + private final Set accounts; + private final CommunicationsManager commsManager; + private final CommunicationsFilter filter;//TODO: Use this + + private AccountRelationshipChildren(Set accounts, CommunicationsManager commsManager, CommunicationsFilter filter) { + this.accounts = accounts; + this.commsManager = commsManager; + this.filter = filter; + } + + @Override + protected Node[] createNodes(BlackboardArtifact key) { + return new Node[]{new RelationShipFilterNode(key)}; + } + + @Override + protected void addNotify() { + Set keys = new HashSet<>(); + for (Account account : accounts) { + List accountsWithRelationship = new ArrayList<>(); + try { + accountsWithRelationship.addAll(commsManager.getAccountsWithRelationship(account)); //TODO: Use filter here + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error loading with relationships to " + account, ex); + } + + accountsWithRelationship.forEach(otherAcount -> { + try { + keys.addAll(commsManager.getRelationships(account, otherAcount)); //TODO:Use filter here + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error loading relationships between " + account + " and " + otherAcount, ex); + } + }); + } + setKeys(keys); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java deleted file mode 100644 index e859765d55..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstanceNode.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2017 Basis Technology Corp. - * Contact: carrier sleuthkit 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.logging.Level; -import java.util.logging.Logger; -import org.openide.nodes.AbstractNode; -import org.openide.nodes.Children; -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.AccountDeviceInstance; -import org.sleuthkit.datamodel.CommunicationsFilter; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Node to represent an Account in the AccountsBrowser - */ -class AccountDeviceInstanceNode extends AbstractNode { - - private static final Logger LOGGER = Logger.getLogger(AccountDeviceInstanceNode.class.getName()); - private final AccountDeviceInstance accountDeviceInstance; - private final CommunicationsFilter filter; - - AccountDeviceInstanceNode(AccountDeviceInstance accountDeviceInstance, CommunicationsFilter filter) { - super(Children.LEAF, Lookups.fixed(accountDeviceInstance)); - this.accountDeviceInstance = accountDeviceInstance; - this.filter = filter; - - setName(accountDeviceInstance.getAccount().getAccountUniqueID()); - setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" - + AccountUtils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); - } - - @Override - @NbBundle.Messages({ - "AccountNode.device=Device", - "AccountNode.accountName=Account", - "AccountNode.accountType=Type", - "AccountNode.messageCount=Msg Count"}) - protected Sheet createSheet() { - Sheet s = super.createSheet(); - Sheet.Set properties = s.get(Sheet.PROPERTIES); - if (properties == null) { - properties = Sheet.createPropertiesSet(); - s.put(properties); - } - - long msgCount = 0; - try { - msgCount = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getRelationshipsCount(this.filter, accountDeviceInstance); - } catch (TskCoreException ex) { - LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS - } - - properties.put(new NodeProperty<>("type", - Bundle.AccountNode_accountType(), - "type", - accountDeviceInstance.getAccount().getAccountType().getDisplayName())); // NON-NLS - - properties.put(new NodeProperty<>("count", - Bundle.AccountNode_messageCount(), - "count", - msgCount)); // NON-NLS - - properties.put(new NodeProperty<>("device", - Bundle.AccountNode_device(), - "device", - accountDeviceInstance.getDeviceId())); // NON-NLS - return s; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java deleted file mode 100644 index 916fc6d933..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountDeviceInstancesNodeChildren.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2017 Basis Technology Corp. - * Contact: carrier sleuthkit 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.Collections; -import java.util.List; -import org.openide.nodes.Children; -import org.openide.nodes.Node; - -class AccountDeviceInstancesNodeChildren extends Children.Keys { - - private final List accountDeviceInstanceKeys; - - AccountDeviceInstancesNodeChildren(List accountDeviceInstanceKeys) { - super(true); - this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; - } - - @Override - protected void removeNotify() { - super.removeNotify(); - setKeys(Collections.emptySet()); - } - - @Override - protected void addNotify() { - super.addNotify(); - setKeys(accountDeviceInstanceKeys); - } - - //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. - // @Override - // protected boolean createKeys(List list) { - // list.addAll(accounts); - // return true; - // } - // - // @Override - // protected Node createNodeForKey(Account key) { - // return new AccountDeviceInstanceNode(key); - // } - @Override - protected Node[] createNodes(AccountDeviceInstanceKey key) { - return new Node[]{new AccountDeviceInstanceNode(key.getAccountDeviceInstance(), key.getCommunicationsFilter())}; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java deleted file mode 100644 index dcc100f5b7..0000000000 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsDeviceInstanceChildren.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2017 Basis Technology Corp. - * Contact: carrier sleuthkit 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.Collections; -import java.util.List; -import org.openide.nodes.Children; -import org.openide.nodes.Node; - -class AccountsDeviceInstanceChildren extends Children.Keys { - - private final List accountDeviceInstanceKeys; - - AccountsDeviceInstanceChildren(List accountDeviceInstanceKeys) { - super(true); - this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; - } - - @Override - protected void removeNotify() { - super.removeNotify(); - setKeys(Collections.emptySet()); - } - - @Override - protected void addNotify() { - super.addNotify(); - setKeys(accountDeviceInstanceKeys); - } - - //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. - // @Override - // protected boolean createKeys(List list) { - // list.addAll(accounts); - // return true; - // } - // - // @Override - // protected Node createNodeForKey(Account key) { - // return new AccountDeviceInstanceNode(key); - // } - @Override - protected Node[] createNodes(AccountDeviceInstanceKey key) { - return new Node[]{new AccountDeviceInstanceNode(key.getAccountDeviceInstance(), key.getCommunicationsFilter())}; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java new file mode 100644 index 0000000000..3da39f6776 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsRootChildren.java @@ -0,0 +1,128 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit 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.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.openide.nodes.AbstractNode; +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.datamodel.NodeProperty; +import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.CommunicationsFilter; +import org.sleuthkit.datamodel.CommunicationsManager; +import org.sleuthkit.datamodel.TskCoreException; + +class AccountsRootChildren extends Children.Keys { + + private final List accountDeviceInstanceKeys; + private final CommunicationsManager commsManager; + + AccountsRootChildren(List accountDeviceInstanceKeys, CommunicationsManager commsManager) { + super(true); + this.accountDeviceInstanceKeys = accountDeviceInstanceKeys; + this.commsManager = commsManager; + } + + @Override + protected void removeNotify() { + super.removeNotify(); + setKeys(Collections.emptySet()); + } + + @Override + protected void addNotify() { + super.addNotify(); + setKeys(accountDeviceInstanceKeys); + } + + //These are the methods for ChildFactory. I am going to keep them around but commented until we make a final descision. + // @Override + // protected boolean createKeys(List list) { + // list.addAll(accounts); + // return true; + // } + // + // @Override + // protected Node createNodeForKey(Account key) { + // return new AccountDeviceInstanceNode(key); + // } + @Override + protected Node[] createNodes(AccountDeviceInstanceKey key) { + return new Node[]{new AccountDeviceInstanceNode(key, commsManager)}; + } + + /** + * Node to represent an Account in the AccountsBrowser + */ + static class AccountDeviceInstanceNode extends AbstractNode { + + private static final Logger LOGGER = Logger.getLogger(AccountDeviceInstanceNode.class.getName()); + private final AccountDeviceInstance accountDeviceInstance; + private final CommunicationsManager commsManager; + private final CommunicationsFilter filter; + + private AccountDeviceInstanceNode(AccountDeviceInstanceKey accountDeviceInstanceKey, CommunicationsManager commsManager) { + super(Children.LEAF, Lookups.fixed(accountDeviceInstanceKey, commsManager)); + this.accountDeviceInstance = accountDeviceInstanceKey.getAccountDeviceInstance(); + this.commsManager = commsManager; + this.filter = accountDeviceInstanceKey.getCommunicationsFilter(); + setName(accountDeviceInstance.getAccount().getAccountUniqueID()); + setIconBaseWithExtension("org/sleuthkit/autopsy/communications/images/" + AccountUtils.getIconFileName(accountDeviceInstance.getAccount().getAccountType())); + } + + public AccountDeviceInstance getAccountDeviceInstance() { + return accountDeviceInstance; + } + + public CommunicationsManager getCommsManager() { + return commsManager; + } + + public CommunicationsFilter getFilter() { + return filter; + } + + @Override + @NbBundle.Messages(value = {"AccountNode.device=Device", "AccountNode.accountName=Account", "AccountNode.accountType=Type", "AccountNode.messageCount=Msg Count"}) + protected Sheet createSheet() { + Sheet s = super.createSheet(); + Sheet.Set properties = s.get(Sheet.PROPERTIES); + if (properties == null) { + properties = Sheet.createPropertiesSet(); + s.put(properties); + } + long msgCount = 0; + try { + msgCount = commsManager.getRelationshipsCount(filter, accountDeviceInstance); + } catch (TskCoreException ex) { + LOGGER.log(Level.WARNING, "Failed to get message count for account", ex); //NON-NLS + } + properties.put(new NodeProperty<>("type", Bundle.AccountNode_accountType(), "type", accountDeviceInstance.getAccount().getAccountType().getDisplayName())); // NON-NLS + properties.put(new NodeProperty<>("count", Bundle.AccountNode_messageCount(), "count", msgCount)); // NON-NLS + properties.put(new NodeProperty<>("device", Bundle.AccountNode_device(), "device", accountDeviceInstance.getDeviceId())); // NON-NLS + return s; + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 99621e3e12..c95f1af5c8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -1,11 +1,9 @@ -CVTTopComponent.jTextField1.text=place holder for messages ,thumbnail list, etc -CVTTopComponent.jTextField2.text=place holder for message viewer CVTTopComponent.TabConstraints.tabTitle=Visualize CVTTopComponent.accountsBrowser.TabConstraints.tabTitle=Browse -FiltersPanel.applyFiltersButton.text=Apply Filters +FiltersPanel.applyFiltersButton.text=Apply FiltersPanel.devicesLabel.text=Devices: FiltersPanel.accountTypesLabel.text=Account Types: -FiltersPanel.filtersTitleLabel.text=Filters +FiltersPanel.filtersTitleLabel.text=Account Filters FiltersPanel.unCheckAllAccountTypesButton.text=Uncheck All FiltersPanel.checkAllAccountTypesButton.text=Check All FiltersPanel.unCheckAllDevicesButton.text=Uncheck All diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index 09ebfc73f0..524529e9bd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -17,10 +17,10 @@ - - - - + + + + @@ -31,7 +31,7 @@ - + @@ -39,9 +39,10 @@ - + + @@ -106,45 +107,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index c4b5721911..9a108d3271 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -46,8 +46,10 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag private final ExplorerManager em = new ExplorerManager(); public CVTTopComponent() { + initComponents(); setName(Bundle.CVTTopComponent_name()); + splitPane.setRightComponent(new MessageBrowser()); } /** @@ -58,16 +60,14 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag // //GEN-BEGIN:initComponents private void initComponents() { - HSplitPane = new javax.swing.JSplitPane(); + splitPane = new javax.swing.JSplitPane(); BrowseVisualizeTabPane = new javax.swing.JTabbedPane(); accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); jPanel1 = new javax.swing.JPanel(); - VSplitPane = new javax.swing.JSplitPane(); - jTextField1 = new javax.swing.JTextField(); - jTextField2 = new javax.swing.JTextField(); filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); - HSplitPane.setDividerLocation(600); + splitPane.setDividerLocation(600); + splitPane.setResizeWeight(0.3); BrowseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N @@ -87,18 +87,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag BrowseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), jPanel1); // NOI18N - HSplitPane.setLeftComponent(BrowseVisualizeTabPane); - - VSplitPane.setDividerLocation(200); - VSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - - jTextField1.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField1.text")); // NOI18N - VSplitPane.setTopComponent(jTextField1); - - jTextField2.setText(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.jTextField2.text")); // NOI18N - VSplitPane.setRightComponent(jTextField2); - - HSplitPane.setRightComponent(VSplitPane); + splitPane.setLeftComponent(BrowseVisualizeTabPane); filtersPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); filtersPane.setMinimumSize(new java.awt.Dimension(256, 495)); @@ -109,9 +98,9 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 244, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(HSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1322, Short.MAX_VALUE) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1322, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( @@ -120,7 +109,7 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(HSplitPane)) + .addComponent(splitPane)) .addContainerGap()) ); }// //GEN-END:initComponents @@ -128,13 +117,10 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTabbedPane BrowseVisualizeTabPane; - private javax.swing.JSplitPane HSplitPane; - private javax.swing.JSplitPane VSplitPane; private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; private org.sleuthkit.autopsy.communications.FiltersPanel filtersPane; private javax.swing.JPanel jPanel1; - private javax.swing.JTextField jTextField1; - private javax.swing.JTextField jTextField2; + private javax.swing.JSplitPane splitPane; // End of variables declaration//GEN-END:variables @Override diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index e020c001a1..ef451b0751 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -28,11 +28,6 @@ - - - - - @@ -56,7 +51,7 @@ - + @@ -90,6 +85,9 @@ + + + @@ -98,7 +96,7 @@ - + @@ -116,7 +114,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index 5058dce36a..893d3cb23a 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -33,15 +33,16 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.AccountDeviceInstance; +import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DeviceFilter; -import org.sleuthkit.datamodel.AccountTypeFilter; import org.sleuthkit.datamodel.TskCoreException; /** - * + * Panel that holds the Filter control widgets and translates user filtering + * changes into queries against the CommunicationsManager */ final public class FiltersPanel extends javax.swing.JPanel { @@ -133,8 +134,6 @@ final public class FiltersPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - jList1 = new javax.swing.JList<>(); - jList1.setModel(new javax.swing.AbstractListModel() { String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; public int getSize() { return strings.length; } @@ -142,18 +141,17 @@ final public class FiltersPanel extends javax.swing.JPanel { }); jScrollPane1.setViewportView(jList1); - setPreferredSize(new java.awt.Dimension(256, 469)); - applyFiltersButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/control-double.png"))); // NOI18N applyFiltersButton.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.applyFiltersButton.text")); // NOI18N applyFiltersButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING); + applyFiltersButton.setPreferredSize(null); applyFiltersButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { applyFiltersButtonActionPerformed(evt); } }); - filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N + filtersTitleLabel.setFont(new java.awt.Font("Tahoma", 0, 16)); // NOI18N filtersTitleLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/funnel.png"))); // NOI18N filtersTitleLabel.setText(org.openide.util.NbBundle.getMessage(FiltersPanel.class, "FiltersPanel.filtersTitleLabel.text")); // NOI18N @@ -184,7 +182,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(51, Short.MAX_VALUE) + .addContainerGap(43, Short.MAX_VALUE) .addComponent(unCheckAllAccountTypesButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(checkAllAccountTypesButton)) @@ -232,15 +230,12 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(devicesLabel) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(devicesPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(unCheckAllDevicesButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(checkAllDevicesButton))) - .addGap(0, 0, 0)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(unCheckAllDevicesButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(checkAllDevicesButton)) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -268,7 +263,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(filtersTitleLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(applyFiltersButton))) + .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -277,7 +272,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(filtersTitleLabel) - .addComponent(applyFiltersButton)) + .addComponent(applyFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -304,15 +299,14 @@ final public class FiltersPanel extends javax.swing.JPanel { commsFilter.addAndFilter(getDeviceFilter()); commsFilter.addAndFilter(getAccountTypeFilter()); - final CommunicationsManager communicationsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); - accountDeviceInstances.addAll(communicationsManager.getAccountDeviceInstancesWithRelationships(commsFilter)); + final CommunicationsManager commsManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager(); + accountDeviceInstances.addAll(commsManager.getAccountDeviceInstancesWithRelationships(commsFilter)); List accountDeviceInstanceKeys = new ArrayList<>(); - accountDeviceInstances.forEach((accountDevInstance) -> { - accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(accountDevInstance, commsFilter ) ); - }); - - em.setRootContext(new AbstractNode(new AccountsDeviceInstanceChildren(accountDeviceInstanceKeys))); + accountDeviceInstances.forEach(accountDeviceInstance + -> accountDeviceInstanceKeys.add(new AccountDeviceInstanceKey(accountDeviceInstance, commsFilter))); + + em.setRootContext(new AbstractNode(new AccountsRootChildren(accountDeviceInstanceKeys, commsManager))); } catch (TskCoreException ex) { logger.log(Level.SEVERE, "There was a error loading the accounts.", ex); } @@ -331,7 +325,7 @@ final public class FiltersPanel extends javax.swing.JPanel { .map(entry -> entry.getKey()).collect(Collectors.toSet())); return accountTypeFilter; } - + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setAllTypesSelected(boolean selected) { setAllSelected(accountTypeMap, selected); @@ -372,7 +366,7 @@ final public class FiltersPanel extends javax.swing.JPanel { private final javax.swing.JLabel devicesLabel = new javax.swing.JLabel(); private final javax.swing.JPanel devicesPane = new javax.swing.JPanel(); private final javax.swing.JLabel filtersTitleLabel = new javax.swing.JLabel(); - private javax.swing.JList jList1; + private final javax.swing.JList jList1 = new javax.swing.JList<>(); private final javax.swing.JPanel jPanel2 = new javax.swing.JPanel(); private final javax.swing.JPanel jPanel3 = new javax.swing.JPanel(); private final javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form new file mode 100644 index 0000000000..606d60c7df --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.form @@ -0,0 +1,61 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java new file mode 100644 index 0000000000..e5c6704f10 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageBrowser.java @@ -0,0 +1,151 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit 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 obt ain 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.collect.Iterables; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; +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.TableFilterNode; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.Account; +import org.sleuthkit.datamodel.CommunicationsFilter; +import org.sleuthkit.datamodel.CommunicationsManager; + +/** + * The right hand side of the CVT. Has a DataResultPanel to show messages and + * account details, and a Content viewer to show individual + */ +final class MessageBrowser extends javax.swing.JPanel implements ExplorerManager.Provider { + + private static final Logger logger = Logger.getLogger(MessageBrowser.class.getName()); + + private static final long serialVersionUID = 1L; + + private ExplorerManager parentExplorereManager; + private final DataResultPanel messagesResultPanel; + private ExplorerManager internalExplorerManager; + + MessageBrowser() { + initComponents(); + messagesResultPanel = DataResultPanel.createInstanceUninitialized("Account", "", Node.EMPTY, 0, messageDataContent); + splitPane.setTopComponent(messagesResultPanel); + splitPane.setBottomComponent(messageDataContent); + + } + + @Override + public void addNotify() { + super.addNotify(); + this.parentExplorereManager = ExplorerManager.find(this); + + internalExplorerManager = new ExplorerManager(); + + parentExplorereManager.addPropertyChangeListener(pce -> { + if (pce.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) { + final Node[] selectedNodes = parentExplorereManager.getSelectedNodes(); + if (selectedNodes.length == 0) { + messagesResultPanel.setNode(null); + messagesResultPanel.setPath(""); + } else { + Set accounts = new HashSet<>(); + CommunicationsFilter filter = null; + CommunicationsManager commsManager = null; + for (Node n : selectedNodes) { + if (n instanceof AccountDeviceInstanceNode) { + final AccountDeviceInstanceNode adiNode = (AccountDeviceInstanceNode) n; + accounts.add(adiNode.getAccountDeviceInstance().getAccount()); + if (commsManager == null) { + commsManager = adiNode.getCommsManager(); + } + if (filter == null) { + filter = adiNode.getFilter(); + } else if (filter != adiNode.getFilter()) { + ///this should never happen... + logger.log(Level.WARNING, "Not all AccountDeviceInstanceNodes have the same filter. Using the first."); + } + } else { + ///this should never happen... + logger.log(Level.WARNING, "Unexpected Node encountered: " + n.toString()); + } + } + messagesResultPanel.setNode(new TableFilterNode(new AccountDetailsNode(accounts, filter, commsManager), true)); + if (accounts.size() == 1) { + messagesResultPanel.setPath(Iterables.getOnlyElement(accounts).getAccountUniqueID()); + } else { + messagesResultPanel.setPath(accounts.size() + " accounts"); + } + } + } + }); + messagesResultPanel.open(); + } + + /** + * 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 + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + splitPane = new javax.swing.JSplitPane(); + messageDataContent = new org.sleuthkit.autopsy.communications.MessageDataContent(); + + splitPane.setDividerLocation(400); + splitPane.setDividerSize(10); + splitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + splitPane.setResizeWeight(0.4); + + messageDataContent.setMinimumSize(null); + splitPane.setBottomComponent(messageDataContent); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 652, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1083, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private org.sleuthkit.autopsy.communications.MessageDataContent messageDataContent; + private javax.swing.JSplitPane splitPane; + // End of variables declaration//GEN-END:variables + + @Override + public ExplorerManager getExplorerManager() { + return internalExplorerManager; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java new file mode 100644 index 0000000000..1b7b5dc3c0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/MessageDataContent.java @@ -0,0 +1,38 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit 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.beans.PropertyChangeEvent; +import org.sleuthkit.autopsy.contentviewers.MessageContentViewer; +import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent; + +/** + * Extend MessageContentViewer so that it implements DataContent and can be set + * as the only ContentViewer for a DataResultPanel + */ +public class MessageDataContent extends MessageContentViewer implements DataContent { + + private static final long serialVersionUID = 1L; + + @Override + public void propertyChange(PropertyChangeEvent evt) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java new file mode 100644 index 0000000000..71508f807a --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/communications/RelationShipFilterNode.java @@ -0,0 +1,124 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit 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.logging.Level; +import org.apache.commons.lang3.StringUtils; +import org.openide.nodes.Sheet; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; +import org.sleuthkit.autopsy.datamodel.NodeProperty; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * + */ +public class RelationShipFilterNode extends BlackboardArtifactNode { + + private static final Logger logger = Logger.getLogger(RelationShipFilterNode.class.getName()); + + public RelationShipFilterNode(BlackboardArtifact artifact) { + super(artifact); + final String stripEnd = StringUtils.stripEnd(artifact.getDisplayName(), "s"); + String removeEndIgnoreCase = StringUtils.removeEndIgnoreCase(stripEnd, "message"); + setDisplayName(removeEndIgnoreCase.isEmpty() ? stripEnd : removeEndIgnoreCase); + } + + @Override + protected Sheet createSheet() { + + Sheet s = new Sheet(); + Sheet.Set ss = s.get(Sheet.PROPERTIES); + if (ss == null) { + ss = Sheet.createPropertiesSet(); + s.put(ss); + } + + ss.put(new NodeProperty<>("Type", "Type", "Type", getDisplayName())); + final BlackboardArtifact artifact = getArtifact(); + BlackboardArtifact.ARTIFACT_TYPE fromID = BlackboardArtifact.ARTIFACT_TYPE.fromID(getArtifact().getArtifactTypeID()); + if (null != fromID) { + switch (fromID) { + case TSK_EMAIL_MSG: + ss.put(new NodeProperty<>("From", "From", "From", + getAttributeDisplayString(artifact, TSK_EMAIL_FROM))); + ss.put(new NodeProperty<>("To", "To", "To", + getAttributeDisplayString(artifact, TSK_EMAIL_TO))); + ss.put(new NodeProperty<>("Date", "Date", "Date", + getAttributeDisplayString(artifact, TSK_DATETIME_SENT))); + ss.put(new NodeProperty<>("Subject", "Subject", "Subject", + getAttributeDisplayString(artifact, TSK_SUBJECT))); + break; + case TSK_MESSAGE: + ss.put(new NodeProperty<>("From", "From", "From", + getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM))); + ss.put(new NodeProperty<>("To", "To", "To", + getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO))); + ss.put(new NodeProperty<>("Date", "Date", "Date", + getAttributeDisplayString(artifact, TSK_DATETIME))); + ss.put(new NodeProperty<>("Subject", "Subject", "Subject", + getAttributeDisplayString(artifact, TSK_SUBJECT))); + break; + case TSK_CALLLOG: + ss.put(new NodeProperty<>("From", "From", "From", + getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM))); + ss.put(new NodeProperty<>("To", "To", "To", + getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO))); + ss.put(new NodeProperty<>("Date", "Date", "Date", + getAttributeDisplayString(artifact, TSK_DATETIME_START))); + break; + default: + break; + } + } + return s; + } + + /** + * + * @param artifact the value of artifact + * @param attributeType the value of TSK_SUBJECT1 + * + * @throws TskCoreException + */ + private static String getAttributeDisplayString(final BlackboardArtifact artifact, final ATTRIBUTE_TYPE attributeType) { + try { + BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attributeType.getTypeID()))); + if (attribute == null) { + return ""; + } else { + return attribute.getDisplayString(); + } + } catch (TskCoreException tskCoreException) { + logger.log(Level.WARNING, "Error getting attribute value.", tskCoreException); + return ""; + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index ed52040276..09048ca131 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -37,4 +37,4 @@ MessageContentViewer.directionText.text=direction MessageContentViewer.ccLabel.text=CC: MessageContentViewer.showImagesToggleButton.text=Show Images MessageContentViewer.showImagesToggleButton.hide.text=Hide Images -MessageContentViewer.htmlbodyScrollPane.TabConstraints.tabTitle=HTML +MessageContentViewer.htmlPane.TabConstraints.tabTitle=HTML diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form index a83f08d765..7c089d54a7 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.form @@ -3,7 +3,7 @@
- + @@ -21,22 +21,24 @@ - - - - + + + + + + + - + + - - - - + + @@ -53,53 +55,46 @@ - + - - - - - + - - - - + - + + + + + + - - - - - - - - - - - - - + + + + + + + + - + - + @@ -116,12 +111,12 @@ - + - + @@ -136,6 +131,7 @@ + @@ -192,6 +188,7 @@ + @@ -247,81 +244,64 @@ - + - + - + + + + + + + + + + + + + + + + + + + + + + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - + - - - + - - - + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java index bdd07871fc..fc1df57e6d 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MessageContentViewer.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.contentviewers; import java.awt.Component; import java.util.logging.Level; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.lookup.ServiceProvider; @@ -28,8 +30,6 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; /** * Shows SMS/MMS/EMail messages @@ -37,16 +37,16 @@ import org.jsoup.nodes.Document; @ServiceProvider(service = DataContentViewer.class, position = 4) public class MessageContentViewer extends javax.swing.JPanel implements DataContentViewer { - private static final Logger LOGGER = Logger.getLogger(MessageContentViewer.class.getName()); - + private static final int HDR_TAB_INDEX = 0; private static final int TEXT_TAB_INDEX = 1; private static final int HTML_TAB_INDEX = 2; private static final int RTF_TAB_INDEX = 3; - + private static final long serialVersionUID = 1L; + private BlackboardArtifact artifact; // Artifact currently being displayed - + /** * Creates new form MessageContentViewer */ @@ -80,20 +80,20 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont headersTextArea = new javax.swing.JTextArea(); textbodyScrollPane = new javax.swing.JScrollPane(); textbodyTextArea = new javax.swing.JTextArea(); - htmlbodyScrollPane = new javax.swing.JScrollPane(); - jPanel2 = new javax.swing.JPanel(); + htmlPane = new javax.swing.JPanel(); jScrollPane2 = new javax.swing.JScrollPane(); htmlbodyTextPane = new javax.swing.JTextPane(); showImagesToggleButton = new javax.swing.JToggleButton(); rtfbodyScrollPane = new javax.swing.JScrollPane(); rtfbodyTextPane = new javax.swing.JTextPane(); - setMinimumSize(new java.awt.Dimension(650, 546)); + setMinimumSize(null); envelopePanel.setBackground(new java.awt.Color(204, 204, 204)); org.openide.awt.Mnemonics.setLocalizedText(fromLabel, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.fromLabel.text")); // NOI18N + datetimeText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); org.openide.awt.Mnemonics.setLocalizedText(datetimeText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.datetimeText.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(fromText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.fromText.text")); // NOI18N @@ -110,6 +110,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont org.openide.awt.Mnemonics.setLocalizedText(subjectText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.subjectText.text")); // NOI18N + directionText.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); org.openide.awt.Mnemonics.setLocalizedText(directionText, org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.directionText.text")); // NOI18N javax.swing.GroupLayout envelopePanelLayout = new javax.swing.GroupLayout(envelopePanel); @@ -117,40 +118,36 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont envelopePanelLayout.setHorizontalGroup( envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() - .addContainerGap() + .addGap(5, 5, 5) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(fromLabel) .addComponent(toLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() - .addGap(8, 8, 8) - .addComponent(datetimeText)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, envelopePanelLayout.createSequentialGroup() + .addComponent(toText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(directionText)))) + .addComponent(directionText, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addComponent(fromText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(datetimeText, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addGroup(envelopePanelLayout.createSequentialGroup() - .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(envelopePanelLayout.createSequentialGroup() - .addComponent(ccLabel) - .addGap(18, 18, 18) - .addComponent(ccText)) - .addGroup(envelopePanelLayout.createSequentialGroup() - .addComponent(subjectLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(subjectText, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + .addComponent(ccLabel) + .addGap(26, 26, 26) + .addComponent(ccText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(envelopePanelLayout.createSequentialGroup() + .addComponent(subjectLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(subjectText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGap(5, 5, 5)) ); envelopePanelLayout.setVerticalGroup( envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(envelopePanelLayout.createSequentialGroup() - .addContainerGap() + .addGap(5, 5, 5) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(fromLabel) .addComponent(datetimeText) @@ -164,11 +161,11 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(ccLabel) .addComponent(ccText)) - .addGap(18, 18, 18) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(envelopePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(subjectLabel) .addComponent(subjectText)) - .addContainerGap(24, Short.MAX_VALUE)) + .addGap(5, 5, 5)) ); headersTextArea.setEditable(false); @@ -195,35 +192,26 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont } }); - javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap(536, Short.MAX_VALUE) + javax.swing.GroupLayout htmlPaneLayout = new javax.swing.GroupLayout(htmlPane); + htmlPane.setLayout(htmlPaneLayout); + htmlPaneLayout.setHorizontalGroup( + htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, htmlPaneLayout.createSequentialGroup() + .addContainerGap(533, Short.MAX_VALUE) .addComponent(showImagesToggleButton) - .addContainerGap()) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 623, Short.MAX_VALUE) - .addContainerGap())) + .addGap(3, 3, 3)) ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() + htmlPaneLayout.setVerticalGroup( + htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(htmlPaneLayout.createSequentialGroup() .addComponent(showImagesToggleButton) - .addContainerGap(333, Short.MAX_VALUE)) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addGap(0, 34, Short.MAX_VALUE) - .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 333, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane2) + .addGap(0, 0, 0)) ); - htmlbodyScrollPane.setViewportView(jPanel2); - - msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlbodyScrollPane.TabConstraints.tabTitle"), htmlbodyScrollPane); // NOI18N + msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); // NOI18N rtfbodyTextPane.setEditable(false); rtfbodyScrollPane.setViewportView(rtfbodyTextPane); @@ -234,37 +222,37 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) - .addComponent(msgbodyTabbedPane) + .addGroup(layout.createSequentialGroup() + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(msgbodyTabbedPane) + .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(5, 5, 5)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(envelopePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(5, 5, 5) + .addComponent(envelopePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(msgbodyTabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 397, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addComponent(msgbodyTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 471, Short.MAX_VALUE) + .addGap(0, 0, 0)) ); }// //GEN-END:initComponents private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed - + try { BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML)); if (attr != null && !attr.getValueString().isEmpty()) { - + if (showImagesToggleButton.isSelected()) { showImagesToggleButton.setText(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.hide.text")); - + this.htmlbodyTextPane.setText("" + attr.getValueString() + ""); - } - else { + } else { showImagesToggleButton.setText(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.showImagesToggleButton.text")); - + this.htmlbodyTextPane.setText("" + cleanseHTML(attr.getValueString()) + ""); } } @@ -284,9 +272,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private javax.swing.JLabel fromText; private javax.swing.JScrollPane headersScrollPane; private javax.swing.JTextArea headersTextArea; - private javax.swing.JScrollPane htmlbodyScrollPane; + private javax.swing.JPanel htmlPane; private javax.swing.JTextPane htmlbodyTextPane; - private javax.swing.JPanel jPanel2; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JTabbedPane msgbodyTabbedPane; private javax.swing.JScrollPane rtfbodyScrollPane; @@ -302,27 +289,30 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont private void customizeComponents() { // do any customizations here - Utilities.configureTextPaneAsHtml(htmlbodyTextPane); - Utilities.configureTextPaneAsRtf(rtfbodyTextPane); - + Utilities.configureTextPaneAsHtml(htmlbodyTextPane); + Utilities.configureTextPaneAsRtf(rtfbodyTextPane); + } - + @Override public void setNode(Node node) { - + + if (node == null) { + return; + } + artifact = node.getLookup().lookup(BlackboardArtifact.class); - + if (artifact == null) { return; } - + if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { displayMsg(); - } - else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { + } else if (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) { displayEmailMsg(); } - + } @Override @@ -352,211 +342,197 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont @Override public boolean isSupported(Node node) { - BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); - return ( (artifact != null) + BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); + return ((artifact != null) && ((artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) || (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()))); } @Override public int isPreferred(Node node) { - - if ( isSupported(node)){ + + if (isSupported(node)) { return 6; } return 0; } - - - private void displayEmailMsg() - { + + private void displayEmailMsg() { directionText.setVisible(false); - + showImagesToggleButton.setVisible(false); showImagesToggleButton.setText("Show Images"); showImagesToggleButton.setSelected(false); - + try { BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM)); this.fromText.setText(attr.getValueString()); - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO)); if (attr != null) { - this.toText.setText(attr.getValueString()); + this.toText.setText(attr.getValueString()); } - - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC)); if (attr != null && !attr.getValueString().isEmpty()) { this.ccText.setVisible(true); this.ccText.setText(attr.getValueString()); - } - else { + } else { this.ccText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)); if (attr != null && !attr.getValueString().isEmpty()) { this.subjectText.setVisible(true); this.subjectText.setText(attr.getValueString()); - } - else { + } else { this.subjectText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD)); if (attr != null && !attr.getDisplayString().isEmpty()) { this.datetimeText.setVisible(true); this.datetimeText.setText(attr.getDisplayString()); - } - else { + } else { this.datetimeText.setVisible(false); } - + int selectedTabIndex = -1; attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN)); if (attr != null && !attr.getValueString().isEmpty()) { this.textbodyTextArea.setVisible(true); this.textbodyTextArea.setText(attr.getValueString()); - + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); selectedTabIndex = TEXT_TAB_INDEX; - } - else { + } else { msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML)); if (attr != null && !attr.getValueString().isEmpty()) { - + this.showImagesToggleButton.setVisible(true); - - + this.htmlbodyTextPane.setVisible(true); this.htmlbodyTextPane.setText("" + cleanseHTML(attr.getValueString()) + ""); //this.htmlbodyTextPane.setText(cleanseHTML(attr.getValueString())); - + msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, true); selectedTabIndex = HTML_TAB_INDEX; - } - else { + } else { msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); this.htmlbodyTextPane.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF)); if (attr != null && !attr.getValueString().isEmpty()) { - + this.rtfbodyTextPane.setVisible(true); this.rtfbodyTextPane.setText(attr.getValueString()); - + msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, true); selectedTabIndex = RTF_TAB_INDEX; - } - else { + } else { msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_HEADERS)); if (attr != null && !attr.getValueString().isEmpty()) { this.headersTextArea.setVisible(true); this.headersTextArea.setText(attr.getValueString()); if (selectedTabIndex < 0) { - selectedTabIndex = HDR_TAB_INDEX; + selectedTabIndex = HDR_TAB_INDEX; } - } - else { + } else { msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); } - + msgbodyTabbedPane.setSelectedIndex(selectedTabIndex); - } - catch (TskCoreException ex) { + } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS } } - + private void displayMsg() { - + this.ccText.setVisible(false); this.showImagesToggleButton.setVisible(false); msgbodyTabbedPane.setEnabledAt(HTML_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(RTF_TAB_INDEX, false); msgbodyTabbedPane.setEnabledAt(HDR_TAB_INDEX, false); - + try { - + BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)); if (attr != null) { this.fromText.setText(attr.getValueString()); - }else { - this.fromText.setVisible(false); + } else { + this.fromText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)); if (attr != null) { - this.toText.setText(attr.getValueString()); - }else { - this.toText.setVisible(false); + this.toText.setText(attr.getValueString()); + } else { + this.toText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION)); if (attr != null) { - this.directionText.setText(attr.getValueString()); - }else { - this.directionText.setVisible(false); + this.directionText.setText(attr.getValueString()); + } else { + this.directionText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT)); if (attr != null && !attr.getValueString().isEmpty()) { this.subjectText.setVisible(true); this.subjectText.setText(attr.getValueString()); - } - else { + } else { this.subjectText.setVisible(false); } - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)); if (attr != null && !attr.getDisplayString().isEmpty()) { this.datetimeText.setVisible(true); this.datetimeText.setText(attr.getDisplayString()); - } - else { + } else { this.datetimeText.setVisible(false); } - - + attr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT)); if (attr != null && !attr.getValueString().isEmpty()) { this.textbodyTextArea.setVisible(true); this.textbodyTextArea.setText(attr.getValueString()); - + msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, true); - } - else { + } else { msgbodyTabbedPane.setEnabledAt(TEXT_TAB_INDEX, false); } msgbodyTabbedPane.setSelectedIndex(TEXT_TAB_INDEX); - } - catch (TskCoreException ex) { + } catch (TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to get attributes for message.", ex); //NON-NLS } - + } - + /** * Cleans out input HTML string + * + * @param htmlInString The HTML string to cleanse + * + * @return The cleansed HTML String */ - private String cleanseHTML(String htmlInString) { - + private String cleanseHTML(String htmlInString) { + Document doc = Jsoup.parse(htmlInString); - + // fix all img tags doc.select("img[src]").forEach((img) -> { img.attr("src", ""); }); return doc.html(); - } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java index 92d0e39547..f51f558f74 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataContent.java @@ -20,12 +20,10 @@ package org.sleuthkit.autopsy.corecomponentinterfaces; import java.beans.PropertyChangeListener; import org.openide.nodes.Node; -import org.openide.windows.TopComponent; /** * The interface for the "bottom right component" window. * - * @author jantonius */ public interface DataContent extends PropertyChangeListener { diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index 34397cf960..e5252e035b 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -22,6 +22,7 @@ import java.awt.Cursor; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; @@ -260,11 +261,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C */ @Override public List getViewers() { - List viewers = new ArrayList<>(); - resultViewers.forEach((viewer) -> { - viewers.add(viewer); - }); - return viewers; + return Collections.unmodifiableList(resultViewers); } /** @@ -397,9 +394,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * @param selectedNodes The nodes to be selected. */ public void setSelectedNodes(Node[] selectedNodes) { - this.resultViewers.forEach((viewer) -> { - viewer.setSelectedNodes(selectedNodes); - }); + this.resultViewers.forEach((viewer) -> viewer.setSelectedNodes(selectedNodes)); } /** @@ -517,14 +512,10 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C explorerManager = null; } - this.resultViewers.forEach((viewer) -> { - viewer.setNode(null); - }); + this.resultViewers.forEach((viewer) -> viewer.setNode(null)); if (!this.isMain) { - this.resultViewers.forEach((viewer) -> { - viewer.clearComponent(); - }); + this.resultViewers.forEach(DataResultViewer::clearComponent); this.directoryTablePath.removeAll(); this.directoryTablePath = null; this.numberMatchLabel.removeAll(); @@ -563,9 +554,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C * Pass the selected nodes to all of the result viewers * sharing this explorer manager. */ - resultViewers.forEach((viewer) -> { - viewer.setSelectedNodes(selectedNodes); - }); + resultViewers.forEach((viewer) -> viewer.setSelectedNodes(selectedNodes)); /* * Passing null signals that either multiple nodes are diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index e922e74c4f..c09ebc92f3 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -764,7 +764,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); // only override the color if a node is not selected - if (!isSelected) { + if (currentRoot != null && !isSelected) { Node node = currentRoot.getChildren().getNodeAt(table.convertRowIndexToModel(row)); boolean tagFound = false; if (node != null) {