From 722cb2d898799b066dcaaac24f4c9dbef11c3c6c Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Sep 2021 15:07:38 -0400 Subject: [PATCH 1/3] 7797 fix analysis result tagging --- .../datamodel/BlackboardArtifactItem.java | 43 +++++++++++++++++++ .../autopsy/datamodel/DataArtifactItem.java | 41 ++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/DataArtifactItem.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java new file mode 100755 index 0000000000..3897e37311 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java @@ -0,0 +1,43 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021-2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import com.google.common.annotations.Beta; +import org.sleuthkit.datamodel.BlackboardArtifact; + +/** + * An abstract super class for an Autopsy Data Model item class with an + * underlying BlackboardArtifact Sleuth Kit Data Model object. + * + * @param The concrete BlackboardArtifact sub class type. + */ +public abstract class BlackboardArtifactItem extends TskContentItem { + + /** + * Constructs an Autopsy Data Model item with an underlying + * BlackboardArtifact Sleuth Kit Data Model object. + * + * @param blackboardArtifact The BlackboardArtifact object. + */ + @Beta + BlackboardArtifactItem(T blackboardArtifact) { + super(blackboardArtifact); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DataArtifactItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/DataArtifactItem.java new file mode 100755 index 0000000000..c43d3a311c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DataArtifactItem.java @@ -0,0 +1,41 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021-2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import com.google.common.annotations.Beta; +import org.sleuthkit.datamodel.DataArtifact; + +/** + * An Autopsy Data Model item with an underlying DataArtifact Sleuth Kit Data + * Model object. + */ +public class DataArtifactItem extends BlackboardArtifactItem { + + /** + * Constructs an Autopsy Data Model item with an underlying DataArtifact + * Sleuth Kit Data Model object. + * + * @param dataArtifact The DataArtifact object. + */ + @Beta + DataArtifactItem(DataArtifact dataArtifact) { + super(dataArtifact); + } + +} From cae2fd798dae95836415ebe70635ef9686d51972 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Sep 2021 15:14:02 -0400 Subject: [PATCH 2/3] 7797 fix analysis result tagging --- .../AddBlackboardArtifactTagAction.java | 19 +++++++++-- .../autopsy/actions/AddTagAction.java | 32 +++++++++++++------ .../AnalysisResultsContentViewer.java | 2 +- .../AnalysisResultsViewModel.java | 6 ++-- .../datamodel/AbstractContentNode.java | 2 +- .../autopsy/datamodel/AnalysisResultItem.java | 16 ++-------- .../datamodel/BlackboardArtifactItem.java | 3 +- .../datamodel/BlackboardArtifactNode.java | 17 ++++++---- .../autopsy/datamodel/TskContentItem.java | 16 ++++++---- 9 files changed, 70 insertions(+), 43 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java index 26d1c7a9bc..06a3e2e39e 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddBlackboardArtifactTagAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2013-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,6 +29,7 @@ import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.BlackboardArtifactItem; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.TagName; @@ -46,6 +47,8 @@ import org.sleuthkit.datamodel.TskCoreException; }) public class AddBlackboardArtifactTagAction extends AddTagAction { + private static final long serialVersionUID = 1L; + // This class is a singleton to support multi-selection of nodes, since // org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every // node in the array returns a reference to the same action object from Node.getActions(boolean). @@ -82,8 +85,14 @@ public class AddBlackboardArtifactTagAction extends AddTagAction { * invocation of addTag(), we don't want to tag the same * BlackboardArtifact more than once, so we dedupe the * BlackboardArtifacts by stuffing them into a HashSet. + * + * RC (9/8/21): The documentation does NOT say that lookupAll() can + * return duplicates. That would be very broken. What motivated this + * "de-duping" ? */ - selectedArtifacts.addAll(Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class)); + for (BlackboardArtifactItem item : Utilities.actionsGlobalContext().lookupAll(BlackboardArtifactItem.class)) { + selectedArtifacts.add(item.getTskContent()); + } } else { for (Content content : getContentToTag()) { if (content instanceof BlackboardArtifact) { @@ -111,4 +120,10 @@ public class AddBlackboardArtifactTagAction extends AddTagAction { } }).start(); } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 9c059205f5..725cdb504d 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2020 Basis Technology Corp. + * Copyright 2013-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,33 +44,40 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; /** - * An abstract base class for Actions that allow users to tag SleuthKit data + * An abstract base class for Actions that allow users to tag Sleuth Kit data * model objects. */ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { private static final long serialVersionUID = 1L; private static final String NO_COMMENT = ""; - private final Collection content = new HashSet<>(); + private final Collection contentObjsToTag; + /** + * Constructs an instance of an abstract base class for Actions that allow + * users to tag Sleuth Kit data model objects. + * + * @param menuText The menu item text. + */ AddTagAction(String menuText) { super(menuText); + contentObjsToTag = new HashSet<>(); } @Override public JMenuItem getPopupPresenter() { - content.clear(); + contentObjsToTag.clear(); return new TagMenu(); } /** - * Get the collection of content which may have been specified for this + * Getz the collection of content which may have been specified for this * action. Empty collection returned when no content was specified. * * @return The specified content for this action. */ Collection getContentToTag() { - return Collections.unmodifiableCollection(content); + return Collections.unmodifiableCollection(contentObjsToTag); } /** @@ -83,8 +90,8 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { * apply to the Content specified. */ public JMenuItem getMenuForContent(Collection contentToTag) { - content.clear(); - content.addAll(contentToTag); + contentObjsToTag.clear(); + contentObjsToTag.addAll(contentToTag); return new TagMenu(); } @@ -111,6 +118,11 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { */ abstract protected void addTag(TagName tagName, String comment); + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + /** * Instances of this class implement a context menu user interface for * creating or selecting a tag name for a tag and specifying an optional tag @@ -126,7 +138,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { super(getActionDisplayName()); // Get the current set of tag names. - Map tagNamesMap = null; + Map tagNamesMap; List standardTagNames = TagsManager.getStandardTagNames(); Map tagSetMenuMap = new HashMap<>(); List standardTagMenuitems = new ArrayList<>(); @@ -240,5 +252,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { return tagNameItem; } + } + } diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java index b056eb11db..d40f6c2a39 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsContentViewer.java @@ -132,7 +132,7 @@ public class AnalysisResultsContentViewer implements DataContentViewer { return true; } - TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); if (!Objects.isNull(contentItem)) { Content content = contentItem.getTskContent(); try { diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java index 37e4114168..b470f9dfb7 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/analysisresults/AnalysisResultsViewModel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2021 Basis Technology Corp. + * Copyright 2021-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -251,7 +251,7 @@ public class AnalysisResultsViewModel { * selected in the content viewer and get the analyzed content * as the source of the analysis results to display. */ - selectedAnalysisResult = analysisResultItem.getAnalysisResult(); + selectedAnalysisResult = analysisResultItem.getTskContent(); selectedObjectId = selectedAnalysisResult.getId(); analyzedContent = selectedAnalysisResult.getParent(); } else { @@ -260,7 +260,7 @@ public class AnalysisResultsViewModel { * an analysis result. Use it as the source of the analysis * results to display. */ - TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); + TskContentItem contentItem = node.getLookup().lookup(TskContentItem.class); analyzedContent = contentItem.getTskContent(); selectedObjectId = analyzedContent.getId(); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java index daf8cd84da..2b8428280a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java @@ -102,7 +102,7 @@ public abstract class AbstractContentNode extends ContentNode * @param content Underlying Content instances */ AbstractContentNode(T content) { - this(content, Lookups.fixed(content, new TskContentItem(content))); + this(content, Lookups.fixed(content, new TskContentItem<>(content))); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java index 442d070f5c..20ee3652c0 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AnalysisResultItem.java @@ -22,30 +22,20 @@ import com.google.common.annotations.Beta; import org.sleuthkit.datamodel.AnalysisResult; /** - * An Autopsy Data Model item with an underlying analysis result Sleuth Kit Data + * An Autopsy Data Model item with an underlying AnalysisResult Sleuth Kit Data * Model object. */ -public class AnalysisResultItem extends TskContentItem { +public class AnalysisResultItem extends BlackboardArtifactItem { /** * Constructs an Autopsy Data Model item with an underlying AnalysisResult * Sleuth Kit Data Model object. * - * @param analysisResult The analysis result. + * @param analysisResult The AnalysisResult object. */ @Beta AnalysisResultItem(AnalysisResult analysisResult) { super(analysisResult); } - /** - * Gets the underlying analysis result. - * - * @return The analysis result. - */ - @Beta - public AnalysisResult getAnalysisResult() { - return (AnalysisResult) (getTskContent()); - } - } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java index 3897e37311..8d4cab5ea5 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactItem.java @@ -23,7 +23,8 @@ import org.sleuthkit.datamodel.BlackboardArtifact; /** * An abstract super class for an Autopsy Data Model item class with an - * underlying BlackboardArtifact Sleuth Kit Data Model object. + * underlying BlackboardArtifact Sleuth Kit Data Model object, i.e., a + * DataArtifact or an AnalysisResult. * * @param The concrete BlackboardArtifact sub class type. */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 469c069aae..0072654ccb 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -81,6 +81,7 @@ import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.BlackboardArtifact.Category; +import org.sleuthkit.datamodel.DataArtifact; import org.sleuthkit.datamodel.Score; /** @@ -232,7 +233,7 @@ public class BlackboardArtifactNode extends AbstractContentNode artifactItem; if (artifact instanceof AnalysisResult) { artifactItem = new AnalysisResultItem((AnalysisResult) artifact); } else { - artifactItem = new TskContentItem(artifact); + artifactItem = new DataArtifactItem((DataArtifact) artifact); } /* * Create the Lookup. + * + * NOTE: For now, we are putting both the Autopsy Data Model item and + * the Sleuth Kit Data Model item in the Lookup so that code that is not + * aware of the new Autopsy Data Model will still function. */ if (content == null) { return Lookups.fixed(artifact, artifactItem); @@ -385,7 +390,7 @@ public class BlackboardArtifactNode extends AbstractContentNode The type of the underlying Sleuth Kit Data Model object. */ @Beta -public class TskContentItem { +public class TskContentItem { - private final Content tskContent; + private final T content; /** * Constructs an Autopsy Data Model item with an underlying Sleuth Kit Data * Model object that implements the Sleuth Kit Data Model's Content * interface. * - * @param content The underlying Sleuth Kit Data Model object. + * @param content The Sleuth Kit Data Model object. * */ @Beta - TskContentItem(Content sleuthKitContent) { - this.tskContent = sleuthKitContent; + TskContentItem(T content) { + this.content = content; } /** @@ -49,8 +51,8 @@ public class TskContentItem { * @return The Sleuth Kit Data Model object. */ @Beta - public Content getTskContent() { - return tskContent; + public T getTskContent() { + return content; } } From d03c1dc789bef8d0e14579373370c33e1b06202a Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 8 Sep 2021 15:20:38 -0400 Subject: [PATCH 3/3] 7797 fix analysis result tagging --- Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java | 6 +++--- .../sleuthkit/autopsy/datamodel/AbstractContentNode.java | 3 +-- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java index 725cdb504d..ff3dc08e04 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/AddTagAction.java @@ -44,7 +44,7 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; /** - * An abstract base class for Actions that allow users to tag Sleuth Kit data + * An abstract super class for Actions that allow users to tag Sleuth Kit data * model objects. */ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { @@ -54,7 +54,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { private final Collection contentObjsToTag; /** - * Constructs an instance of an abstract base class for Actions that allow + * Constructs an instance of an abstract super class for Actions that allow * users to tag Sleuth Kit data model objects. * * @param menuText The menu item text. @@ -71,7 +71,7 @@ abstract class AddTagAction extends AbstractAction implements Presenter.Popup { } /** - * Getz the collection of content which may have been specified for this + * Get the collection of content which may have been specified for this * action. Empty collection returned when no content was specified. * * @return The specified content for this action. diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java index 2b8428280a..cb4bb9794c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractContentNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2012-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,7 +39,6 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance.Type; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.datamodel.AnalysisResult; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Score; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 0072654ccb..f11c75784e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -368,7 +368,7 @@ public class BlackboardArtifactNode extends AbstractContentNode artifactItem; if (artifact instanceof AnalysisResult) {