From a60dd923849505aba58bbd08265d63c0d9fcff62 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Thu, 6 Oct 2016 10:06:21 -0400 Subject: [PATCH 01/10] Rows initially colored, does not update upon tag addition or reordering --- .../corecomponents/DataResultViewerTable.java | 42 ++++++++++++++++++- .../datamodel/AbstractAbstractFileNode.java | 16 +++++++ .../datamodel/AbstractFsContentNode.java | 5 ++- .../datamodel/BlackboardArtifactNode.java | 18 ++++++++ .../autopsy/datamodel/Bundle.properties | 5 +++ .../autopsy/datamodel/LayoutFileNode.java | 5 ++- .../autopsy/datamodel/LocalFileNode.java | 4 +- 7 files changed, 90 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 8ea3846945..fb7f8acefb 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.corecomponents; +import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.FontMetrics; @@ -41,6 +42,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableColumnModelEvent; import javax.swing.event.TableColumnModelListener; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import org.netbeans.swing.outline.DefaultOutlineModel; import org.openide.explorer.ExplorerManager; @@ -55,6 +57,7 @@ import org.openide.nodes.NodeListener; import org.openide.nodes.NodeMemberEvent; import org.openide.nodes.NodeReorderEvent; import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; @@ -413,7 +416,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { for (int column = 0; column < ov.getOutline().getModel().getColumnCount(); column++) { int firstColumnPadding = (column == 0) ? 32 : 0; - int columnWidthLimit = (column == 0) ? 250 : 350; + int columnWidthLimit = (column == 0) ? 250 : 300; int valuesWidth = 0; // find the maximum width needed to fit the values for the first 30 rows, at most @@ -439,9 +442,44 @@ public class DataResultViewerTable extends AbstractDataResultViewer { ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); } } + // Node[] childrenNodes = currentRoot.getChildren().getNodes(); + final TableCellRenderer DEFAULT_RENDERER = ov.getOutline().getDefaultRenderer(Object.class); + final Color TAGGED_COLOR = new Color(230, 235, 240); + final Color SELECTED_COLOR = new Color(51, 153, 255); + + + class CustomRenderer extends DefaultTableCellRenderer { + private static final long serialVersionUID = 1L; + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, boolean isSelected, boolean hasFocus, int row, int col) { + Component component = DEFAULT_RENDERER.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + + if (col != 0) { + try { + int tag_col = ov.getOutline().getColumnModel().getColumnIndex("Tags"); + Property cellProp = (Property)(table.getModel().getValueAt(row, tag_col)); + if (cellProp != null) { + String valueString = cellProp.getValue().toString();//((Property) value).getValue().toString(); + if (!valueString.equals("")) { + component.setBackground(TAGGED_COLOR); + if (isSelected) { + component.setBackground(SELECTED_COLOR); + } + } + } + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { + } + + } + return component; + } + } + ov.getOutline().setDefaultRenderer(Object.class, new CustomRenderer()); + } } - + /** * Store the current column order into a preference file. */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 0458ec9a59..f8865898da 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -20,10 +20,13 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.List; import org.openide.nodes.Children; import java.util.Map; import java.util.logging.Level; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; @@ -31,6 +34,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -278,6 +282,18 @@ public abstract class AbstractAbstractFileNode extends A map.put(AbstractFilePropertyType.MIMETYPE.toString(), content.getMIMEType() == null ? "" : content.getMIMEType()); } + static void addTagProperty(Sheet.Set ss, Content content) { + final String NO_DESCR = NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.desc"); + try { + List tags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content); + ss.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.name"), + NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); + } + } + static String getContentDisplayName(AbstractFile file) { String name = file.getName(); switch (name) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 5beca1dbc4..82de781b50 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -84,7 +84,10 @@ public abstract class AbstractFsContentNode extends Abst ss.put(new NodeProperty<>(HIDE_PARENT, HIDE_PARENT, HIDE_PARENT, HIDE_PARENT)); } + // add tags property to the sheet + AbstractAbstractFileNode.addTagProperty(ss, content); + return s; } - + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index bee4cba0a8..81c263980f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -25,6 +25,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; +import java.util.stream.Collectors; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Children; @@ -40,9 +41,12 @@ import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; +import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.ContentTag; +import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -209,6 +213,20 @@ public class BlackboardArtifactNode extends DisplayableItemNode { ss.put(np); } } + + // add properties for tags + try { + List artifactTags = Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact); + List contentTags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(associated); + List tags = new ArrayList<>(artifactTags); + tags.addAll(contentTags); + ss.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.name"), + NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); + } + final int artifactTypeId = artifact.getArtifactTypeID(); // If mismatch, add props for extension and file type diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties index ffe0797410..3134bd563d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties @@ -281,3 +281,8 @@ DeleteReportAction.actionDisplayName.multipleReports=Delete Reports DeleteReportAction.actionPerformed.showConfirmDialog.title=Confirm Deletion DeleteReportAction.actionPerformed.showConfirmDialog.single.msg=Do you want to delete 1 report from the case? DeleteReportAction.actionPerformed.showConfirmDialog.multiple.msg=Do you want to delete {0} reports from the case? +AbstractAbstractFileNode.addFileProperty.desc=no description +AbstractAbstractFileNode.addFileProperty.tags.name=Tags +AbstractAbstractFileNode.addFileProperty.tags.displayName=Tags +BlackboardArtifactNode.createSheet.tags.name=Tags +BlackboardArtifactNode.createSheet.tags.displayName=Tags \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java index 0e97757401..878f0809aa 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java @@ -39,7 +39,7 @@ import org.sleuthkit.datamodel.TskData; public class LayoutFileNode extends AbstractAbstractFileNode { public static enum LayoutContentPropertyType { - + PARTS { @Override public String toString() { @@ -86,6 +86,9 @@ public class LayoutFileNode extends AbstractAbstractFileNode { ss.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } + // add tags property to the sheet + AbstractAbstractFileNode.addTagProperty(ss, content); + return s; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index e2f701d044..9e3c40b595 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -74,7 +74,9 @@ public class LocalFileNode extends AbstractAbstractFileNode { for (Map.Entry entry : map.entrySet()) { ss.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } - // @@@ add more properties here... + + // add tags property to the sheet + AbstractAbstractFileNode.addTagProperty(ss, content); return s; } From 83818aefb0ca9641833e93f5fe0418e3f15069f6 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Wed, 19 Oct 2016 17:00:58 -0400 Subject: [PATCH 02/10] Added listening to tag events for various nodes and node factories --- .../corecomponents/DataResultViewerTable.java | 2 +- .../datamodel/AbstractAbstractFileNode.java | 5 +- .../datamodel/BlackboardArtifactNode.java | 5 +- .../datamodel/BlackboardArtifactTagNode.java | 10 +++- .../autopsy/datamodel/ContentTagNode.java | 9 ++++ .../autopsy/datamodel/DataSourcesNode.java | 13 +++-- .../autopsy/datamodel/DeletedContent.java | 5 ++ .../autopsy/datamodel/EmailExtracted.java | 6 +++ .../autopsy/datamodel/ExtractedContent.java | 28 ++++++++++- .../sleuthkit/autopsy/datamodel/FileSize.java | 5 ++ .../autopsy/datamodel/FileTypesNode.java | 6 +++ .../autopsy/datamodel/HashsetHits.java | 6 +++ .../autopsy/datamodel/InterestingHits.java | 6 +++ .../autopsy/datamodel/KeywordHits.java | 47 ++++++++++++------- .../org/sleuthkit/autopsy/datamodel/Tags.java | 20 ++++---- .../autopsy/datamodel/accounts/Accounts.java | 37 ++++++++++++++- .../DirectoryTreeTopComponent.java | 1 + 17 files changed, 169 insertions(+), 42 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index fb7f8acefb..dfb84c642b 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -458,7 +458,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { if (col != 0) { try { int tag_col = ov.getOutline().getColumnModel().getColumnIndex("Tags"); - Property cellProp = (Property)(table.getModel().getValueAt(row, tag_col)); + Property cellProp = (Property)(table.getModel().getValueAt(row, tag_col)); if (cellProp != null) { String valueString = cellProp.getValue().toString();//((Property) value).getValue().toString(); if (!valueString.equals("")) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index f8865898da..b8c61fcbcf 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -286,9 +286,8 @@ public abstract class AbstractAbstractFileNode extends A final String NO_DESCR = NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.desc"); try { List tags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content); - ss.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.name"), - NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 7ceb7fbb40..1bbbc2149a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -219,9 +219,8 @@ public class BlackboardArtifactNode extends DisplayableItemNode { List contentTags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(associated); List tags = new ArrayList<>(artifactTags); tags.addAll(contentTags); - ss.put(new NodeProperty<>(NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.name"), - NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.displayName"), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index 3ff339e98d..d2620e85cd 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -22,12 +22,14 @@ import java.text.MessageFormat; import java.util.Arrays; import java.util.List; import java.util.logging.Level; +import java.util.stream.Collectors; import javax.swing.Action; 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.actions.DeleteBlackboardArtifactTagAction; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; @@ -93,7 +95,13 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.comment.text"), "", tag.getComment())); - + try { + List tags = Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(tag.getArtifact()); + properties.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), + "", tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } catch (TskCoreException ex) { + //LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); + } return propertySheet; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java index a1d78644dd..37599dc5c8 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java @@ -21,12 +21,14 @@ package org.sleuthkit.autopsy.datamodel; import java.util.Arrays; import java.util.List; import java.util.logging.Level; +import java.util.stream.Collectors; import javax.swing.Action; 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.actions.DeleteContentTagAction; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; @@ -103,6 +105,13 @@ class ContentTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"), "", content.getSize())); + try { + List tags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content); + properties.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), + "", tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } catch (TskCoreException ex) { + //LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); + } return propertySheet; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java index 73f4d95cd0..6343a79d7d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * + * * Copyright 2011-2014 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. @@ -81,6 +81,11 @@ public class DataSourcesNode extends DisplayableItemNode { String eventType = evt.getPropertyName(); if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) { reloadKeys(); + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + reloadKeys(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java index 3096a3e552..52c1b4be47 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java @@ -230,6 +230,11 @@ public class DeletedContent implements AutopsyVisitableItem { removeListeners(); } maxFilesDialogShown = false; + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java index 9f8d3d9bd1..1e61078765 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java @@ -269,6 +269,12 @@ public class EmailExtracted implements AutopsyVisitableItem { removeNotify(); skCase = null; } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + refresh(true); + emailResults.update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java index 896cec5322..ff4d9e259d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java @@ -244,9 +244,21 @@ public class ExtractedContent implements AutopsyVisitableItem { removeNotify(); skCase = null; } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + try { + Case.getCurrentCase(); + refresh(true); + } catch (IllegalStateException notUsed) { + /** + * Case is closed, do nothing. + */ + } } }; - + @Override protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); @@ -431,6 +443,18 @@ public class ExtractedContent implements AutopsyVisitableItem { * Case is closed, do nothing. */ } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + try { + Case.getCurrentCase(); + refresh(true); + } catch (IllegalStateException notUsed) { + /** + * Case is closed, do nothing. + */ + } } } }; @@ -439,12 +463,14 @@ public class ExtractedContent implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); + Case.addPropertyChangeListener(pcl); } @Override protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); + Case.removePropertyChangeListener(pcl); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java index c250166c3b..769f15973a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java @@ -226,6 +226,11 @@ public class FileSize implements AutopsyVisitableItem { if (evt.getNewValue() == null) { removeListeners(); } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java index daf1a31780..2c40f3e45d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java @@ -192,6 +192,12 @@ public class FileTypesNode extends DisplayableItemNode { if (evt.getNewValue() == null) { removeListeners(); } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + refresh(true); + update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java index 5305df440b..068d9a44e5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java @@ -243,6 +243,12 @@ public class HashsetHits implements AutopsyVisitableItem { removeNotify(); skCase = null; } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + refresh(true); + hashsetResults.update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java index 872b5bcb25..e898ed448c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java @@ -236,6 +236,12 @@ public class InterestingHits implements AutopsyVisitableItem { removeNotify(); skCase = null; } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + refresh(true); + interestingResults.update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index f81fd46e08..d7e95412bf 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -202,6 +202,9 @@ public class KeywordHits implements AutopsyVisitableItem { logger.log(Level.WARNING, "SQL Exception occurred: ", ex); //NON-NLS } + setChanged(); + notifyObservers(); + populateMaps(artifactIds); } } @@ -306,6 +309,12 @@ public class KeywordHits implements AutopsyVisitableItem { removeNotify(); skCase = null; } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) + || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + refresh(true); + keywordResults.update(); } } }; @@ -409,24 +418,25 @@ public class KeywordHits implements AutopsyVisitableItem { } } - private class TermFactory extends ChildFactory.Detachable implements Observer { + private class TermFactory extends ChildFactory implements Observer { private String setName; private TermFactory(String setName) { super(); this.setName = setName; - } - - @Override - protected void addNotify() { keywordResults.addObserver(this); } - @Override - protected void removeNotify() { - keywordResults.deleteObserver(this); - } +// @Override +// protected void addNotify() { +// keywordResults.addObserver(this); +// } +// +// @Override +// protected void removeNotify() { +// keywordResults.deleteObserver(this); +// } @Override protected boolean createKeys(List list) { @@ -507,7 +517,7 @@ public class KeywordHits implements AutopsyVisitableItem { } } - public class HitsFactory extends ChildFactory.Detachable implements Observer { + public class HitsFactory extends ChildFactory implements Observer { private String keyword; private String setName; @@ -516,17 +526,18 @@ public class KeywordHits implements AutopsyVisitableItem { super(); this.setName = setName; this.keyword = keyword; - } - - @Override - protected void addNotify() { keywordResults.addObserver(this); } - @Override - protected void removeNotify() { - keywordResults.deleteObserver(this); - } +// @Override +// protected void addNotify() { +// keywordResults.addObserver(this); +// } +// +// @Override +// protected void removeNotify() { +// keywordResults.deleteObserver(this); +// } @Override protected boolean createKeys(List list) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java index 2d89ef3cca..1e5c71c813 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * + * * Copyright 2011-2015 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. @@ -46,8 +46,8 @@ import org.sleuthkit.datamodel.TskCoreException; * factory built on top of the NetBeans Children.Keys class. */ public class Tags implements AutopsyVisitableItem { - // Creation of a RootNode object corresponding to a Tags object is done - // by a CreateAutopsyNodeVisitor dispatched from the AbstractContentChildren + // Creation of a RootNode object corresponding to a Tags object is done + // by a CreateAutopsyNodeVisitor dispatched from the AbstractContentChildren // override of Children.Keys.createNodes(). private final TagResults tagResults = new TagResults(); @@ -134,7 +134,7 @@ public class Tags implements AutopsyVisitableItem { */ try { Case.getCurrentCase(); - refresh(true); + //refresh(true); tagResults.update(); } catch (IllegalStateException notUsed) { /** @@ -203,7 +203,7 @@ public class Tags implements AutopsyVisitableItem { @Override public void update(Observable o, Object arg) { - refresh(true); + //refresh(true); } } @@ -409,7 +409,7 @@ public class Tags implements AutopsyVisitableItem { @Override public void update(Observable o, Object arg) { - refresh(true); + refresh(true); //this caused table to update } } @@ -505,7 +505,7 @@ public class Tags implements AutopsyVisitableItem { // The blackboard artifact tags to be wrapped are used as the keys. return new BlackboardArtifactTagNode(key); } - + @Override public void update(Observable o, Object arg) { refresh(true); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 71b0b6492e..84b954eb70 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -320,11 +320,16 @@ final public class Accounts implements AutopsyVisitableItem { public boolean isLeafTypeNode() { return false; } - + @Override public T accept(DisplayableItemNodeVisitor v) { return v.visit(this); } + + @Override + public String getItemType() { + return getClass().getName(); + } } /** @@ -395,6 +400,11 @@ final public class Accounts implements AutopsyVisitableItem { public T accept(DisplayableItemNodeVisitor v) { return v.visit(this); } + + @Override + public String getItemType() { + return getClass().getName(); + } } /** @@ -460,6 +470,11 @@ final public class Accounts implements AutopsyVisitableItem { public T accept(DisplayableItemNodeVisitor v) { return v.visit(this); } + + @Override + public String getItemType() { + return getClass().getName(); + } } /** @@ -578,6 +593,11 @@ final public class Accounts implements AutopsyVisitableItem { return v.visit(this); } + @Override + public String getItemType() { + return getClass().getName(); + } + @Subscribe public void handleReviewStatusChange(ReviewStatusChangeEvent event) { updateDisplayName(); @@ -692,6 +712,11 @@ final public class Accounts implements AutopsyVisitableItem { return v.visit(this); } + @Override + public String getItemType() { + return getClass().getName(); + } + @Subscribe public void handleReviewStatusChange(ReviewStatusChangeEvent event) { updateDisplayName(); @@ -871,6 +896,11 @@ final public class Accounts implements AutopsyVisitableItem { return v.visit(this); } + @Override + public String getItemType() { + return getClass().getName(); + } + @Override @NbBundle.Messages({ "Accounts.FileWithCCNNode.nameProperty.displayName=File", @@ -1036,6 +1066,11 @@ final public class Accounts implements AutopsyVisitableItem { return v.visit(this); } + @Override + public String getItemType() { + return getClass().getName(); + } + private Sheet.Set getPropertySet(Sheet s) { Sheet.Set ss = s.get(Sheet.PROPERTIES); if (ss == null) { diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 0a7308b065..8f63752a27 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -60,6 +60,7 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode; import org.sleuthkit.autopsy.datamodel.DataSources; import org.sleuthkit.autopsy.datamodel.DataSourcesNode; +import org.sleuthkit.autopsy.datamodel.DisplayableItemNode; import org.sleuthkit.autopsy.datamodel.ExtractedContent; import org.sleuthkit.autopsy.datamodel.KeywordHits; import org.sleuthkit.autopsy.datamodel.KnownFileFilterNode; From d961e4baa6d0410777abff4694be7e73a2ab50bb Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Fri, 21 Oct 2016 16:50:56 -0400 Subject: [PATCH 03/10] Modified table coloring method, reordering and filtering now work --- .../corecomponents/DataResultViewerTable.java | 71 ++++++++++++------- .../datamodel/AbstractAbstractFileNode.java | 10 +-- .../datamodel/BlackboardArtifactNode.java | 13 ++-- .../datamodel/BlackboardArtifactTagNode.java | 13 ++-- .../autopsy/datamodel/ContentTagNode.java | 17 +++-- .../autopsy/datamodel/DataSourcesNode.java | 5 -- .../autopsy/datamodel/KeywordHits.java | 8 +-- .../org/sleuthkit/autopsy/datamodel/Tags.java | 4 +- 8 files changed, 84 insertions(+), 57 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index dfb84c642b..d850b99282 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -42,8 +42,8 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableColumnModelEvent; import javax.swing.event.TableColumnModelListener; -import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; +import org.netbeans.swing.outline.DefaultOutlineCellRenderer; import org.netbeans.swing.outline.DefaultOutlineModel; import org.openide.explorer.ExplorerManager; import org.openide.explorer.view.OutlineView; @@ -60,8 +60,12 @@ import org.openide.nodes.Sheet; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; +import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.TskCoreException; /** * DataResult sortable table viewer @@ -77,6 +81,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private final Set> propertiesAcc = new LinkedHashSet<>(); private final DummyNodeListener dummyNodeListener = new DummyNodeListener(); private static final String DUMMY_NODE_DISPLAY_NAME = NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.dummyNodeDisplayName"); + private static final Color TAGGED_COLOR = new Color(230, 235, 240); private Node currentRoot; // The following two variables keep track of whether the user is trying // to move the first column, which is not allowed. @@ -114,6 +119,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { ov.getOutline().setRootVisible(false); ov.getOutline().setDragEnabled(false); + // add a listener so that when columns are moved, the new order is stored ov.getOutline().getColumnModel().addColumnModelListener(new TableColumnModelListener() { @Override public void columnAdded(TableColumnModelEvent e) { @@ -134,7 +140,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { if (fromIndex == toIndex) { return; } - // To keep track of attempts to move the first column + // to keep track of attempts to move the first column if (oldColumnIndex == -1) { oldColumnIndex = fromIndex; } @@ -151,6 +157,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { } }); + // add a listener to move columns back if user tries to move the first column out of place ov.getOutline().getTableHeader().addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { @@ -442,41 +449,55 @@ public class DataResultViewerTable extends AbstractDataResultViewer { ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); } } - // Node[] childrenNodes = currentRoot.getChildren().getNodes(); - final TableCellRenderer DEFAULT_RENDERER = ov.getOutline().getDefaultRenderer(Object.class); - final Color TAGGED_COLOR = new Color(230, 235, 240); - final Color SELECTED_COLOR = new Color(51, 153, 255); - - - class CustomRenderer extends DefaultTableCellRenderer { + + /** + * This custom renderer extends the renderer that was already being + * used by the outline table. This renderer colors a row if the file + * or artifact associated with the row's node is tagged. + */ + class ColorTagCustomRenderer extends DefaultOutlineCellRenderer { private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { - Component component = DEFAULT_RENDERER.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); - - if (col != 0) { - try { - int tag_col = ov.getOutline().getColumnModel().getColumnIndex("Tags"); - Property cellProp = (Property)(table.getModel().getValueAt(row, tag_col)); - if (cellProp != null) { - String valueString = cellProp.getValue().toString();//((Property) value).getValue().toString(); - if (!valueString.equals("")) { - component.setBackground(TAGGED_COLOR); - if (isSelected) { - component.setBackground(SELECTED_COLOR); + + Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + if (!isSelected) { + Node node = currentRoot.getChildren().getNodeAt(table.convertRowIndexToModel(row)); + boolean tagFound = false; + if (node != null) { + //see if there is a blackboard artifact at the node and whether the artifact is tagged + BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); + if (artifact != null) { + try { + tagFound = !Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact).isEmpty(); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + } + + //if no tags have been found yet, see if the abstract file at the node is tagged + if (!tagFound) { + AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class); + if (abstractFile != null) { + try { + tagFound = !Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(abstractFile).isEmpty(); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); } } } - } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { + + //if the node does have associated tags, set its background color + if (tagFound) { + component.setBackground(TAGGED_COLOR); + } } - } return component; } } - ov.getOutline().setDefaultRenderer(Object.class, new CustomRenderer()); - + ov.getOutline().setDefaultRenderer(Object.class, new ColorTagCustomRenderer()); } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index b8c61fcbcf..4cd37bed03 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.ArrayList; import java.util.List; import org.openide.nodes.Children; import java.util.Map; @@ -34,7 +35,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.ContentTag; +import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -284,13 +285,14 @@ public abstract class AbstractAbstractFileNode extends A static void addTagProperty(Sheet.Set ss, Content content) { final String NO_DESCR = NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.desc"); + List tags = new ArrayList<>(); try { - List tags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content); - ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content)); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); } + ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } static String getContentDisplayName(AbstractFile file) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 1bbbc2149a..b10c867c9b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -41,11 +41,9 @@ import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; -import org.sleuthkit.datamodel.BlackboardArtifactTag; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; @@ -214,16 +212,15 @@ public class BlackboardArtifactNode extends DisplayableItemNode { } // add properties for tags + List tags = new ArrayList<>(); try { - List artifactTags = Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact); - List contentTags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(associated); - List tags = new ArrayList<>(artifactTags); - tags.addAll(contentTags); - ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.displayName"), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); + tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(associated)); } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); } + ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); final int artifactTypeId = artifact.getArtifactTypeID(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index d2620e85cd..86fce1ab78 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.datamodel; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; @@ -37,6 +38,7 @@ import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifactTag; +import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -95,13 +97,16 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.comment.text"), "", tag.getComment())); + + List tags = new ArrayList<>(); try { - List tags = Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(tag.getArtifact()); - properties.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), - "", tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(tag.getArtifact())); } catch (TskCoreException ex) { - //LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); + Logger.getLogger(ContentTagNode.class.getName()).log(Level.SEVERE, "Failed to get tags for artifact " + tag.getArtifact().getDisplayName(), ex); } + properties.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), + "", tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + return propertySheet; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java index 37599dc5c8..7569bc25d4 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; @@ -34,6 +35,7 @@ import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentTag; +import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -44,6 +46,8 @@ import org.sleuthkit.datamodel.TskCoreException; */ class ContentTagNode extends DisplayableItemNode { + private static final Logger LOGGER = Logger.getLogger(ContentTagNode.class.getName()); + private static final String ICON_PATH = "org/sleuthkit/autopsy/images/blue-tag-icon-16.png"; //NON-NLS private final ContentTag tag; @@ -62,7 +66,7 @@ class ContentTagNode extends DisplayableItemNode { try { contentPath = content.getUniquePath(); } catch (TskCoreException ex) { - Logger.getLogger(ContentTagNode.class.getName()).log(Level.SEVERE, "Failed to get path for content (id = " + content.getId() + ")", ex); //NON-NLS + LOGGER.log(Level.SEVERE, "Failed to get path for content (id = " + content.getId() + ")", ex); //NON-NLS contentPath = NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.unavail.path"); } AbstractFile file = content instanceof AbstractFile ? (AbstractFile) content : null; @@ -105,13 +109,16 @@ class ContentTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"), "", content.getSize())); + + List tags = new ArrayList<>(); try { - List tags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content); - properties.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), - "", tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content)); } catch (TskCoreException ex) { - //LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); + LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); } + properties.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), + "", tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + return propertySheet; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java index 6343a79d7d..6b4d425fbb 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java @@ -81,11 +81,6 @@ public class DataSourcesNode extends DisplayableItemNode { String eventType = evt.getPropertyName(); if (eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) { reloadKeys(); - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - reloadKeys(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index d7e95412bf..fec18d7c45 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -202,10 +202,10 @@ public class KeywordHits implements AutopsyVisitableItem { logger.log(Level.WARNING, "SQL Exception occurred: ", ex); //NON-NLS } + populateMaps(artifactIds); + setChanged(); notifyObservers(); - - populateMaps(artifactIds); } } @@ -519,8 +519,8 @@ public class KeywordHits implements AutopsyVisitableItem { public class HitsFactory extends ChildFactory implements Observer { - private String keyword; - private String setName; + private final String keyword; + private final String setName; public HitsFactory(String setName, String keyword) { super(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java index 1e5c71c813..d3f9d6688f 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java @@ -134,7 +134,7 @@ public class Tags implements AutopsyVisitableItem { */ try { Case.getCurrentCase(); - //refresh(true); + refresh(true); tagResults.update(); } catch (IllegalStateException notUsed) { /** @@ -203,7 +203,7 @@ public class Tags implements AutopsyVisitableItem { @Override public void update(Observable o, Object arg) { - //refresh(true); + refresh(true); } } From e35faceb08834d22ae368e73aeee372e6650e8d3 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 25 Oct 2016 14:12:14 -0400 Subject: [PATCH 04/10] Now working, using property getValue to color, adding listeners at node to update --- .../casemodule/events/TagAddedEvent.java | 2 +- .../corecomponents/DataResultViewerTable.java | 67 ++++++++----------- .../datamodel/AbstractAbstractFileNode.java | 20 +++++- .../datamodel/AbstractFsContentNode.java | 2 +- .../datamodel/BlackboardArtifactNode.java | 49 ++++++++++++++ .../autopsy/datamodel/ExtractedContent.java | 4 +- .../autopsy/datamodel/KeywordHits.java | 13 +--- .../autopsy/datamodel/LayoutFileNode.java | 2 +- .../autopsy/datamodel/LocalFileNode.java | 2 +- 9 files changed, 103 insertions(+), 58 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/events/TagAddedEvent.java b/Core/src/org/sleuthkit/autopsy/casemodule/events/TagAddedEvent.java index 365a3c0ff8..1f679c47a3 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/events/TagAddedEvent.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/events/TagAddedEvent.java @@ -39,7 +39,7 @@ abstract class TagAddedEvent extends AutopsyEvent implements Seri private transient T tag; /** - * The id of the tag that was added. This will bu used to re-load the + * The id of the tag that was added. This will be used to re-load the * transient tag from the database. */ private final Long tagID; diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index d850b99282..57ff03168f 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -60,18 +60,14 @@ import org.openide.nodes.Sheet; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.BlackboardArtifact; -import org.sleuthkit.datamodel.TskCoreException; /** * DataResult sortable table viewer */ -// @@@ Restore implementation of DataResultViewerTable as a DataResultViewer -// service provider when DataResultViewers can be made compatible with node +// @@@ Restore implementation of DataResultViewerTable as a DataResultViewer +// service provider when DataResultViewers can be made compatible with node // multiple selection actions. //@ServiceProvider(service = DataResultViewer.class) public class DataResultViewerTable extends AbstractDataResultViewer { @@ -166,7 +162,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { } oldColumnIndex = -1; } - }); + }); } /** @@ -423,11 +419,12 @@ public class DataResultViewerTable extends AbstractDataResultViewer { for (int column = 0; column < ov.getOutline().getModel().getColumnCount(); column++) { int firstColumnPadding = (column == 0) ? 32 : 0; - int columnWidthLimit = (column == 0) ? 250 : 300; + int columnWidthLimit = (column == 0) ? 350 : 300; int valuesWidth = 0; - // find the maximum width needed to fit the values for the first 30 rows, at most - for (int row = 0; row < Math.min(30, ov.getOutline().getRowCount()); row++) { + // find the maximum width needed to fit the values for the first 15 rows, at most + // *15 is an arbitrary number + for (int row = 0; row < Math.min(15, ov.getOutline().getRowCount()); row++) { TableCellRenderer renderer = ov.getOutline().getCellRenderer(row, column); Component comp = ov.getOutline().prepareRenderer(renderer, row, column); valuesWidth = Math.max(comp.getPreferredSize().width, valuesWidth); @@ -466,32 +463,26 @@ public class DataResultViewerTable extends AbstractDataResultViewer { Node node = currentRoot.getChildren().getNodeAt(table.convertRowIndexToModel(row)); boolean tagFound = false; if (node != null) { - //see if there is a blackboard artifact at the node and whether the artifact is tagged - BlackboardArtifact artifact = node.getLookup().lookup(BlackboardArtifact.class); - if (artifact != null) { - try { - tagFound = !Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact).isEmpty(); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); - } - } + Node.PropertySet[] propSets = node.getPropertySets(); - //if no tags have been found yet, see if the abstract file at the node is tagged - if (!tagFound) { - AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class); - if (abstractFile != null) { - try { - tagFound = !Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(abstractFile).isEmpty(); - } catch (TskCoreException ex) { - Exceptions.printStackTrace(ex); + if (propSets.length != 0) { + Node.Property[] props = propSets[0].getProperties(); + for (Property prop : props) { + if (prop.getName().equals("Tags")) { + try { + tagFound = !prop.getValue().equals(""); + } catch (IllegalAccessException | InvocationTargetException ex) { + Exceptions.printStackTrace(ex); + } + break; } } } + } - //if the node does have associated tags, set its background color - if (tagFound) { - component.setBackground(TAGGED_COLOR); - } + //if the node does have associated tags, set its background color + if (tagFound) { + component.setBackground(TAGGED_COLOR); } } return component; @@ -500,7 +491,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { ov.getOutline().setDefaultRenderer(Object.class, new ColorTagCustomRenderer()); } } - + /** * Store the current column order into a preference file. */ @@ -580,8 +571,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer { + prop.getName().replaceAll("[^a-zA-Z0-9_]", "") + ".column"; } - // Populate a two-dimensional array with rows of property values for up - // to maxRows children of the node passed in. + // Populate a two-dimensional array with rows of property values for up + // to maxRows children of the node passed in. private static Object[][] getRowValues(Node node, int maxRows) { int numRows = Math.min(maxRows, node.getChildren().getNodesCount()); Object[][] rowValues = new Object[numRows][]; @@ -591,10 +582,10 @@ public class DataResultViewerTable extends AbstractDataResultViewer { break; } // BC: I got this once, I think it was because the table - // refreshed while we were in this method - // could be better synchronized. Or it was from - // the lazy nodes updating... Didn't have time - // to fully debug it. + // refreshed while we were in this method + // could be better synchronized. Or it was from + // the lazy nodes updating... Didn't have time + // to fully debug it. if (rowCount > numRows) { break; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 4cd37bed03..4b23a47898 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -30,6 +30,8 @@ import org.apache.commons.lang3.StringUtils; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; +import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; @@ -101,16 +103,30 @@ public abstract class AbstractAbstractFileNode extends A } catch (NullPointerException ex) { // Skip } - + } } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { if (evt.getNewValue() == null) { // case was closed. Remove listeners so that we don't get called with a stale case handle removeListeners(); } + } else if (eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())) { + ContentTagAddedEvent event = (ContentTagAddedEvent) evt; + if (event.getAddedTag().getContent().equals(content)) { + updateSheet(); + } + } else if (eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + ContentTagDeletedEvent event = (ContentTagDeletedEvent) evt; + if (event.getDeletedTagInfo().getContentID() == content.getId()) { + updateSheet(); + } } }; + private void updateSheet() { + this.setSheet(createSheet()); + } + // Note: this order matters for the search result, changed it if the order of property headers on the "KeywordSearchNode"changed public static enum AbstractFilePropertyType { @@ -283,7 +299,7 @@ public abstract class AbstractAbstractFileNode extends A map.put(AbstractFilePropertyType.MIMETYPE.toString(), content.getMIMEType() == null ? "" : content.getMIMEType()); } - static void addTagProperty(Sheet.Set ss, Content content) { + protected void addTagProperty(Sheet.Set ss) { final String NO_DESCR = NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.desc"); List tags = new ArrayList<>(); try { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 82de781b50..675e666373 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -85,7 +85,7 @@ public abstract class AbstractFsContentNode extends Abst } // add tags property to the sheet - AbstractAbstractFileNode.addTagProperty(ss, content); + addTagProperty(ss); return s; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index b10c867c9b..8400c665e0 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -36,6 +38,10 @@ import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; +import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent; +import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagDeletedEvent; +import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; +import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; @@ -72,6 +78,39 @@ public class BlackboardArtifactNode extends DisplayableItemNode { private static final Integer[] SHOW_FILE_METADATA = new Integer[]{ BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),}; + private final PropertyChangeListener pcl = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + String eventType = evt.getPropertyName(); + if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString())) { + BlackBoardArtifactTagAddedEvent event = (BlackBoardArtifactTagAddedEvent) evt; + if (event.getAddedTag().getArtifact().equals(artifact)) { + updateSheet(); + } + } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString())) { + BlackBoardArtifactTagDeletedEvent event = (BlackBoardArtifactTagDeletedEvent) evt; + if (event.getDeletedTagInfo().getArtifactID() == artifact.getArtifactID()) { + updateSheet(); + } + } else if (eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())) { + ContentTagAddedEvent event = (ContentTagAddedEvent) evt; + if (event.getAddedTag().getContent().equals(associated)) { + updateSheet(); + } + } else if (eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + ContentTagDeletedEvent event = (ContentTagDeletedEvent) evt; + if (event.getDeletedTagInfo().getContentID()== associated.getId()) { + updateSheet(); + } + } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { + if (evt.getNewValue() == null) { + // case was closed. Remove listeners so that we don't get called with a stale case handle + removeListeners(); + } + } + } + }; + /** * Construct blackboard artifact node from an artifact and using provided * icon @@ -88,6 +127,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode { this.setName(Long.toString(artifact.getArtifactID())); this.setDisplayName(); this.setIconBaseWithExtension(iconPath); + Case.addPropertyChangeListener(pcl); } /** @@ -105,6 +145,11 @@ public class BlackboardArtifactNode extends DisplayableItemNode { this.setName(Long.toString(artifact.getArtifactID())); this.setDisplayName(); this.setIconBaseWithExtension(ExtractedContent.getIconFilePath(artifact.getArtifactTypeID())); //NON-NLS + Case.addPropertyChangeListener(pcl); + } + + private void removeListeners() { + Case.removePropertyChangeListener(pcl); } @Override @@ -311,6 +356,10 @@ public class BlackboardArtifactNode extends DisplayableItemNode { return s; } + private void updateSheet() { + this.setSheet(createSheet()); + } + private String getRootParentName() { String parentName = associated.getName(); Content parent = associated; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java index ff4d9e259d..603d056a08 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java @@ -444,9 +444,7 @@ public class ExtractedContent implements AutopsyVisitableItem { */ } } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { + || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())) { try { Case.getCurrentCase(); refresh(true); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index fec18d7c45..5a996d494a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -203,9 +203,6 @@ public class KeywordHits implements AutopsyVisitableItem { } populateMaps(artifactIds); - - setChanged(); - notifyObservers(); } } @@ -309,12 +306,6 @@ public class KeywordHits implements AutopsyVisitableItem { removeNotify(); skCase = null; } - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - refresh(true); - keywordResults.update(); } } }; @@ -457,8 +448,8 @@ public class KeywordHits implements AutopsyVisitableItem { public class TermNode extends DisplayableItemNode implements Observer { - private String setName; - private String keyword; + private final String setName; + private final String keyword; public TermNode(String setName, String keyword) { super(Children.create(new HitsFactory(setName, keyword), true), Lookups.singleton(keyword)); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java index 878f0809aa..158b682ac5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java @@ -87,7 +87,7 @@ public class LayoutFileNode extends AbstractAbstractFileNode { } // add tags property to the sheet - AbstractAbstractFileNode.addTagProperty(ss, content); + addTagProperty(ss); return s; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index 9e3c40b595..b7019cfeb7 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -76,7 +76,7 @@ public class LocalFileNode extends AbstractAbstractFileNode { } // add tags property to the sheet - AbstractAbstractFileNode.addTagProperty(ss, content); + addTagProperty(ss); return s; } From f126b5a23a6359fdd2ffd4bb560b1a33e3ba72db Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 25 Oct 2016 14:33:56 -0400 Subject: [PATCH 05/10] Recognized that exception thrown by getValue is ignored --- .../autopsy/corecomponents/DataResultViewerTable.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 57ff03168f..7a1bd8acf4 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -471,8 +471,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { if (prop.getName().equals("Tags")) { try { tagFound = !prop.getValue().equals(""); - } catch (IllegalAccessException | InvocationTargetException ex) { - Exceptions.printStackTrace(ex); + } catch (IllegalAccessException | InvocationTargetException ignore) { } break; } From c89af585ef5659783fe1a34ac51703f57c639fe4 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 25 Oct 2016 16:34:30 -0400 Subject: [PATCH 06/10] Cleaned up code --- .../corecomponents/DataResultViewerTable.java | 7 ++-- .../datamodel/AbstractAbstractFileNode.java | 5 +++ .../datamodel/AbstractFsContentNode.java | 2 +- .../autopsy/datamodel/DeletedContent.java | 5 --- .../autopsy/datamodel/EmailExtracted.java | 6 --- .../autopsy/datamodel/ExtractedContent.java | 26 +------------ .../sleuthkit/autopsy/datamodel/FileSize.java | 5 --- .../autopsy/datamodel/FileTypesNode.java | 6 --- .../autopsy/datamodel/HashsetHits.java | 6 --- .../autopsy/datamodel/InterestingHits.java | 6 --- .../autopsy/datamodel/KeywordHits.java | 38 +++++++++---------- .../autopsy/datamodel/LayoutFileNode.java | 2 +- .../org/sleuthkit/autopsy/datamodel/Tags.java | 2 +- .../autopsy/datamodel/accounts/Accounts.java | 2 +- 14 files changed, 32 insertions(+), 86 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 7a1bd8acf4..2011d01911 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -449,8 +449,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer { /** * This custom renderer extends the renderer that was already being - * used by the outline table. This renderer colors a row if the file - * or artifact associated with the row's node is tagged. + * used by the outline table. This renderer colors a row if the + * tags property of the node is not empty. */ class ColorTagCustomRenderer extends DefaultOutlineCellRenderer { private static final long serialVersionUID = 1L; @@ -459,13 +459,14 @@ public class DataResultViewerTable extends AbstractDataResultViewer { Object value, boolean isSelected, boolean hasFocus, int row, int col) { Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + // only override the color if a node is not selected if (!isSelected) { Node node = currentRoot.getChildren().getNodeAt(table.convertRowIndexToModel(row)); boolean tagFound = false; if (node != null) { Node.PropertySet[] propSets = node.getPropertySets(); - if (propSets.length != 0) { + // currently, a node has only one property set, named Sheet.PROPERTIES ("properties") Node.Property[] props = propSets[0].getProperties(); for (Property prop : props) { if (prop.getName().equals("Tags")) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 4b23a47898..6d005d2aaf 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -299,6 +299,11 @@ public abstract class AbstractAbstractFileNode extends A map.put(AbstractFilePropertyType.MIMETYPE.toString(), content.getMIMEType() == null ? "" : content.getMIMEType()); } + /** + * Used by subclasses of AbstractAbstractFileNode to add the tags property + * to their sheets. + * @param ss + */ protected void addTagProperty(Sheet.Set ss) { final String NO_DESCR = NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.desc"); List tags = new ArrayList<>(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 675e666373..a6db3c1df1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -89,5 +89,5 @@ public abstract class AbstractFsContentNode extends Abst return s; } - + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java index 52c1b4be47..3096a3e552 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DeletedContent.java @@ -230,11 +230,6 @@ public class DeletedContent implements AutopsyVisitableItem { removeListeners(); } maxFilesDialogShown = false; - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java index 1e61078765..9f8d3d9bd1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/EmailExtracted.java @@ -269,12 +269,6 @@ public class EmailExtracted implements AutopsyVisitableItem { removeNotify(); skCase = null; } - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - refresh(true); - emailResults.update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java index 603d056a08..896cec5322 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java @@ -244,21 +244,9 @@ public class ExtractedContent implements AutopsyVisitableItem { removeNotify(); skCase = null; } - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - try { - Case.getCurrentCase(); - refresh(true); - } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ - } } }; - + @Override protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); @@ -443,16 +431,6 @@ public class ExtractedContent implements AutopsyVisitableItem { * Case is closed, do nothing. */ } - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString())) { - try { - Case.getCurrentCase(); - refresh(true); - } catch (IllegalStateException notUsed) { - /** - * Case is closed, do nothing. - */ - } } } }; @@ -461,14 +439,12 @@ public class ExtractedContent implements AutopsyVisitableItem { protected void addNotify() { IngestManager.getInstance().addIngestJobEventListener(pcl); IngestManager.getInstance().addIngestModuleEventListener(pcl); - Case.addPropertyChangeListener(pcl); } @Override protected void removeNotify() { IngestManager.getInstance().removeIngestJobEventListener(pcl); IngestManager.getInstance().removeIngestModuleEventListener(pcl); - Case.removePropertyChangeListener(pcl); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java index 769f15973a..c250166c3b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileSize.java @@ -226,11 +226,6 @@ public class FileSize implements AutopsyVisitableItem { if (evt.getNewValue() == null) { removeListeners(); } - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java index 2c40f3e45d..daf1a31780 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/FileTypesNode.java @@ -192,12 +192,6 @@ public class FileTypesNode extends DisplayableItemNode { if (evt.getNewValue() == null) { removeListeners(); } - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - refresh(true); - update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java index 068d9a44e5..5305df440b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HashsetHits.java @@ -243,12 +243,6 @@ public class HashsetHits implements AutopsyVisitableItem { removeNotify(); skCase = null; } - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - refresh(true); - hashsetResults.update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java index e898ed448c..872b5bcb25 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/InterestingHits.java @@ -236,12 +236,6 @@ public class InterestingHits implements AutopsyVisitableItem { removeNotify(); skCase = null; } - } else if (eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_ADDED.toString()) - || eventType.equals(Case.Events.CONTENT_TAG_DELETED.toString())) { - refresh(true); - interestingResults.update(); } } }; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index 5a996d494a..240f4e0ec0 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -409,25 +409,24 @@ public class KeywordHits implements AutopsyVisitableItem { } } - private class TermFactory extends ChildFactory implements Observer { + private class TermFactory extends ChildFactory.Detachable implements Observer { private String setName; private TermFactory(String setName) { super(); this.setName = setName; + } + + @Override + protected void addNotify() { keywordResults.addObserver(this); } -// @Override -// protected void addNotify() { -// keywordResults.addObserver(this); -// } -// -// @Override -// protected void removeNotify() { -// keywordResults.deleteObserver(this); -// } + @Override + protected void removeNotify() { + keywordResults.deleteObserver(this); + } @Override protected boolean createKeys(List list) { @@ -508,7 +507,7 @@ public class KeywordHits implements AutopsyVisitableItem { } } - public class HitsFactory extends ChildFactory implements Observer { + public class HitsFactory extends ChildFactory.Detachable implements Observer { private final String keyword; private final String setName; @@ -517,18 +516,17 @@ public class KeywordHits implements AutopsyVisitableItem { super(); this.setName = setName; this.keyword = keyword; + } + + @Override + protected void addNotify() { keywordResults.addObserver(this); } -// @Override -// protected void addNotify() { -// keywordResults.addObserver(this); -// } -// -// @Override -// protected void removeNotify() { -// keywordResults.deleteObserver(this); -// } + @Override + protected void removeNotify() { + keywordResults.deleteObserver(this); + } @Override protected boolean createKeys(List list) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java index 158b682ac5..495737488b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java @@ -39,7 +39,7 @@ import org.sleuthkit.datamodel.TskData; public class LayoutFileNode extends AbstractAbstractFileNode { public static enum LayoutContentPropertyType { - + PARTS { @Override public String toString() { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java index d3f9d6688f..ff51e7c92e 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java @@ -409,7 +409,7 @@ public class Tags implements AutopsyVisitableItem { @Override public void update(Observable o, Object arg) { - refresh(true); //this caused table to update + refresh(true); } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java index 84b954eb70..f1205211a4 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java @@ -320,7 +320,7 @@ final public class Accounts implements AutopsyVisitableItem { public boolean isLeafTypeNode() { return false; } - + @Override public T accept(DisplayableItemNodeVisitor v) { return v.visit(this); From f803b01f182eb252f5e2b1303d64c8ced943c036 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Wed, 26 Oct 2016 13:38:26 -0400 Subject: [PATCH 07/10] Cleaned up DataResultViewerTable --- .../corecomponents/DataResultViewerTable.java | 61 +++---------------- 1 file changed, 8 insertions(+), 53 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 2011d01911..d312af106a 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -57,7 +57,6 @@ import org.openide.nodes.NodeListener; import org.openide.nodes.NodeMemberEvent; import org.openide.nodes.NodeReorderEvent; import org.openide.nodes.Sheet; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; @@ -72,6 +71,8 @@ import org.sleuthkit.autopsy.coreutils.Logger; //@ServiceProvider(service = DataResultViewer.class) public class DataResultViewerTable extends AbstractDataResultViewer { + private static final long serialVersionUID = 1L; + private final String firstColumnLabel = NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.firstColLbl"); // This is a set because we add properties of up to 100 child nodes, and we want unique properties private final Set> propertiesAcc = new LinkedHashSet<>(); @@ -405,10 +406,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { ov.getOutline().setAutoResizeMode((props.size() > 0) ? JTable.AUTO_RESIZE_OFF : JTable.AUTO_RESIZE_ALL_COLUMNS); // get first row's values for the table - Object[][] content; - content = getRowValues(root, 1); - - if (content != null) { + if (root.getChildren().getNodesCount() != 0) { final Graphics graphics = ov.getGraphics(); if (graphics != null) { @@ -438,13 +436,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { columnWidth = Math.min(columnWidth, columnWidthLimit); ov.getOutline().getColumnModel().getColumn(column).setPreferredWidth(columnWidth); - } - - // if there's no content just auto resize all columns - if (content.length <= 0) { - // turn on the auto resize - ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - } + } } /** @@ -479,7 +471,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { } } } - //if the node does have associated tags, set its background color if (tagFound) { component.setBackground(TAGGED_COLOR); @@ -489,6 +480,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer { } } ov.getOutline().setDefaultRenderer(Object.class, new ColorTagCustomRenderer()); + } else { + ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); } } @@ -571,41 +564,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { + prop.getName().replaceAll("[^a-zA-Z0-9_]", "") + ".column"; } - // Populate a two-dimensional array with rows of property values for up - // to maxRows children of the node passed in. - private static Object[][] getRowValues(Node node, int maxRows) { - int numRows = Math.min(maxRows, node.getChildren().getNodesCount()); - Object[][] rowValues = new Object[numRows][]; - int rowCount = 0; - for (Node child : node.getChildren().getNodes()) { - if (rowCount >= maxRows) { - break; - } - // BC: I got this once, I think it was because the table - // refreshed while we were in this method - // could be better synchronized. Or it was from - // the lazy nodes updating... Didn't have time - // to fully debug it. - if (rowCount > numRows) { - break; - } - PropertySet[] propertySets = child.getPropertySets(); - if (propertySets.length > 0) { - Property[] properties = propertySets[0].getProperties(); - rowValues[rowCount] = new Object[properties.length]; - for (int j = 0; j < properties.length; ++j) { - try { - rowValues[rowCount][j] = properties[j].getValue(); - } catch (IllegalAccessException | InvocationTargetException ignore) { - rowValues[rowCount][j] = "n/a"; //NON-NLS - } - } - } - ++rowCount; - } - return rowValues; - } - @Override public String getTitle() { return NbBundle.getMessage(this.getClass(), "DataResultViewerTable.title"); @@ -640,11 +598,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer { if (SwingUtilities.isEventDispatchThread()) { setupTable(nme.getNode()); } else { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - setupTable(nme.getNode()); - } + SwingUtilities.invokeLater(() -> { + setupTable(nme.getNode()); }); } } From 5052d62133dfc16afeaf878adcc0fa93b6669fcf Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Wed, 9 Nov 2016 10:32:58 -0500 Subject: [PATCH 08/10] Clean up code --- .../corecomponents/DataResultViewerTable.java | 12 ++++++------ .../datamodel/AbstractAbstractFileNode.java | 4 ++-- .../autopsy/datamodel/ContentTagNode.java | 10 +++++----- .../autopsy/datamodel/DataSourcesNode.java | 13 +++++++------ .../sleuthkit/autopsy/datamodel/KeywordHits.java | 6 +++--- .../sleuthkit/autopsy/datamodel/LocalFileNode.java | 7 +++---- Core/src/org/sleuthkit/autopsy/datamodel/Tags.java | 14 +++++++------- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 0d6f057f9b..21135f68c8 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * - * Copyright 2013-2014 Basis Technology Corp. + * + * Copyright 2013-2016 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. @@ -391,7 +391,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { columnWidth = Math.min(columnWidth, columnWidthLimit); ov.getOutline().getColumnModel().getColumn(column).setPreferredWidth(columnWidth); - } + } } } else { // if there's no content just auto resize all columns diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 6d005d2aaf..131c069aa0 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2014 Basis Technology Corp. + * Copyright 2011-2016 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -103,7 +103,7 @@ public abstract class AbstractAbstractFileNode extends A } catch (NullPointerException ex) { // Skip } - + } } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) { if (evt.getNewValue() == null) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java index 7569bc25d4..8099bbc300 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * - * Copyright 2013 Basis Technology Corp. + * + * Copyright 2013-2016 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. diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java index 6b4d425fbb..7ac9e37398 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataSourcesNode.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * - * Copyright 2011-2014 Basis Technology Corp. + * + * Copyright 2011-2016 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. @@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.logging.Level; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.lookup.Lookups; @@ -103,7 +104,7 @@ public class DataSourcesNode extends DisplayableItemNode { currentKeys = Case.getCurrentCase().getDataSources(); setKeys(currentKeys); } catch (TskCoreException | IllegalStateException ex) { - logger.severe("Error getting data sources: " + ex.getMessage()); // NON-NLS + logger.log(Level.SEVERE, "Error getting data sources: {0}", ex.getMessage()); // NON-NLS setKeys(Collections.emptySet()); } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java index 240f4e0ec0..c7b8983be0 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2015 Basis Technology Corp. + * Copyright 2011-2016 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -346,7 +346,7 @@ public class KeywordHits implements AutopsyVisitableItem { public class ListNode extends DisplayableItemNode implements Observer { - private String listName; + private final String listName; public ListNode(String listName) { super(Children.create(new TermFactory(listName), true), Lookups.singleton(listName)); @@ -411,7 +411,7 @@ public class KeywordHits implements AutopsyVisitableItem { private class TermFactory extends ChildFactory.Detachable implements Observer { - private String setName; + private final String setName; private TermFactory(String setName) { super(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index b7019cfeb7..ecccb26272 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2014 Basis Technology Corp. + * Copyright 2013-2016 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.datamodel; import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -84,9 +85,7 @@ public class LocalFileNode extends AbstractAbstractFileNode { @Override public Action[] getActions(boolean context) { List actionsList = new ArrayList<>(); - for (Action a : super.getActions(true)) { - actionsList.add(a); - } + actionsList.addAll(Arrays.asList(super.getActions(true))); actionsList.add(new ViewContextAction(NbBundle.getMessage(this.getClass(), "LocalFileNode.viewFileInDir.text"), this.content)); actionsList.add(null); // creates a menu separator actionsList.add(new NewWindowViewAction( diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java index ff51e7c92e..b8127fe5a7 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Tags.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * - * Copyright 2011-2015 Basis Technology Corp. + * + * Copyright 2011-2016 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. @@ -325,7 +325,7 @@ public class Tags implements AutopsyVisitableItem { public class ContentTagTypeNode extends DisplayableItemNode implements Observer { private final String ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS - private TagName tagName; + private final TagName tagName; public ContentTagTypeNode(TagName tagName) { super(Children.create(new ContentTagNodeFactory(tagName), true), Lookups.singleton(tagName.getDisplayName() + " " + CONTENT_DISPLAY_NAME)); @@ -423,7 +423,7 @@ public class Tags implements AutopsyVisitableItem { */ public class BlackboardArtifactTagTypeNode extends DisplayableItemNode implements Observer { - private TagName tagName; + private final TagName tagName; private final String ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS public BlackboardArtifactTagTypeNode(TagName tagName) { From e0112d2030189e6d8c83da8af8a532f52fd6f4b8 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Wed, 23 Nov 2016 10:27:43 -0500 Subject: [PATCH 09/10] Remove tag columns for tag nodes, add column for VD --- .../datamodel/AbstractAbstractFileNode.java | 17 +++++++------- .../datamodel/BlackboardArtifactNode.java | 2 +- .../datamodel/BlackboardArtifactTagNode.java | 15 +----------- .../autopsy/datamodel/ContentTagNode.java | 23 ++++--------------- .../datamodel/VirtualDirectoryNode.java | 1 + 5 files changed, 17 insertions(+), 41 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 131c069aa0..e3c750826d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * + * * Copyright 2011-2016 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. @@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.Tag; +import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -302,14 +302,15 @@ public abstract class AbstractAbstractFileNode extends A /** * Used by subclasses of AbstractAbstractFileNode to add the tags property * to their sheets. - * @param ss + * @param ss the modifiable Sheet.Set returned by Sheet.get(Sheet.PROPERTIES) */ protected void addTagProperty(Sheet.Set ss) { final String NO_DESCR = NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.desc"); - List tags = new ArrayList<>(); + List tags; try { - tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content)); + tags = Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content); } catch (TskCoreException ex) { + tags = new ArrayList<>(); LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); } ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 8400c665e0..df2b6520a9 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -204,7 +204,7 @@ public class BlackboardArtifactNode extends DisplayableItemNode { displayName = associated.getName(); } - // If this is a node for a keyword hit on an artifact, we set the + // If this is a node for a keyword hit on an artifact, we set the // display name to be the artifact type name followed by " Artifact" // e.g. "Messages Artifact". if (artifact != null && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index 86fce1ab78..4647298931 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2014 Basis Technology Corp. + * Copyright 2013-2016 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,18 +19,15 @@ package org.sleuthkit.autopsy.datamodel; import java.text.MessageFormat; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; -import java.util.stream.Collectors; import javax.swing.Action; 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.actions.DeleteBlackboardArtifactTagAction; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; @@ -38,7 +35,6 @@ import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifactTag; -import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -98,15 +94,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { "", tag.getComment())); - List tags = new ArrayList<>(); - try { - tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(tag.getArtifact())); - } catch (TskCoreException ex) { - Logger.getLogger(ContentTagNode.class.getName()).log(Level.SEVERE, "Failed to get tags for artifact " + tag.getArtifact().getDisplayName(), ex); - } - properties.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), - "", tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); - return propertySheet; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java index 8099bbc300..74ab98d517 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java @@ -1,15 +1,15 @@ /* * Autopsy Forensic Browser - * + * * Copyright 2013-2016 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. @@ -18,24 +18,20 @@ */ package org.sleuthkit.autopsy.datamodel; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; -import java.util.stream.Collectors; import javax.swing.Action; 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.actions.DeleteContentTagAction; -import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentTag; -import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; /** @@ -110,15 +106,6 @@ class ContentTagNode extends DisplayableItemNode { "", content.getSize())); - List tags = new ArrayList<>(); - try { - tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(content)); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Failed to get tags for content " + content.getName(), ex); - } - properties.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "AbstractAbstractFileNode.addFileProperty.tags.displayName"), - "", tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); - return propertySheet; } @@ -131,7 +118,7 @@ class ContentTagNode extends DisplayableItemNode { if (file != null) { actions.add(ViewFileInTimelineAction.createViewFileAction(file)); } - actions.add(null); // Adds a menu item separator. + actions.add(null); // Adds a menu item separator. actions.add(DeleteContentTagAction.getInstance()); return actions.toArray(new Action[actions.size()]); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java index 9cf67f4649..246c6d6e1d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java @@ -148,6 +148,7 @@ public class VirtualDirectoryNode extends AbstractAbstractFileNode entry : map.entrySet()) { ss.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } + addTagProperty(ss); } else { ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_type_name(), Bundle.VirtualDirectoryNode_createSheet_type_displayName(), From 0917c3f53f4f238c646fc5abd78bf21b5afc9b8b Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Wed, 23 Nov 2016 13:00:01 -0500 Subject: [PATCH 10/10] Make tagged items darker and move tags column to end by default --- .../corecomponents/DataResultViewerTable.java | 2 +- .../datamodel/BlackboardArtifactNode.java | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 8b26ac8ca4..a3e87e3008 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -81,7 +81,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private final Map> propertiesMap = new TreeMap<>(); private final DummyNodeListener dummyNodeListener = new DummyNodeListener(); private static final String DUMMY_NODE_DISPLAY_NAME = NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.dummyNodeDisplayName"); - private static final Color TAGGED_COLOR = new Color(230, 235, 240); + private static final Color TAGGED_COLOR = new Color(200, 210, 220); private Node currentRoot; // When a column in the table is moved, these two variables keep track of where // the column started and where it ended up. diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index df2b6520a9..7d15bb2101 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -256,17 +256,6 @@ public class BlackboardArtifactNode extends DisplayableItemNode { } } - // add properties for tags - List tags = new ArrayList<>(); - try { - tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(associated)); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); - } - ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.displayName"), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); - final int artifactTypeId = artifact.getArtifactTypeID(); // If mismatch, add props for extension and file type @@ -353,6 +342,17 @@ public class BlackboardArtifactNode extends DisplayableItemNode { } } + // add properties for tags + List tags = new ArrayList<>(); + try { + tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); + tags.addAll(Case.getCurrentCase().getServices().getTagsManager().getContentTagsByContent(associated)); + } catch (TskCoreException ex) { + LOGGER.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); + } + ss.put(new NodeProperty<>("Tags", NbBundle.getMessage(AbstractAbstractFileNode.class, "BlackboardArtifactNode.createSheet.tags.displayName"), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + return s; }