From e35faceb08834d22ae368e73aeee372e6650e8d3 Mon Sep 17 00:00:00 2001 From: Sophie Mori Date: Tue, 25 Oct 2016 14:12:14 -0400 Subject: [PATCH] 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; }