refactoring and added fields

This commit is contained in:
Greg DiCristofaro 2021-10-08 14:39:16 -04:00
parent 9624426637
commit 0653e61b3f
38 changed files with 1456 additions and 1021 deletions

View File

@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.corecomponentinterfaces;
import java.awt.Component;
import org.openide.nodes.Node;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
/**
* An interface for result viewers. A result viewer uses a Swing Component to
@ -76,7 +76,7 @@ public interface DataResultViewer {
*/
public void setNode(Node node);
default public void setNode(Node node, SearchResultsDTO<?> searchResults) {
default public void setNode(Node node, SearchResultsDTO searchResults) {
setNode(node, null);
}

View File

@ -43,9 +43,9 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResult;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo;
import org.sleuthkit.autopsy.datamodel.SearchResultTableNode;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.mainui.nodes.SearchResultRootNode;
import org.sleuthkit.autopsy.mainui.datamodel.ThreePanelDAO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
/**
* A result view panel is a JPanel with a JTabbedPane child component that
@ -88,7 +88,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
private DataContent contentView;
private ExplorerManager explorerManager;
private Node currentRootNode;
private SearchResultsDTO<?> searchResults;
private SearchResultsDTO searchResults;
private boolean listeningToTabbedPane;
/**
@ -363,7 +363,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
setNode(rootNode, null);
}
void setNode(Node rootNode, SearchResultsDTO<?> searchResults) {
void setNode(Node rootNode, SearchResultsDTO searchResults) {
this.searchResults = searchResults;
if (this.currentRootNode != null) {

View File

@ -40,16 +40,14 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResult;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.DataArtifactKeyv2;
import org.sleuthkit.autopsy.datamodel.DataArtifactNodev2;
import org.sleuthkit.autopsy.datamodel.FileNodev2;
import org.sleuthkit.autopsy.datamodel.FileTypeExtensionsKeyv2;
import org.sleuthkit.autopsy.datamodel.SearchResultChildFactory.NodeCreator;
import org.sleuthkit.autopsy.datamodel.SearchResultTableNode;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.RowResultDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDataArtifactDAO.DataArtifactTableSearchResultsDTO;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactSearchParam;
import org.sleuthkit.autopsy.mainui.nodes.DataArtifactNode;
import org.sleuthkit.autopsy.mainui.nodes.FileNode;
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParam;
import org.sleuthkit.autopsy.mainui.nodes.SearchResultRootNode;
import org.sleuthkit.autopsy.mainui.datamodel.ThreePanelDAO;
import org.sleuthkit.autopsy.mainui.datamodel.RowResultDTO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -375,9 +373,9 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
private final ThreePanelDAO threePanelDAO = ThreePanelDAO.getInstance();
public void displayDataArtifact(DataArtifactKeyv2 dataArtifactKey) {
public void displayDataArtifact(DataArtifactSearchParam dataArtifactKey) {
try {
displaySearchResults(threePanelDAO.getDataArtifactsDAO().getDataArtifactsForTable(dataArtifactKey), (table, row) -> new DataArtifactNodev2(table, row));
displaySearchResults(threePanelDAO.getDataArtifactsDAO().getDataArtifactsForTable(dataArtifactKey));
} catch (ExecutionException | IllegalArgumentException ex) {
logger.log(Level.WARNING, MessageFormat.format(
"There was an error fetching data for artifact type: {0} and data source id: {1}.",
@ -388,9 +386,9 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
}
public void displayFileExtensions(FileTypeExtensionsKeyv2 fileExtensionsKey) {
public void displayFileExtensions(FileTypeExtensionsSearchParam fileExtensionsKey) {
try {
displaySearchResults(threePanelDAO.getViewsDAO().getFilesByExtension(fileExtensionsKey), FileNodev2::new);
displaySearchResults(threePanelDAO.getViewsDAO().getFilesByExtension(fileExtensionsKey));
} catch (ExecutionException | IllegalArgumentException ex) {
logger.log(Level.WARNING, MessageFormat.format(
"There was an error fetching data for files of extension filter: {0} and data source id: {1}.",
@ -400,8 +398,8 @@ public final class DataResultTopComponent extends TopComponent implements DataRe
}
}
public <T extends SearchResultsDTO<S>, S extends RowResultDTO> void displaySearchResults(T searchResults, NodeCreator<T, S> nodeCreator) {
dataResultPanel.setNode(new SearchResultTableNode<>(nodeCreator, searchResults), searchResults);
private void displaySearchResults(SearchResultsDTO searchResults) {
dataResultPanel.setNode(new SearchResultRootNode(searchResults), searchResults);
dataResultPanel.setNumberOfChildNodes(
searchResults.getTotalResultsCount() > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) searchResults.getTotalResultsCount());
}

View File

@ -87,9 +87,9 @@ import org.sleuthkit.autopsy.datamodel.BaseChildFactory;
import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageChangeEvent;
import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageCountChangeEvent;
import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageSizeChangeEvent;
import org.sleuthkit.autopsy.datamodel.SearchResultTableNode;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.mainui.nodes.SearchResultRootNode;
import org.sleuthkit.autopsy.mainui.datamodel.ThreePanelDAO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
import org.sleuthkit.datamodel.Score.Significance;
/**
@ -145,7 +145,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
private final TableListener outlineViewListener;
private final IconRendererTableListener iconRendererListener;
private Node rootNode;
private SearchResultsDTO<?> searchResults;
private SearchResultsDTO searchResults;
/**
* Multiple nodes may have been visited in the context of this
@ -319,7 +319,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
*/
@Override
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
public void setNode(Node rootNode, SearchResultsDTO<?> searchResults) {
public void setNode(Node rootNode, SearchResultsDTO searchResults) {
this.searchResults = searchResults;
if (!SwingUtilities.isEventDispatchThread()) {
@ -1539,7 +1539,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
private void exportCSVButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportCSVButtonActionPerformed
Node currentRoot = this.getExplorerManager().getRootContext();
// GVDTODO disabled for Search Result node
if (currentRoot != null && (!(currentRoot instanceof SearchResultTableNode)) && currentRoot.getChildren().getNodesCount() > 0) {
if (currentRoot != null && (!(currentRoot instanceof SearchResultRootNode)) && currentRoot.getChildren().getNodesCount() > 0) {
org.sleuthkit.autopsy.directorytree.ExportCSVAction.saveNodesToCSV(java.util.Arrays.asList(currentRoot.getChildren().getNodes()), this);
} else {
MessageNotifyUtil.Message.info(Bundle.DataResultViewerTable_exportCSVButtonActionPerformed_empty());

View File

@ -56,7 +56,7 @@ import static org.sleuthkit.autopsy.corecomponents.Bundle.*;
import org.sleuthkit.autopsy.corecomponents.ResultViewerPersistence.SortCriterion;
import org.sleuthkit.autopsy.coreutils.ImageUtils;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
import org.sleuthkit.autopsy.guiutils.WrapLayout;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException;
@ -457,7 +457,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
}
@Override
public void setNode(Node givenNode, SearchResultsDTO<?> searchResults) {
public void setNode(Node givenNode, SearchResultsDTO searchResults) {
// GVDTODO givenNode cannot be assumed to be a table filter node and search results needs to be captured.
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.datamodel;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactSearchParam;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections;
@ -530,13 +531,12 @@ public class Artifacts {
* no filtering will occur.
*/
TypeNode(BlackboardArtifact.Type type, long filteringDSObjId) {
super(
type.getCategory() == Category.DATA_ARTIFACT
super(type.getCategory() == Category.DATA_ARTIFACT
? new Children.Array()
: Children.create(new ArtifactFactory(type, filteringDSObjId), true),
type.getCategory() == Category.DATA_ARTIFACT
? Lookups.fixed(type.getDisplayName(), new DataArtifactKeyv2(type, filteringDSObjId > 0 ? filteringDSObjId : null))
? Lookups.fixed(type.getDisplayName(), new DataArtifactSearchParam(type, filteringDSObjId > 0 ? filteringDSObjId : null))
: Lookups.singleton(type.getDisplayName()),
type.getDisplayName(),

View File

@ -36,7 +36,7 @@ public class DataArtifactItem extends BlackboardArtifactItem<DataArtifact> {
* @param sourceContent The source content of the DataArtifact.
*/
@Beta
DataArtifactItem(DataArtifact dataArtifact, Content sourceContent) {
public DataArtifactItem(DataArtifact dataArtifact, Content sourceContent) {
super(dataArtifact, sourceContent);
}

View File

@ -18,6 +18,7 @@
*/
package org.sleuthkit.autopsy.datamodel;
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParam;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
@ -37,10 +38,9 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ThreePanelViewsDAO.DocumentFilter;
import org.sleuthkit.autopsy.datamodel.ThreePanelViewsDAO.ExecutableFilter;
import org.sleuthkit.autopsy.datamodel.ThreePanelViewsDAO.RootFilter;
import org.sleuthkit.autopsy.datamodel.ThreePanelViewsDAO.SearchFilterInterface;
import org.sleuthkit.autopsy.mainui.datamodel.FileExtDocumentFilter;
import org.sleuthkit.autopsy.mainui.datamodel.FileExtExecutableFilter;
import org.sleuthkit.autopsy.mainui.datamodel.FileExtRootFilter;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.datamodel.AbstractFile;
@ -48,6 +48,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.guiutils.RefreshThrottler;
import org.sleuthkit.autopsy.mainui.datamodel.FileExtSearchFilter;
/**
* Filters database results by file extension.
@ -195,7 +196,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
*/
class FileTypesByExtNode extends DisplayableItemNode {
private final RootFilter filter;
private final FileExtRootFilter filter;
/**
*
@ -203,7 +204,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
* @param filter null to display root node of file type tree, pass in
* something to provide a sub-node.
*/
FileTypesByExtNode(SleuthkitCase skCase, RootFilter filter) {
FileTypesByExtNode(SleuthkitCase skCase, FileExtRootFilter filter) {
this(skCase, filter, null);
}
@ -214,7 +215,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
* @param o Observable that was created by a higher-level node that
* provides updates on events
*/
private FileTypesByExtNode(SleuthkitCase skCase, RootFilter filter, FileTypesByExtObservable o) {
private FileTypesByExtNode(SleuthkitCase skCase, FileExtRootFilter filter, FileTypesByExtObservable o) {
super(Children.create(new FileTypesByExtNodeChildren(skCase, filter, o), true),
Lookups.singleton(filter == null ? FNAME : filter.getDisplayName()));
@ -250,7 +251,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
sheetSet = Sheet.createPropertiesSet();
sheet.put(sheetSet);
}
if (filter != null && (filter.equals(RootFilter.TSK_DOCUMENT_FILTER) || filter.equals(RootFilter.TSK_EXECUTABLE_FILTER))) {
if (filter != null && (filter.equals(FileExtRootFilter.TSK_DOCUMENT_FILTER) || filter.equals(FileExtRootFilter.TSK_EXECUTABLE_FILTER))) {
String extensions = "";
for (String ext : filter.getFilter()) {
extensions += "'" + ext + "', ";
@ -272,7 +273,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
if (filter == null) {
return getClass().getName();
}
if (filter.equals(RootFilter.TSK_DOCUMENT_FILTER) || filter.equals(RootFilter.TSK_EXECUTABLE_FILTER)) {
if (filter.equals(FileExtRootFilter.TSK_DOCUMENT_FILTER) || filter.equals(FileExtRootFilter.TSK_EXECUTABLE_FILTER)) {
return getClass().getName() + filter.getName();
}
return getClass().getName();
@ -280,10 +281,10 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
}
private class FileTypesByExtNodeChildren extends ChildFactory<SearchFilterInterface> {
private class FileTypesByExtNodeChildren extends ChildFactory<FileExtSearchFilter> {
private final SleuthkitCase skCase;
private final RootFilter filter;
private final FileExtRootFilter filter;
private final FileTypesByExtObservable notifier;
/**
@ -293,7 +294,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
* @param o Observable that provides updates based on events being
* fired (or null if one needs to be created)
*/
private FileTypesByExtNodeChildren(SleuthkitCase skCase, RootFilter filter, FileTypesByExtObservable o) {
private FileTypesByExtNodeChildren(SleuthkitCase skCase, FileExtRootFilter filter, FileTypesByExtObservable o) {
super();
this.skCase = skCase;
this.filter = filter;
@ -305,26 +306,26 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
}
@Override
protected boolean createKeys(List<SearchFilterInterface> list) {
protected boolean createKeys(List<FileExtSearchFilter> list) {
// root node
if (filter == null) {
list.addAll(Arrays.asList(RootFilter.values()));
list.addAll(Arrays.asList(FileExtRootFilter.values()));
} // document and executable has another level of nodes
else if (filter.equals(RootFilter.TSK_DOCUMENT_FILTER)) {
list.addAll(Arrays.asList(DocumentFilter.values()));
} else if (filter.equals(RootFilter.TSK_EXECUTABLE_FILTER)) {
list.addAll(Arrays.asList(ExecutableFilter.values()));
else if (filter.equals(FileExtRootFilter.TSK_DOCUMENT_FILTER)) {
list.addAll(Arrays.asList(FileExtDocumentFilter.values()));
} else if (filter.equals(FileExtRootFilter.TSK_EXECUTABLE_FILTER)) {
list.addAll(Arrays.asList(FileExtExecutableFilter.values()));
}
return true;
}
@Override
protected Node createNodeForKey(SearchFilterInterface key) {
protected Node createNodeForKey(FileExtSearchFilter key) {
// make new nodes for the sub-nodes
if (key.getName().equals(RootFilter.TSK_DOCUMENT_FILTER.getName())) {
return new FileTypesByExtNode(skCase, RootFilter.TSK_DOCUMENT_FILTER, notifier);
} else if (key.getName().equals(RootFilter.TSK_EXECUTABLE_FILTER.getName())) {
return new FileTypesByExtNode(skCase, RootFilter.TSK_EXECUTABLE_FILTER, notifier);
if (key.getName().equals(FileExtRootFilter.TSK_DOCUMENT_FILTER.getName())) {
return new FileTypesByExtNode(skCase, FileExtRootFilter.TSK_DOCUMENT_FILTER, notifier);
} else if (key.getName().equals(FileExtRootFilter.TSK_EXECUTABLE_FILTER.getName())) {
return new FileTypesByExtNode(skCase, FileExtRootFilter.TSK_EXECUTABLE_FILTER, notifier);
} else {
return new FileExtensionNode(key, skCase, notifier);
}
@ -337,7 +338,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
*/
final class FileExtensionNode extends FileTypes.BGCountUpdatingNode {
private final SearchFilterInterface filter;
private final FileExtSearchFilter filter;
/**
*
@ -346,10 +347,10 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
* @param o Observable that sends updates when the child factories
* should refresh
*/
FileExtensionNode(SearchFilterInterface filter, SleuthkitCase skCase, FileTypesByExtObservable o) {
FileExtensionNode(FileExtSearchFilter filter, SleuthkitCase skCase, FileTypesByExtObservable o) {
super(typesRoot, Children.LEAF,
Lookups.fixed(filter.getDisplayName(),
new FileTypeExtensionsKeyv2(
new FileTypeExtensionsSearchParam(
filter,
filteringDataSourceObjId() > 0 ? filteringDataSourceObjId() : null,
!UserPreferences.hideKnownFilesInViewsTree())));
@ -417,7 +418,7 @@ public final class FileTypesByExtension implements AutopsyVisitableItem {
}
}
private String createQuery(SearchFilterInterface filter) {
private String createQuery(FileExtSearchFilter filter) {
if (filter.getFilter().isEmpty()) {
// We should never be given a search filter without extensions
// but if we are it is clearly a programming error so we throw

View File

@ -1,111 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.datamodel;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Node;
import org.sleuthkit.autopsy.datamodel.SearchResultChildFactory.ChildKey;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.RowResultDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
/**
*
* @author gregd
*/
public class SearchResultChildFactory<T extends SearchResultsDTO<S>, S extends RowResultDTO> extends ChildFactory<ChildKey<T, S>> {
private final NodeCreator<T,S> nodeCreator;
private T results;
public SearchResultChildFactory(NodeCreator<T,S> nodeCreator, T initialResults) {
this.nodeCreator = nodeCreator;
this.results = initialResults;
}
@Override
protected boolean createKeys(List<ChildKey<T, S>> toPopulate) {
T results = this.results;
if (results != null) {
List<ChildKey<T, S>> childKeys = results.getItems().stream()
.map((item) -> new ChildKey<>(results, item))
.collect(Collectors.toList());
toPopulate.addAll(childKeys);
}
return true;
}
@Override
protected Node createNodeForKey(ChildKey<T, S> key) {
return this.nodeCreator.create(key.getSearchResults(), key.getChild());
}
public void update(T newResults) {
this.results = newResults;
this.refresh(false);
}
public long getResultCount() {
return results == null ? 0 : results.getTotalResultsCount();
}
public static interface NodeCreator<T extends SearchResultsDTO<S>, S extends RowResultDTO> {
Node create(T searchResults, S itemData);
}
static class ChildKey<T, S> {
private final T searchResults;
private final S child;
ChildKey(T searchResults, S child) {
this.searchResults = searchResults;
this.child = child;
}
T getSearchResults() {
return searchResults;
}
S getChild() {
return child;
}
@Override
public int hashCode() {
int hash = 3;
hash = 97 * hash + Objects.hashCode(this.child);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ChildKey<?, ?> other = (ChildKey<?, ?>) obj;
if (!Objects.equals(this.child, other.child)) {
return false;
}
return true;
}
}
}

View File

@ -1,225 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.datamodel;
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.List;
import org.openide.util.NbBundle.Messages;
public class ThreePanelDAO {
private static ThreePanelDAO instance = null;
public synchronized static ThreePanelDAO getInstance() {
if (instance == null) {
instance = new ThreePanelDAO();
}
return instance;
}
private final ThreePanelDataArtifactDAO dataArtifactDAO = ThreePanelDataArtifactDAO.getInstance();
private final ThreePanelViewsDAO viewsDAO = ThreePanelViewsDAO.getInstance();
public ThreePanelDataArtifactDAO getDataArtifactsDAO() {
return dataArtifactDAO;
}
public ThreePanelViewsDAO getViewsDAO() {
return viewsDAO;
}
public static class ColumnKey {
private final String fieldName;
private final String displayName;
private final String description;
public ColumnKey(String fieldName, String displayName, String description) {
this.fieldName = fieldName;
this.displayName = displayName;
this.description = description;
}
public String getFieldName() {
return fieldName;
}
public String getDisplayName() {
return displayName;
}
public String getDescription() {
return description;
}
}
public interface RowResultDTO {
List<Object> getCellValues();
long getId();
}
public static class BaseRowResultDTO implements RowResultDTO {
private final List<Object> cellValues;
private final long id;
public BaseRowResultDTO(List<Object> cellValues, long id) {
this.cellValues = cellValues;
this.id = id;
}
@Override
public List<Object> getCellValues() {
return cellValues;
}
@Override
public long getId() {
return id;
}
@Override
public int hashCode() {
int hash = 3;
hash = 23 * hash + (int) (this.id ^ (this.id >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final BaseRowResultDTO other = (BaseRowResultDTO) obj;
if (this.id != other.id) {
return false;
}
return true;
}
}
@Messages({
"CountsRowResultDTO_columns_displayName_name=displayName",
"CountsRowResultDTO_columns_displayName_displayName=Name",
"CountsRowResultDTO_columns_displayName_description=Name",
"CountsRowResultDTO_columns_count_name=displayName",
"CountsRowResultDTO_columns_count_displayName=Name",
"CountsRowResultDTO_columns_count_description=Name",})
public static class CountsRowResultDTO implements RowResultDTO {
public static ColumnKey DISPLAY_NAME_COL = new ColumnKey(
Bundle.CountsRowResultDTO_columns_displayName_name(),
Bundle.CountsRowResultDTO_columns_displayName_displayName(),
Bundle.CountsRowResultDTO_columns_displayName_description()
);
public static ColumnKey COUNT_COL = new ColumnKey(
Bundle.CountsRowResultDTO_columns_count_name(),
Bundle.CountsRowResultDTO_columns_count_displayName(),
Bundle.CountsRowResultDTO_columns_count_description()
);
private final long id;
private final String displayName;
private final long count;
private final List<Object> cellValues;
public CountsRowResultDTO(long id, String displayName, long count) {
this.id = id;
this.displayName = displayName;
this.count = count;
this.cellValues = ImmutableList.of(Arrays.asList(displayName, count));
}
@Override
public long getId() {
return id;
}
public String getDisplayName() {
return displayName;
}
public long getCount() {
return count;
}
@Override
public List<Object> getCellValues() {
return cellValues;
}
}
public static interface SearchResultsDTO<R extends RowResultDTO> {
String getTypeId();
String getDisplayName();
List<ColumnKey> getColumns();
List<R> getItems();
long getTotalResultsCount();
}
public static class BaseSearchResultsDTO<R extends RowResultDTO> implements SearchResultsDTO<R> {
private final String typeId;
private final String displayName;
private final List<ColumnKey> columns;
private final List<R> items;
private final long totalResultsCount;
public BaseSearchResultsDTO(String typeId, String displayName, List<ColumnKey> columns, List<R> items) {
this(typeId, displayName, columns, items, items == null ? 0 : items.size());
}
public BaseSearchResultsDTO(String typeId, String displayName, List<ColumnKey> columns, List<R> items, long totalResultsCount) {
this.typeId = typeId;
this.displayName = displayName;
this.columns = columns;
this.items = items;
this.totalResultsCount = totalResultsCount;
}
@Override
public String getTypeId() {
return typeId;
}
@Override
public String getDisplayName() {
return displayName;
}
@Override
public List<ColumnKey> getColumns() {
return columns;
}
@Override
public List<R> getItems() {
return items;
}
@Override
public long getTotalResultsCount() {
return totalResultsCount;
}
}
}

View File

@ -42,7 +42,7 @@ public class TskContentItem<T extends Content> {
*
*/
@Beta
TskContentItem(T content) {
public TskContentItem(T content) {
this.content = content;
}

View File

@ -1,181 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.Action;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.directorytree.ExplorerNodeActionVisitor;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.datamodel.Volume;
import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskData.TSK_VS_PART_FLAG_ENUM;
/**
* This class is used to represent the "Node" for the volume. Its child is the
* root directory of a file system
*/
public class VolumeNodev2 extends AbstractNode {
private static final Logger logger = Logger.getLogger(VolumeNodev2.class.getName());
public static class VolumeTableDTO {
private final Volume volume;
private final long id;
private final long addr;
private final long start;
private final long length;
private final String description;
private final boolean contiguousVolume; // based on vol.getParent() != null && vol.getParent().getParent() instanceof Pool
private final TskData.TSK_VS_PART_FLAG_ENUM partitionFlag; // see Volume.vsFlagToString
public VolumeTableDTO(Volume volume, long id, long addr, long start, long length, String description, boolean contiguousVolume, TSK_VS_PART_FLAG_ENUM partitionFlag) {
this.volume = volume;
this.id = id;
this.addr = addr;
this.start = start;
this.length = length;
this.description = description;
this.contiguousVolume = contiguousVolume;
this.partitionFlag = partitionFlag;
}
public long getAddr() {
return addr;
}
public long getStart() {
return start;
}
public long getLength() {
return length;
}
public String getDescription() {
return description;
}
public boolean isContiguousVolume() {
return contiguousVolume;
}
public TSK_VS_PART_FLAG_ENUM getPartitionFlag() {
return partitionFlag;
}
public long getId() {
return id;
}
public Volume getVolume() {
return volume;
}
}
private final VolumeTableDTO volData;
/**
*
* @param vol underlying Content instance
*/
public VolumeNodev2(VolumeTableDTO vol) {
super(ContentNodeUtilv2.getChildren(vol.getId()), ContentNodeUtilv2.getLookup(vol.getVolume()));
setIconBaseWithExtension("org/sleuthkit/autopsy/images/vol-icon.png");
setDisplayName(getDisplayName(vol));
setName(ContentNodeUtilv2.getContentName(vol.getId()));
this.volData = vol;
}
private String getDisplayName(VolumeTableDTO vol) {
// set name, display name, and icon
String volName = "vol" + Long.toString(vol.getAddr());
long end = vol.getStart() + (vol.getLength() - 1);
return vol.isContiguousVolume()
? volName + " (" + vol.getDescription() + ": " + vol.getStart() + "-" + end + ")"
: volName + " (" + vol.getDescription() + ": " + vol.getStart() + ")";
}
/**
* Right click action for volume node
*
* @param popup
*
* @return
*/
@Override
public Action[] getActions(boolean popup) {
List<Action> actionsList = new ArrayList<>();
actionsList.add(new FileSystemDetailsAction(volData.getVolume()));
actionsList.add(new NewWindowViewAction(
NbBundle.getMessage(this.getClass(), "VolumeNode.getActions.viewInNewWin.text"), this));
actionsList.addAll(ExplorerNodeActionVisitor.getActions(volData.getVolume()));
actionsList.add(null);
actionsList.addAll(Arrays.asList(super.getActions(true)));
return actionsList.toArray(new Action[actionsList.size()]);
}
@Override
protected Sheet createSheet() {
Sheet sheet = super.createSheet();
Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
if (sheetSet == null) {
sheetSet = Sheet.createPropertiesSet();
sheet.put(sheetSet);
}
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.name"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.displayName"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.desc"),
this.getDisplayName()));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.name"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.displayName"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.desc"),
volData.getAddr()));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.name"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.displayName"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.desc"),
volData.getStart()));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.name"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.displayName"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.desc"),
volData.getLength()));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.name"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.displayName"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.desc"),
volData.getDescription()));
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.name"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.displayName"),
NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.desc"),
Volume.vsFlagToString(volData.getPartitionFlag().getVsFlag())));
return sheet;
}
}

View File

@ -82,9 +82,9 @@ import org.sleuthkit.autopsy.datamodel.EmptyNode;
import org.sleuthkit.autopsy.datamodel.FileTypesByMimeType;
import org.sleuthkit.autopsy.datamodel.KeywordHits;
import org.sleuthkit.autopsy.datamodel.AutopsyTreeChildFactory;
import org.sleuthkit.autopsy.datamodel.DataArtifactKeyv2;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactSearchParam;
import org.sleuthkit.autopsy.datamodel.DataArtifacts;
import org.sleuthkit.autopsy.datamodel.FileTypeExtensionsKeyv2;
import org.sleuthkit.autopsy.mainui.datamodel.FileTypeExtensionsSearchParam;
import org.sleuthkit.autopsy.datamodel.OsAccounts;
import org.sleuthkit.autopsy.datamodel.PersonNode;
import org.sleuthkit.autopsy.datamodel.Tags;
@ -871,8 +871,8 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
//set node, wrap in filter node first to filter out children
Node drfn = new DataResultFilterNode(originNode, DirectoryTreeTopComponent.this.em);
// Create a TableFilterNode with knowledge of the node's type to allow for column order settings
DataArtifactKeyv2 dataArtifactKey = originNode.getLookup().lookup(DataArtifactKeyv2.class);
FileTypeExtensionsKeyv2 fileExtensionsKey = originNode.getLookup().lookup(FileTypeExtensionsKeyv2.class);
DataArtifactSearchParam dataArtifactKey = originNode.getLookup().lookup(DataArtifactSearchParam.class);
FileTypeExtensionsSearchParam fileExtensionsKey = originNode.getLookup().lookup(FileTypeExtensionsSearchParam.class);
if (dataArtifactKey != null) {
dataResult.displayDataArtifact(dataArtifactKey);
} else if (fileExtensionsKey != null) {

View File

@ -0,0 +1,78 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.List;
/**
* Base implementation for a row result.
*/
public class BaseRowResultDTO implements RowResultDTO {
private final List<Object> cellValues;
private final long id;
private final String typeId;
public BaseRowResultDTO(List<Object> cellValues, String typeId, long id) {
this.cellValues = cellValues;
this.id = id;
this.typeId = typeId;
}
@Override
public List<Object> getCellValues() {
return cellValues;
}
@Override
public long getId() {
return id;
}
@Override
public String getTypeId() {
return typeId;
}
@Override
public int hashCode() {
int hash = 3;
hash = 23 * hash + (int) (this.id ^ (this.id >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final BaseRowResultDTO other = (BaseRowResultDTO) obj;
if (this.id != other.id) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,77 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.List;
/**
* Base implementation for a series of results to be displayed in the results viewer.
*/
public class BaseSearchResultsDTO implements SearchResultsDTO {
private final String typeId;
private final String displayName;
private final List<ColumnKey> columns;
private final List<RowResultDTO> items;
private final long totalResultsCount;
private final long startItem;
public BaseSearchResultsDTO(String typeId, String displayName, List<ColumnKey> columns, List<RowResultDTO> items) {
this(typeId, displayName, columns, items, 0, items == null ? 0 : items.size());
}
public BaseSearchResultsDTO(String typeId, String displayName, List<ColumnKey> columns, List<RowResultDTO> items, long startItem, long totalResultsCount) {
this.typeId = typeId;
this.displayName = displayName;
this.columns = columns;
this.items = items;
this.startItem = startItem;
this.totalResultsCount = totalResultsCount;
}
@Override
public String getTypeId() {
return typeId;
}
@Override
public String getDisplayName() {
return displayName;
}
@Override
public List<ColumnKey> getColumns() {
return columns;
}
@Override
public List<RowResultDTO> getItems() {
return items;
}
@Override
public long getTotalResultsCount() {
return totalResultsCount;
}
@Override
public long getStartItem() {
return startItem;
}
}

View File

@ -0,0 +1,49 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
/**
* Describes a column to be displayed in the results table including the display
* name and description.
*/
public class ColumnKey {
private final String fieldName;
private final String displayName;
private final String description;
public ColumnKey(String fieldName, String displayName, String description) {
this.fieldName = fieldName;
this.displayName = displayName;
this.description = description;
}
public String getFieldName() {
return fieldName;
}
public String getDisplayName() {
return displayName;
}
public String getDescription() {
return description;
}
}

View File

@ -0,0 +1,92 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.List;
import org.openide.util.NbBundle.Messages;
/**
*
* A row result providing a category and a count for that category.
*/
@Messages({
"CountsRowResultDTO_columns_displayName_name=displayName",
"CountsRowResultDTO_columns_displayName_displayName=Name",
"CountsRowResultDTO_columns_displayName_description=Name",
"CountsRowResultDTO_columns_count_name=displayName",
"CountsRowResultDTO_columns_count_displayName=Name",
"CountsRowResultDTO_columns_count_description=Name"
})
public class CountsRowResultDTO implements RowResultDTO {
private static final String DEFAULT_TYPE_ID = "COUNTS";
public static ColumnKey DISPLAY_NAME_COL = new ColumnKey(
Bundle.CountsRowResultDTO_columns_displayName_name(),
Bundle.CountsRowResultDTO_columns_displayName_displayName(),
Bundle.CountsRowResultDTO_columns_displayName_description());
public static ColumnKey COUNT_COL = new ColumnKey(
Bundle.CountsRowResultDTO_columns_count_name(),
Bundle.CountsRowResultDTO_columns_count_displayName(),
Bundle.CountsRowResultDTO_columns_count_description());
private final long id;
private final String displayName;
private final long count;
private final List<Object> cellValues;
private final String typeId;
public CountsRowResultDTO(long id, String displayName, long count) {
this(DEFAULT_TYPE_ID, id, displayName, count);
}
public CountsRowResultDTO(String typeId, long id, String displayName, long count) {
this.typeId = typeId;
this.id = id;
this.displayName = displayName;
this.count = count;
this.cellValues = ImmutableList.of(Arrays.asList(displayName, count));
}
@Override
public long getId() {
return id;
}
public String getDisplayName() {
return displayName;
}
public long getCount() {
return count;
}
@Override
public List<Object> getCellValues() {
return cellValues;
}
@Override
public String getTypeId() {
return typeId;
}
}

View File

@ -1,22 +1,34 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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;
package org.sleuthkit.autopsy.mainui.datamodel;
import java.util.Objects;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
*
* @author gregd
* Key for data artifact in order to retrieve data from DAO.
*/
public class DataArtifactKeyv2 {
public class DataArtifactSearchParam {
private final BlackboardArtifact.Type artifactType;
private final Long dataSourceId;
public DataArtifactKeyv2(BlackboardArtifact.Type artifactType, Long dataSourceId) {
public DataArtifactSearchParam(BlackboardArtifact.Type artifactType, Long dataSourceId) {
this.artifactType = artifactType;
this.dataSourceId = dataSourceId;
}
@ -48,7 +60,7 @@ public class DataArtifactKeyv2 {
if (getClass() != obj.getClass()) {
return false;
}
final DataArtifactKeyv2 other = (DataArtifactKeyv2) obj;
final DataArtifactSearchParam other = (DataArtifactSearchParam) obj;
if (!Objects.equals(this.artifactType, other.artifactType)) {
return false;
}

View File

@ -0,0 +1,65 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.List;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataArtifact;
/**
* A result for a data artifact.
*/
public class DataArtifactTableDTO extends BaseRowResultDTO {
private static final String TYPE_ID = "DATA_ARTIFACT";
public static String getTypeIdForClass() {
return TYPE_ID;
}
final DataArtifact dataArtifact;
final Content srcContent;
final Content linkedFile;
final boolean isTimelineSupported;
public DataArtifactTableDTO(DataArtifact dataArtifact, Content srcContent, Content linkedFile, boolean isTimelineSupported, List<Object> cellValues, long id) {
super(cellValues, TYPE_ID, id);
this.dataArtifact = dataArtifact;
this.srcContent = srcContent;
this.linkedFile = linkedFile;
this.isTimelineSupported = isTimelineSupported;
}
public DataArtifact getDataArtifact() {
return dataArtifact;
}
public Content getSrcContent() {
return srcContent;
}
public Content getLinkedFile() {
return linkedFile;
}
public boolean isIsTimelineSupported() {
return isTimelineSupported;
}
}

View File

@ -0,0 +1,41 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.List;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
* Search results for data artifacts.
*/
public class DataArtifactTableSearchResultsDTO extends BaseSearchResultsDTO {
private static final String TYPE_ID = "DATA_ARTIFACT";
private final BlackboardArtifact.Type artifactType;
public DataArtifactTableSearchResultsDTO(BlackboardArtifact.Type artifactType, List<ColumnKey> columns, List<RowResultDTO> items) {
super(TYPE_ID, artifactType.getDisplayName(), columns, items);
this.artifactType = artifactType;
}
public BlackboardArtifact.Type getArtifactType() {
return artifactType;
}
}

View File

@ -0,0 +1,70 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.datamodel.FileTypesByExtension;
/**
* Document sub-node filters
*/
public enum FileExtDocumentFilter implements FileExtSearchFilter {
AUT_DOC_HTML(0, "AUT_DOC_HTML", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocHtmlFilter.text"), Arrays.asList(".htm", ".html")), //NON-NLS
AUT_DOC_OFFICE(1, "AUT_DOC_OFFICE", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocOfficeFilter.text"), Arrays.asList(".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx")), //NON-NLS
AUT_DOC_PDF(2, "AUT_DOC_PDF", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autoDocPdfFilter.text"), Arrays.asList(".pdf")), //NON-NLS
AUT_DOC_TXT(3, "AUT_DOC_TXT", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocTxtFilter.text"), Arrays.asList(".txt")), //NON-NLS
AUT_DOC_RTF(4, "AUT_DOC_RTF", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocRtfFilter.text"), Arrays.asList(".rtf"));
//NON-NLS
final int id;
final String name;
final String displayName;
final List<String> filter;
private FileExtDocumentFilter(int id, String name, String displayName, List<String> filter) {
this.id = id;
this.name = name;
this.displayName = displayName;
this.filter = filter;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getId() {
return this.id;
}
@Override
public String getDisplayName() {
return this.displayName;
}
@Override
public List<String> getFilter() {
return Collections.unmodifiableList(this.filter);
}
}

View File

@ -0,0 +1,67 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Executable sub-node filters.
*/
public enum FileExtExecutableFilter implements FileExtSearchFilter {
ExecutableFilter_EXE(0, "ExecutableFilter_EXE", ".exe", Arrays.asList(".exe")), //NON-NLS
ExecutableFilter_DLL(1, "ExecutableFilter_DLL", ".dll", Arrays.asList(".dll")), //NON-NLS
ExecutableFilter_BAT(2, "ExecutableFilter_BAT", ".bat", Arrays.asList(".bat")), //NON-NLS
ExecutableFilter_CMD(3, "ExecutableFilter_CMD", ".cmd", Arrays.asList(".cmd")), //NON-NLS
ExecutableFilter_COM(4, "ExecutableFilter_COM", ".com", Arrays.asList(".com"));
//NON-NLS
final int id;
final String name;
final String displayName;
final List<String> filter;
private FileExtExecutableFilter(int id, String name, String displayName, List<String> filter) {
this.id = id;
this.name = name;
this.displayName = displayName;
this.filter = filter;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getId() {
return this.id;
}
@Override
public String getDisplayName() {
return this.displayName;
}
@Override
public List<String> getFilter() {
return Collections.unmodifiableList(this.filter);
}
}

View File

@ -0,0 +1,68 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.datamodel.FileTypeExtensions;
import org.sleuthkit.autopsy.datamodel.FileTypesByExtension;
/**
* Root node filters
*/
@NbBundle.Messages(value = {"FileTypeExtensionFilters.tskDatabaseFilter.text=Databases"})
public enum FileExtRootFilter implements FileExtSearchFilter {
TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskImgFilter.text"), FileTypeExtensions.getImageExtensions()), TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskVideoFilter.text"), FileTypeExtensions.getVideoExtensions()), TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskAudioFilter.text"), FileTypeExtensions.getAudioExtensions()), TSK_ARCHIVE_FILTER(3, "TSK_ARCHIVE_FILTER", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskArchiveFilter.text"), FileTypeExtensions.getArchiveExtensions()), TSK_DATABASE_FILTER(4, "TSK_DATABASE_FILTER", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskDatabaseFilter.text"), FileTypeExtensions.getDatabaseExtensions()), TSK_DOCUMENT_FILTER(5, "TSK_DOCUMENT_FILTER", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskDocumentFilter.text"), Arrays.asList(".htm", ".html", ".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".rtf")), //NON-NLS
TSK_EXECUTABLE_FILTER(6, "TSK_EXECUTABLE_FILTER", NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskExecFilter.text"), FileTypeExtensions.getExecutableExtensions());
//NON-NLS
final int id;
final String name;
final String displayName;
final List<String> filter;
private FileExtRootFilter(int id, String name, String displayName, List<String> filter) {
this.id = id;
this.name = name;
this.displayName = displayName;
this.filter = filter;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getId() {
return this.id;
}
@Override
public String getDisplayName() {
return this.displayName;
}
@Override
public List<String> getFilter() {
return Collections.unmodifiableList(this.filter);
}
}

View File

@ -0,0 +1,36 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.List;
/**
* Interface for filters by file extensions.
*/
public interface FileExtSearchFilter {
public String getName();
public int getId();
public String getDisplayName();
public List<String> getFilter();
}

View File

@ -0,0 +1,87 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.List;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskData;
/**
* DTO Representing an abstract file in the results view.
*/
public class FileRowDTO extends BaseRowResultDTO {
public enum ExtensionMediaType {
IMAGE, VIDEO, AUDIO, DOC, EXECUTABLE, TEXT, WEB, PDF, ARCHIVE, UNCATEGORIZED
}
private static String TYPE_ID = "FILE";
public static String getTypeIdForClass() {
return TYPE_ID;
}
final AbstractFile abstractFile;
final String fileName;
final String extension;
final ExtensionMediaType extensionMediaType;
final boolean allocated;
final TskData.TSK_DB_FILES_TYPE_ENUM fileType;
final boolean encryptionDetected;
public FileRowDTO(AbstractFile abstractFile, long id, String fileName, String extension, ExtensionMediaType extensionMediaType, boolean allocated, TskData.TSK_DB_FILES_TYPE_ENUM fileType, boolean encryptionDetected, List<Object> cellValues) {
super(cellValues, TYPE_ID, id);
this.abstractFile = abstractFile;
this.fileName = fileName;
this.extension = extension;
this.extensionMediaType = extensionMediaType;
this.allocated = allocated;
this.fileType = fileType;
this.encryptionDetected = encryptionDetected;
}
public ExtensionMediaType getExtensionMediaType() {
return extensionMediaType;
}
public boolean getAllocated() {
return allocated;
}
public TskData.TSK_DB_FILES_TYPE_ENUM getFileType() {
return fileType;
}
public AbstractFile getAbstractFile() {
return abstractFile;
}
public String getExtension() {
return extension;
}
public boolean isEncryptionDetected() {
return encryptionDetected;
}
public String getFileName() {
return fileName;
}
}

View File

@ -1,30 +1,42 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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;
package org.sleuthkit.autopsy.mainui.datamodel;
import java.util.Objects;
import org.sleuthkit.autopsy.datamodel.ThreePanelViewsDAO.SearchFilterInterface;
/**
*
* @author gregd
* Key for accessing data about file type extensions from the DAO.
*/
public class FileTypeExtensionsKeyv2 {
private final SearchFilterInterface filter;
public class FileTypeExtensionsSearchParam {
private final FileExtSearchFilter filter;
private final Long dataSourceId;
private final boolean knownShown;
// this assumes that filters implicitly or explicitly implement hashCode and equals to work
public FileTypeExtensionsKeyv2(SearchFilterInterface filter, Long dataSourceId, boolean showKnown) {
public FileTypeExtensionsSearchParam(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) {
this.filter = filter;
this.dataSourceId = dataSourceId;
this.knownShown = showKnown;
}
public SearchFilterInterface getFilter() {
public FileExtSearchFilter getFilter() {
return filter;
}
@ -56,7 +68,7 @@ public class FileTypeExtensionsKeyv2 {
if (getClass() != obj.getClass()) {
return false;
}
final FileTypeExtensionsKeyv2 other = (FileTypeExtensionsKeyv2) obj;
final FileTypeExtensionsSearchParam other = (FileTypeExtensionsSearchParam) obj;
if (this.knownShown != other.knownShown) {
return false;
}
@ -68,6 +80,5 @@ public class FileTypeExtensionsKeyv2 {
}
return true;
}
}

View File

@ -0,0 +1,33 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.List;
/**
* DTO representing an individual row in search results.
*/
public interface RowResultDTO {
List<Object> getCellValues();
long getId();
String getTypeId();
}

View File

@ -0,0 +1,40 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
import java.util.List;
/**
*
* @author gregd
*/
public interface SearchResultsDTO {
String getTypeId();
String getDisplayName();
List<ColumnKey> getColumns();
List<RowResultDTO> getItems();
long getTotalResultsCount();
long getStartItem();
}

View File

@ -0,0 +1,47 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.datamodel;
/**
* Main entry point for DAO for providing data to populate the data results
* viewer.
*/
public class ThreePanelDAO {
private static ThreePanelDAO instance = null;
public synchronized static ThreePanelDAO getInstance() {
if (instance == null) {
instance = new ThreePanelDAO();
}
return instance;
}
private final ThreePanelDataArtifactDAO dataArtifactDAO = ThreePanelDataArtifactDAO.getInstance();
private final ThreePanelViewsDAO viewsDAO = ThreePanelViewsDAO.getInstance();
public ThreePanelDataArtifactDAO getDataArtifactsDAO() {
return dataArtifactDAO;
}
public ThreePanelViewsDAO getViewsDAO() {
return viewsDAO;
}
}

View File

@ -1,9 +1,22 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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;
package org.sleuthkit.autopsy.mainui.datamodel;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@ -22,9 +35,6 @@ import java.util.stream.Collectors;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.BaseRowResultDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.BaseSearchResultsDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.ColumnKey;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Blackboard;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -36,8 +46,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
*
* @author gregd
* DAO for providing data about data artifacts to populate the results viewer.
*/
@Messages({
"ThreePanelDataArtifactDAO.dataArtifact.columnKeys.srcFile.name=Source Name",
@ -110,7 +119,7 @@ public class ThreePanelDataArtifactDAO {
private static ThreePanelDataArtifactDAO instance = null;
public synchronized static ThreePanelDataArtifactDAO getInstance() {
synchronized static ThreePanelDataArtifactDAO getInstance() {
if (instance == null) {
instance = new ThreePanelDataArtifactDAO();
}
@ -118,13 +127,13 @@ public class ThreePanelDataArtifactDAO {
return instance;
}
private final Cache<DataArtifactKeyv2, DataArtifactTableSearchResultsDTO> dataArtifactCache = CacheBuilder.newBuilder().maximumSize(1000).build();
private final Cache<DataArtifactSearchParam, DataArtifactTableSearchResultsDTO> dataArtifactCache = CacheBuilder.newBuilder().maximumSize(1000).build();
private SleuthkitCase getCase() throws NoCurrentCaseException {
return Case.getCurrentCaseThrows().getSleuthkitCase();
}
private DataArtifactTableSearchResultsDTO fetchDataArtifactsForTable(DataArtifactKeyv2 cacheKey) throws NoCurrentCaseException, TskCoreException {
private DataArtifactTableSearchResultsDTO fetchDataArtifactsForTable(DataArtifactSearchParam cacheKey) throws NoCurrentCaseException, TskCoreException {
SleuthkitCase skCase = getCase();
Blackboard blackboard = skCase.getBlackboard();
@ -165,7 +174,7 @@ public class ThreePanelDataArtifactDAO {
columnKeys.add(DATASOURCE_COL);
// determine all different attribute types present as well as row data for each artifact
List<DataArtifactTableDTO> rows = new ArrayList<>();
List<RowResultDTO> rows = new ArrayList<>();
for (DataArtifact artifact : arts) {
List<Object> cellValues = new ArrayList<>();
@ -300,7 +309,7 @@ public class ThreePanelDataArtifactDAO {
}
}
public DataArtifactTableSearchResultsDTO getDataArtifactsForTable(DataArtifactKeyv2 artifactKey) throws ExecutionException, IllegalArgumentException {
public DataArtifactTableSearchResultsDTO getDataArtifactsForTable(DataArtifactSearchParam artifactKey) throws ExecutionException, IllegalArgumentException {
BlackboardArtifact.Type artType = artifactKey.getArtifactType();
if (artType == null || artType.getCategory() != BlackboardArtifact.Category.DATA_ARTIFACT
@ -316,55 +325,4 @@ public class ThreePanelDataArtifactDAO {
public void dropDataArtifactCache() {
dataArtifactCache.invalidateAll();
}
public static class DataArtifactTableDTO extends BaseRowResultDTO {
//private final Map<Integer, Object> attributeValues;
//private final String dataSourceName;
private final DataArtifact dataArtifact;
private final Content srcContent;
private final Content linkedFile;
private final boolean isTimelineSupported;
public DataArtifactTableDTO(DataArtifact dataArtifact, Content srcContent, Content linkedFile, boolean isTimelineSupported, List<Object> cellValues, long id) {
super(cellValues, id);
this.dataArtifact = dataArtifact;
this.srcContent = srcContent;
this.linkedFile = linkedFile;
this.isTimelineSupported = isTimelineSupported;
}
public DataArtifact getDataArtifact() {
return dataArtifact;
}
public Content getSrcContent() {
return srcContent;
}
public Content getLinkedFile() {
return linkedFile;
}
public boolean isIsTimelineSupported() {
return isTimelineSupported;
}
}
public static class DataArtifactTableSearchResultsDTO extends BaseSearchResultsDTO<DataArtifactTableDTO> {
private static final String TYPE_ID = "DATA_ARTIFACT";
private final BlackboardArtifact.Type artifactType;
public DataArtifactTableSearchResultsDTO(BlackboardArtifact.Type artifactType, List<ColumnKey> columns, List<DataArtifactTableDTO> items) {
super(TYPE_ID, artifactType.getDisplayName(), columns, items);
this.artifactType = artifactType;
}
public BlackboardArtifact.Type getArtifactType() {
return artifactType;
}
}
}

View File

@ -1,36 +1,49 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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;
package org.sleuthkit.autopsy.mainui.datamodel;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.BaseRowResultDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.BaseSearchResultsDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.ColumnKey;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.datamodel.FileTypeExtensions;
import org.sleuthkit.autopsy.mainui.datamodel.FileRowDTO.ExtensionMediaType;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
/**
* Provides information to populate the results viewer for data in the views
* section.
*/
@Messages({"ThreePanelViewsDAO.fileColumns.nameColLbl=Name",
"ThreePanelViewsDAO.fileColumns.originalName=Original Name",
"ThreePanelViewsDAO.fileColumns.scoreName=S",
@ -61,7 +74,7 @@ import org.sleuthkit.datamodel.TskData;
public class ThreePanelViewsDAO {
private static final String FILE_VIEW_EXT_TYPE_ID = "FILE_VIEW_BY_EXT";
private static final List<ColumnKey> FILE_COLUMNS = Arrays.asList(
getFileColumnKey(Bundle.ThreePanelViewsDAO_fileColumns_nameColLbl()),
getFileColumnKey(Bundle.ThreePanelViewsDAO_fileColumns_originalName()),
@ -92,7 +105,7 @@ public class ThreePanelViewsDAO {
private static ThreePanelViewsDAO instance = null;
public synchronized static ThreePanelViewsDAO getInstance() {
synchronized static ThreePanelViewsDAO getInstance() {
if (instance == null) {
instance = new ThreePanelViewsDAO();
}
@ -137,18 +150,18 @@ public class ThreePanelViewsDAO {
return Case.getCurrentCaseThrows().getSleuthkitCase();
}
private final Cache<FileTypeExtensionsKeyv2, SearchResultsDTO<FileRowDTO>> fileTypeByExtensionCache = CacheBuilder.newBuilder().maximumSize(1000).build();
public SearchResultsDTO<FileRowDTO> getFilesByExtension(FileTypeExtensionsKeyv2 key) throws ExecutionException, IllegalArgumentException {
private final Cache<FileTypeExtensionsSearchParam, SearchResultsDTO> fileTypeByExtensionCache = CacheBuilder.newBuilder().maximumSize(1000).build();
public SearchResultsDTO getFilesByExtension(FileTypeExtensionsSearchParam key) throws ExecutionException, IllegalArgumentException {
if (key.getFilter() == null) {
throw new IllegalArgumentException("Must have non-null filter");
} else if (key.getDataSourceId() != null && key.getDataSourceId() <= 0) {
throw new IllegalArgumentException("Data source id must be greater than 0 or null");
}
return fileTypeByExtensionCache.get(key, () -> fetchFileViewFiles(key.getFilter(), key.getDataSourceId(), key.isKnownShown()));
}
// private ViewFileTableSearchResultsDTO fetchFilesForTable(ViewFileCacheKey cacheKey) throws NoCurrentCaseException, TskCoreException {
//
// }
@ -163,9 +176,9 @@ public class ThreePanelViewsDAO {
// ViewFileCacheKey cacheKey = new ViewFileCacheKey(artType, dataSourceId);
// return dataArtifactCache.get(cacheKey, () -> fetchFilesForTable(cacheKey));
// }
private Map<Integer, Long> fetchFileViewCounts(List<SearchFilterInterface> filters, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
private Map<Integer, Long> fetchFileViewCounts(List<FileExtSearchFilter> filters, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
Map<Integer, Long> counts = new HashMap<>();
for (SearchFilterInterface filter : filters) {
for (FileExtSearchFilter filter : filters) {
String whereClause = getFileWhereStatement(filter, dataSourceId, showKnown);
long count = getCase().countFilesWhere(whereClause);
counts.put(filter.getId(), count);
@ -174,7 +187,7 @@ public class ThreePanelViewsDAO {
return counts;
}
private String getFileWhereStatement(SearchFilterInterface filter, Long dataSourceId, boolean showKnown) {
private String getFileWhereStatement(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) {
String whereClause = "(dir_type = " + TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue() + ")"
+ (showKnown
? " "
@ -189,11 +202,11 @@ public class ThreePanelViewsDAO {
return whereClause;
}
private SearchResultsDTO<FileRowDTO> fetchFileViewFiles(SearchFilterInterface filter, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
private SearchResultsDTO fetchFileViewFiles(FileExtSearchFilter filter, Long dataSourceId, boolean showKnown) throws NoCurrentCaseException, TskCoreException {
String whereStatement = getFileWhereStatement(filter, dataSourceId, showKnown);
List<AbstractFile> files = getCase().findAllFilesWhere(whereStatement);
List<FileRowDTO> fileRows = new ArrayList<>();
List<RowResultDTO> fileRows = new ArrayList<>();
for (AbstractFile file : files) {
boolean encryptionDetected = FileTypeExtensions.getArchiveExtensions().contains("." + file.getNameExtension().toLowerCase())
@ -233,240 +246,7 @@ public class ThreePanelViewsDAO {
cellValues));
}
return new BaseSearchResultsDTO<>(FILE_VIEW_EXT_TYPE_ID, filter.getDisplayName(), FILE_COLUMNS, fileRows);
return new BaseSearchResultsDTO(FILE_VIEW_EXT_TYPE_ID, filter.getDisplayName(), FILE_COLUMNS, fileRows);
}
// root node filters
@NbBundle.Messages({"FileTypeExtensionFilters.tskDatabaseFilter.text=Databases"})
public static enum RootFilter implements SearchFilterInterface {
TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskImgFilter.text"),
FileTypeExtensions.getImageExtensions()),
TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskVideoFilter.text"),
FileTypeExtensions.getVideoExtensions()),
TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskAudioFilter.text"),
FileTypeExtensions.getAudioExtensions()),
TSK_ARCHIVE_FILTER(3, "TSK_ARCHIVE_FILTER", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskArchiveFilter.text"),
FileTypeExtensions.getArchiveExtensions()),
TSK_DATABASE_FILTER(4, "TSK_DATABASE_FILTER", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskDatabaseFilter.text"),
FileTypeExtensions.getDatabaseExtensions()),
TSK_DOCUMENT_FILTER(5, "TSK_DOCUMENT_FILTER", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskDocumentFilter.text"),
Arrays.asList(".htm", ".html", ".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".rtf")), //NON-NLS
TSK_EXECUTABLE_FILTER(6, "TSK_EXECUTABLE_FILTER", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskExecFilter.text"),
FileTypeExtensions.getExecutableExtensions()); //NON-NLS
private final int id;
private final String name;
private final String displayName;
private final List<String> filter;
private RootFilter(int id, String name, String displayName, List<String> filter) {
this.id = id;
this.name = name;
this.displayName = displayName;
this.filter = filter;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getId() {
return this.id;
}
@Override
public String getDisplayName() {
return this.displayName;
}
@Override
public List<String> getFilter() {
return Collections.unmodifiableList(this.filter);
}
}
// document sub-node filters
public static enum DocumentFilter implements SearchFilterInterface {
AUT_DOC_HTML(0, "AUT_DOC_HTML", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocHtmlFilter.text"),
Arrays.asList(".htm", ".html")), //NON-NLS
AUT_DOC_OFFICE(1, "AUT_DOC_OFFICE", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocOfficeFilter.text"),
Arrays.asList(".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx")), //NON-NLS
AUT_DOC_PDF(2, "AUT_DOC_PDF", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autoDocPdfFilter.text"),
Arrays.asList(".pdf")), //NON-NLS
AUT_DOC_TXT(3, "AUT_DOC_TXT", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocTxtFilter.text"),
Arrays.asList(".txt")), //NON-NLS
AUT_DOC_RTF(4, "AUT_DOC_RTF", //NON-NLS
NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocRtfFilter.text"),
Arrays.asList(".rtf")); //NON-NLS
private final int id;
private final String name;
private final String displayName;
private final List<String> filter;
private DocumentFilter(int id, String name, String displayName, List<String> filter) {
this.id = id;
this.name = name;
this.displayName = displayName;
this.filter = filter;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getId() {
return this.id;
}
@Override
public String getDisplayName() {
return this.displayName;
}
@Override
public List<String> getFilter() {
return Collections.unmodifiableList(this.filter);
}
}
// executable sub-node filters
public static enum ExecutableFilter implements SearchFilterInterface {
ExecutableFilter_EXE(0, "ExecutableFilter_EXE", ".exe", Arrays.asList(".exe")), //NON-NLS
ExecutableFilter_DLL(1, "ExecutableFilter_DLL", ".dll", Arrays.asList(".dll")), //NON-NLS
ExecutableFilter_BAT(2, "ExecutableFilter_BAT", ".bat", Arrays.asList(".bat")), //NON-NLS
ExecutableFilter_CMD(3, "ExecutableFilter_CMD", ".cmd", Arrays.asList(".cmd")), //NON-NLS
ExecutableFilter_COM(4, "ExecutableFilter_COM", ".com", Arrays.asList(".com")); //NON-NLS
private final int id;
private final String name;
private final String displayName;
private final List<String> filter;
private ExecutableFilter(int id, String name, String displayName, List<String> filter) {
this.id = id;
this.name = name;
this.displayName = displayName;
this.filter = filter;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getId() {
return this.id;
}
@Override
public String getDisplayName() {
return this.displayName;
}
@Override
public List<String> getFilter() {
return Collections.unmodifiableList(this.filter);
}
}
public interface SearchFilterInterface {
public String getName();
public int getId();
public String getDisplayName();
public List<String> getFilter();
}
public enum ExtensionMediaType {
IMAGE,
VIDEO,
AUDIO,
DOC,
EXECUTABLE,
TEXT,
WEB,
PDF,
ARCHIVE,
UNCATEGORIZED
}
public static class FileRowDTO extends BaseRowResultDTO {
private final AbstractFile abstractFile;
private final String fileName;
private final String extension;
private final ExtensionMediaType extensionMediaType;
private final boolean allocated;
private final TskData.TSK_DB_FILES_TYPE_ENUM fileType;
private final boolean encryptionDetected;
public FileRowDTO(AbstractFile abstractFile, long id, String fileName,
String extension, ExtensionMediaType extensionMediaType,
boolean allocated,
TskData.TSK_DB_FILES_TYPE_ENUM fileType,
boolean encryptionDetected, List<Object> cellValues) {
super(cellValues, id);
this.abstractFile = abstractFile;
this.fileName = fileName;
this.extension = extension;
this.extensionMediaType = extensionMediaType;
this.allocated = allocated;
this.fileType = fileType;
this.encryptionDetected = encryptionDetected;
}
public ExtensionMediaType getExtensionMediaType() {
return extensionMediaType;
}
public boolean getAllocated() {
return allocated;
}
public TskData.TSK_DB_FILES_TYPE_ENUM getFileType() {
return fileType;
}
public AbstractFile getAbstractFile() {
return abstractFile;
}
public String getExtension() {
return extension;
}
public boolean isEncryptionDetected() {
return encryptionDetected;
}
public String getFileName() {
return fileName;
}
}
}

View File

@ -1,25 +1,39 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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;
package org.sleuthkit.autopsy.mainui.nodes;
import java.util.Date;
import java.util.List;
import org.openide.nodes.Children;
import org.openide.nodes.Sheet;
import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.ColumnKey;
import org.sleuthkit.autopsy.datamodel.DirectoryNode;
import org.sleuthkit.autopsy.datamodel.NodeProperty;
import org.sleuthkit.autopsy.datamodel.TskContentItem;
import org.sleuthkit.autopsy.mainui.datamodel.ColumnKey;
import org.sleuthkit.datamodel.Content;
/**
*
* @author gregd
* Utilities for setting up nodes that handle content.
*/
public class ContentNodeUtilv2 {
public class ContentNodeUtil {
public static String getContentDisplayName(String fileName) {
switch (fileName) {
@ -40,11 +54,6 @@ public class ContentNodeUtilv2 {
return Lookups.fixed(content, new TskContentItem<>(content));
}
public static Children getChildren(long id) {
throw new UnsupportedOperationException("Not supported...");
//return Children.create(new ContentChildren(content), true);
}
public static Sheet setSheet(Sheet sheet, List<ColumnKey> columnKeys, List<Object> values) {
Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
if (sheetSet == null) {

View File

@ -16,14 +16,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.datamodel;
package org.sleuthkit.autopsy.mainui.nodes;
import org.sleuthkit.autopsy.actions.ViewArtifactAction;
import org.sleuthkit.autopsy.actions.ViewOsAccountAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -49,16 +48,25 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.datamodel.utils.IconsUtil;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.ColumnKey;
import org.sleuthkit.autopsy.datamodel.ThreePanelDataArtifactDAO.DataArtifactTableDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDataArtifactDAO.DataArtifactTableSearchResultsDTO;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactItem;
import org.sleuthkit.autopsy.datamodel.DataArtifactItem;
import org.sleuthkit.autopsy.datamodel.DataModelActionsFactory;
import org.sleuthkit.autopsy.datamodel.DirectoryNode;
import org.sleuthkit.autopsy.datamodel.FileNode;
import org.sleuthkit.autopsy.datamodel.LayoutFileNode;
import org.sleuthkit.autopsy.datamodel.LocalDirectoryNode;
import org.sleuthkit.autopsy.datamodel.LocalFileNode;
import org.sleuthkit.autopsy.datamodel.SlackFileNode;
import org.sleuthkit.autopsy.datamodel.VirtualDirectoryNode;
import org.sleuthkit.autopsy.mainui.datamodel.ColumnKey;
import org.sleuthkit.autopsy.directorytree.ExportCSVAction;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactTableDTO;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactTableSearchResultsDTO;
import org.sleuthkit.datamodel.DataArtifact;
import org.sleuthkit.datamodel.DerivedFile;
import org.sleuthkit.datamodel.Directory;
@ -71,9 +79,12 @@ import org.sleuthkit.datamodel.Report;
import org.sleuthkit.datamodel.SlackFile;
import org.sleuthkit.datamodel.VirtualDirectory;
public class DataArtifactNodev2 extends AbstractNode {
/**
* node to display a data artifact.
*/
public class DataArtifactNode extends AbstractNode {
private static final Logger logger = Logger.getLogger(DataArtifactNodev2.class.getName());
private static final Logger logger = Logger.getLogger(DataArtifactNode.class.getName());
private static Lookup createLookup(DataArtifactTableDTO row) {
DataArtifactItem artifactItem = new DataArtifactItem(row.getDataArtifact(), row.getSrcContent());
@ -88,18 +99,18 @@ public class DataArtifactNodev2 extends AbstractNode {
private final DataArtifactTableDTO artifactRow;
private final List<ColumnKey> columns;
public DataArtifactNodev2(DataArtifactTableSearchResultsDTO tableData, DataArtifactTableDTO artifactRow) {
public DataArtifactNode(DataArtifactTableSearchResultsDTO tableData, DataArtifactTableDTO artifactRow) {
this(tableData, artifactRow, IconsUtil.getIconFilePath(tableData.getArtifactType().getTypeID()));
}
public DataArtifactNodev2(DataArtifactTableSearchResultsDTO tableData, DataArtifactTableDTO artifactRow, String iconPath) {
public DataArtifactNode(DataArtifactTableSearchResultsDTO tableData, DataArtifactTableDTO artifactRow, String iconPath) {
super(Children.LEAF, createLookup(artifactRow));
// use first cell value for display name
String displayName = artifactRow.getCellValues().size() > 0
? artifactRow.getCellValues().get(0).toString()
: "";
setDisplayName(displayName);
setShortDescription(displayName);
setName(Long.toString(artifactRow.getId()));
@ -193,16 +204,16 @@ public class DataArtifactNodev2 extends AbstractNode {
* @return The artifact type name.
*/
@Messages({
"DataArtifactNodev2_getAssociatedTypeStr_webCache=Cached File",
"DataArtifactNodev2_getAssociatedTypeStr_webDownload=Downloaded File",
"DataArtifactNodev2_getAssociatedTypeStr_associated=Associated File",})
"DataArtifactNode_getAssociatedTypeStr_webCache=Cached File",
"DataArtifactNode_getAssociatedTypeStr_webDownload=Downloaded File",
"DataArtifactNode_getAssociatedTypeStr_associated=Associated File",})
private String getAssociatedTypeStr(BlackboardArtifact.Type artifactType) {
if (BlackboardArtifact.Type.TSK_WEB_CACHE.equals(artifactType)) {
return Bundle.DataArtifactNodev2_getAssociatedTypeStr_webCache();
return Bundle.DataArtifactNode_getAssociatedTypeStr_webCache();
} else if (BlackboardArtifact.Type.TSK_WEB_DOWNLOAD.equals(artifactType)) {
return Bundle.DataArtifactNodev2_getAssociatedTypeStr_webDownload();
return Bundle.DataArtifactNode_getAssociatedTypeStr_webDownload();
} else {
return Bundle.DataArtifactNodev2_getAssociatedTypeStr_associated();
return Bundle.DataArtifactNode_getAssociatedTypeStr_associated();
}
}
@ -215,38 +226,38 @@ public class DataArtifactNodev2 extends AbstractNode {
* @return The name of the type of content.
*/
@Messages({
"DataArtifactNodev2_getViewSrcContentAction_type_File=File",
"DataArtifactNodev2_getViewSrcContentAction_type_DataArtifact=Data Artifact",
"DataArtifactNodev2_getViewSrcContentAction_type_OSAccount=OS Account",
"DataArtifactNodev2_getViewSrcContentAction_type_unknown=Item"
"DataArtifactNode_getViewSrcContentAction_type_File=File",
"DataArtifactNode_getViewSrcContentAction_type_DataArtifact=Data Artifact",
"DataArtifactNode_getViewSrcContentAction_type_OSAccount=OS Account",
"DataArtifactNode_getViewSrcContentAction_type_unknown=Item"
})
private String getContentTypeStr(Content content) {
if (content instanceof AbstractFile) {
return Bundle.DataArtifactNodev2_getViewSrcContentAction_type_File();
return Bundle.DataArtifactNode_getViewSrcContentAction_type_File();
} else if (content instanceof DataArtifact) {
return Bundle.DataArtifactNodev2_getViewSrcContentAction_type_DataArtifact();
return Bundle.DataArtifactNode_getViewSrcContentAction_type_DataArtifact();
} else if (content instanceof OsAccount) {
return Bundle.DataArtifactNodev2_getViewSrcContentAction_type_OSAccount();
return Bundle.DataArtifactNode_getViewSrcContentAction_type_OSAccount();
} else {
return Bundle.DataArtifactNodev2_getViewSrcContentAction_type_unknown();
return Bundle.DataArtifactNode_getViewSrcContentAction_type_unknown();
}
}
@Messages({
"# {0} - type",
"DataArtifactNodev2_getAssociatedFileActions_viewAssociatedFileAction=View {0} in Directory",
"DataArtifactNode_getAssociatedFileActions_viewAssociatedFileAction=View {0} in Directory",
"# {0} - type",
"DataArtifactNodev2_getAssociatedFileActions_viewAssociatedFileInTimelineAction=View {0} in Timeline..."
"DataArtifactNode_getAssociatedFileActions_viewAssociatedFileInTimelineAction=View {0} in Timeline..."
})
private List<Action> getAssociatedFileActions(AbstractFile associatedFile, BlackboardArtifact.Type artifactType) {
if (associatedFile != null) {
return Arrays.asList(
new ViewContextAction(
Bundle.DataArtifactNodev2_getAssociatedFileActions_viewAssociatedFileAction(
Bundle.DataArtifactNode_getAssociatedFileActions_viewAssociatedFileAction(
getAssociatedTypeStr(artifactType)),
associatedFile),
new ViewFileInTimelineAction(associatedFile,
Bundle.DataArtifactNodev2_getAssociatedFileActions_viewAssociatedFileInTimelineAction(
Bundle.DataArtifactNode_getAssociatedFileActions_viewAssociatedFileInTimelineAction(
getAssociatedTypeStr(artifactType)))
);
} else {
@ -265,22 +276,22 @@ public class DataArtifactNodev2 extends AbstractNode {
*/
@Messages({
"# {0} - contentType",
"DataArtifactNodev2_getSrcContentAction_actionDisplayName=View Source {0} in Directory"
"DataArtifactNode_getSrcContentAction_actionDisplayName=View Source {0} in Directory"
})
private Action getViewSrcContentAction(BlackboardArtifact artifact, Content content) {
if (content instanceof DataArtifact) {
return new ViewArtifactAction(
(BlackboardArtifact) content,
Bundle.DataArtifactNodev2_getSrcContentAction_actionDisplayName(
Bundle.DataArtifactNode_getSrcContentAction_actionDisplayName(
getContentTypeStr(content)));
} else if (content instanceof OsAccount) {
return new ViewOsAccountAction(
(OsAccount) content,
Bundle.DataArtifactNodev2_getSrcContentAction_actionDisplayName(
Bundle.DataArtifactNode_getSrcContentAction_actionDisplayName(
getContentTypeStr(content)));
} else if (content instanceof AbstractFile || artifact instanceof DataArtifact) {
return new ViewContextAction(
Bundle.DataArtifactNodev2_getSrcContentAction_actionDisplayName(
Bundle.DataArtifactNode_getSrcContentAction_actionDisplayName(
getContentTypeStr(content)),
content);
} else {
@ -358,15 +369,15 @@ public class DataArtifactNodev2 extends AbstractNode {
* @return The list of actions or an empty list.
*/
@Messages({
"DataArtifactNodev2_getSrcContentViewerActions_viewInNewWin=View Item in New Window",
"DataArtifactNodev2_getSrcContentViewerActions_openInExtViewer=Open in External Viewer Ctrl+E"
"DataArtifactNode_getSrcContentViewerActions_viewInNewWin=View Item in New Window",
"DataArtifactNode_getSrcContentViewerActions_openInExtViewer=Open in External Viewer Ctrl+E"
})
private List<Action> getSrcContentViewerActions(Node srcFileNode, int selectedFileCount) {
List<Action> actionsList = new ArrayList<>();
if (srcFileNode != null) {
actionsList.add(new NewWindowViewAction(Bundle.DataArtifactNodev2_getSrcContentViewerActions_viewInNewWin(), srcFileNode));
actionsList.add(new NewWindowViewAction(Bundle.DataArtifactNode_getSrcContentViewerActions_viewInNewWin(), srcFileNode));
if (selectedFileCount == 1) {
actionsList.add(new ExternalViewerAction(Bundle.DataArtifactNodev2_getSrcContentViewerActions_openInExtViewer(), srcFileNode));
actionsList.add(new ExternalViewerAction(Bundle.DataArtifactNode_getSrcContentViewerActions_openInExtViewer(), srcFileNode));
} else {
actionsList.add(ExternalViewerShortcutAction.getInstance());
}
@ -384,12 +395,12 @@ public class DataArtifactNodev2 extends AbstractNode {
*/
@NbBundle.Messages({
"# {0} - contentType",
"DataArtifactNodev2_getTimelineSrcContentAction_actionDisplayName=View Source {0} in Timeline... "
"DataArtifactNode_getTimelineSrcContentAction_actionDisplayName=View Source {0} in Timeline... "
})
private Action getTimelineSrcContentAction(Content srcContent) {
if (srcContent instanceof AbstractFile) {
return new ViewFileInTimelineAction((AbstractFile) srcContent,
Bundle.DataArtifactNodev2_getTimelineSrcContentAction_actionDisplayName(
Bundle.DataArtifactNode_getTimelineSrcContentAction_actionDisplayName(
getContentTypeStr(srcContent)));
}
@ -398,7 +409,7 @@ public class DataArtifactNodev2 extends AbstractNode {
// try {
// if (hasSupportedTimeStamp((BlackboardArtifact) srcContent)) {
// return new ViewArtifactInTimelineAction((BlackboardArtifact) srcContent,
// Bundle.DataArtifactNodev2_getTimelineSrcContentAction_actionDisplayName(
// Bundle.DataArtifactNode_getTimelineSrcContentAction_actionDisplayName(
// getContentTypeStr(srcContent)));
// }
// } catch (TskCoreException ex) {
@ -418,11 +429,11 @@ public class DataArtifactNodev2 extends AbstractNode {
* @return The action or null if no action should exist.
*/
@Messages({
"DataArtifactNodev2_getTimelineArtifactAction_displayName=View Selected Item in Timeline... "
"DataArtifactNode_getTimelineArtifactAction_displayName=View Selected Item in Timeline... "
})
private Action getTimelineArtifactAction(BlackboardArtifact art, boolean hasSupportedTimeStamp) {
if (hasSupportedTimeStamp) {
return new ViewArtifactInTimelineAction(art, Bundle.DataArtifactNodev2_getTimelineArtifactAction_displayName());
return new ViewArtifactInTimelineAction(art, Bundle.DataArtifactNode_getTimelineArtifactAction_displayName());
} else {
return null;
}
@ -430,6 +441,6 @@ public class DataArtifactNodev2 extends AbstractNode {
@Override
protected Sheet createSheet() {
return ContentNodeUtilv2.setSheet(super.createSheet(), this.columns, this.artifactRow.getCellValues());
return ContentNodeUtil.setSheet(super.createSheet(), this.columns, this.artifactRow.getCellValues());
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2019 Basis Technology Corp.
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.datamodel;
package org.sleuthkit.autopsy.mainui.nodes;
import java.util.ArrayList;
import java.util.Arrays;
@ -32,25 +32,24 @@ import org.openide.util.Utilities;
import org.sleuthkit.autopsy.actions.AddContentTagAction;
import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelViewsDAO.ExtensionMediaType;
import org.sleuthkit.autopsy.datamodel.ThreePanelViewsDAO.FileRowDTO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
import org.sleuthkit.autopsy.mainui.datamodel.FileRowDTO;
import org.sleuthkit.autopsy.directorytree.ExportCSVAction;
import org.sleuthkit.autopsy.directorytree.ExternalViewerAction;
import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction;
import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.mainui.datamodel.ColumnKey;
import org.sleuthkit.autopsy.mainui.datamodel.FileRowDTO.ExtensionMediaType;
import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction;
import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM;
/**
* A node for representing an AbstractFile. It may have derived file node
* children.
* A node for representing an AbstractFile.
*/
public class FileNodev2 extends AbstractNode {
public class FileNode extends AbstractNode {
/**
* Gets the path to the icon file that should be used to visually represent
@ -92,20 +91,20 @@ public class FileNodev2 extends AbstractNode {
private final boolean directoryBrowseMode;
private final FileRowDTO fileData;
private final List<ThreePanelDAO.ColumnKey> columns;
private final List<ColumnKey> columns;
public FileNodev2(SearchResultsDTO<FileRowDTO> results, FileRowDTO file) {
public FileNode(SearchResultsDTO results, FileRowDTO file) {
this(results, file, true);
}
public FileNodev2(SearchResultsDTO<FileRowDTO> results, FileRowDTO file, boolean directoryBrowseMode) {
public FileNode(SearchResultsDTO results, FileRowDTO file, boolean directoryBrowseMode) {
// GVDTODO: at some point, this leaf will need to allow for children
super(Children.LEAF, ContentNodeUtilv2.getLookup(file.getAbstractFile()));
super(Children.LEAF, ContentNodeUtil.getLookup(file.getAbstractFile()));
setIcon(file);
setDisplayName(ContentNodeUtilv2.getContentDisplayName(file.getFileName()));
setName(ContentNodeUtilv2.getContentName(file.getId()));
setDisplayName(ContentNodeUtil.getContentDisplayName(file.getFileName()));
setName(ContentNodeUtil.getContentName(file.getId()));
this.directoryBrowseMode = directoryBrowseMode;
this.fileData = file;
this.columns = results.getColumns();
@ -186,6 +185,6 @@ public class FileNodev2 extends AbstractNode {
@Override
protected Sheet createSheet() {
return ContentNodeUtilv2.setSheet(super.createSheet(), this.columns, this.fileData.getCellValues());
return ContentNodeUtil.setSheet(super.createSheet(), this.columns, this.fileData.getCellValues());
}
}

View File

@ -0,0 +1,132 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.mainui.nodes;
import java.text.MessageFormat;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Node;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactTableDTO;
import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactTableSearchResultsDTO;
import org.sleuthkit.autopsy.mainui.datamodel.FileRowDTO;
import org.sleuthkit.autopsy.mainui.nodes.SearchResultChildFactory.ChildKey;
import org.sleuthkit.autopsy.mainui.datamodel.RowResultDTO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
/**
* Factory for populating results in a results viewer with a SearchResultsDTO.
*/
public class SearchResultChildFactory extends ChildFactory<ChildKey> {
private static final Logger logger = Logger.getLogger(SearchResultChildFactory.class.getName());
private SearchResultsDTO results;
public SearchResultChildFactory(SearchResultsDTO initialResults) {
this.results = initialResults;
}
@Override
protected boolean createKeys(List<ChildKey> toPopulate) {
SearchResultsDTO results = this.results;
if (results != null) {
List<ChildKey> childKeys = results.getItems().stream()
.map((item) -> new ChildKey(results, item))
.collect(Collectors.toList());
toPopulate.addAll(childKeys);
}
return true;
}
@Override
protected Node createNodeForKey(ChildKey key) {
String typeId = key.getRow().getTypeId();
try {
if (DataArtifactTableDTO.getTypeIdForClass().equals(typeId)) {
return new DataArtifactNode((DataArtifactTableSearchResultsDTO) key.getSearchResults(), (DataArtifactTableDTO) key.getRow());
} else if (DataArtifactTableDTO.getTypeIdForClass().equals(typeId)) {
return new FileNode(key.getSearchResults(), (FileRowDTO) key.getRow());
}
} catch (ClassCastException ex) {
logger.log(Level.WARNING, MessageFormat.format("Could not cast item with type id: {0} to valid type.", typeId), ex);
}
return null;
}
public void update(SearchResultsDTO newResults) {
this.results = newResults;
this.refresh(false);
}
public long getResultCount() {
return results == null ? 0 : results.getTotalResultsCount();
}
static class ChildKey {
private final SearchResultsDTO searchResults;
private final RowResultDTO row;
ChildKey(SearchResultsDTO searchResults, RowResultDTO child) {
this.searchResults = searchResults;
this.row = child;
}
SearchResultsDTO getSearchResults() {
return searchResults;
}
RowResultDTO getRow() {
return row;
}
@Override
public int hashCode() {
int hash = 3;
hash = 97 * hash + Objects.hashCode(this.row);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ChildKey other = (ChildKey) obj;
if (!Objects.equals(this.row, other.row)) {
return false;
}
return true;
}
}
}

View File

@ -1,37 +1,46 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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;
package org.sleuthkit.autopsy.mainui.nodes;
import java.util.Collections;
import java.util.List;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.datamodel.SearchResultChildFactory.NodeCreator;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.ColumnKey;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.RowResultDTO;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.datamodel.NodeProperty;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
/**
*
* @author gregd
* A node whose children will be displayed in the results view and determines
* children based on a SearchResultDTO.
*/
public class SearchResultTableNode<T extends SearchResultsDTO<S>, S extends RowResultDTO> extends AbstractNode {
public class SearchResultRootNode extends AbstractNode {
private final SearchResultChildFactory<T, S> factory;
private final SearchResultChildFactory factory;
public SearchResultTableNode(NodeCreator<T, S> nodeCreator, T initialResults) {
this(initialResults, new SearchResultChildFactory<>(nodeCreator, initialResults));
public SearchResultRootNode(SearchResultsDTO initialResults) {
this(initialResults, new SearchResultChildFactory(initialResults));
}
private SearchResultTableNode(SearchResultsDTO<S> initialResults, SearchResultChildFactory<T, S> factory) {
private SearchResultRootNode(SearchResultsDTO initialResults, SearchResultChildFactory factory) {
super(Children.create(factory, true));
this.factory = factory;
setName(initialResults.getTypeId());
setDisplayName(initialResults.getDisplayName());

View File

@ -0,0 +1,182 @@
///*
// * Autopsy Forensic Browser
// *
// * Copyright 2011-2021 Basis Technology Corp.
// * Contact: carrier <at> sleuthkit <dot> 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.mainui.nodes;
//
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//import javax.swing.Action;
//import org.openide.nodes.AbstractNode;
//import org.openide.nodes.Sheet;
//import org.openide.util.NbBundle;
//import org.sleuthkit.autopsy.coreutils.Logger;
//import org.sleuthkit.autopsy.datamodel.NodeProperty;
//import org.sleuthkit.autopsy.directorytree.ExplorerNodeActionVisitor;
//import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
//import org.sleuthkit.datamodel.Volume;
//import org.sleuthkit.autopsy.directorytree.FileSystemDetailsAction;
//import org.sleuthkit.datamodel.TskData;
//import org.sleuthkit.datamodel.TskData.TSK_VS_PART_FLAG_ENUM;
//
///**
// * This class is used to represent the "Node" for the volume. Its child is the
// * root directory of a file system
// */
//public class VolumeNodev2 extends AbstractNode {
//
// private static final Logger logger = Logger.getLogger(VolumeNodev2.class.getName());
//
// public static class VolumeTableDTO {
//
// private final Volume volume;
// private final long id;
// private final long addr;
// private final long start;
// private final long length;
// private final String description;
// private final boolean contiguousVolume; // based on vol.getParent() != null && vol.getParent().getParent() instanceof Pool
// private final TskData.TSK_VS_PART_FLAG_ENUM partitionFlag; // see Volume.vsFlagToString
//
// public VolumeTableDTO(Volume volume, long id, long addr, long start, long length, String description, boolean contiguousVolume, TSK_VS_PART_FLAG_ENUM partitionFlag) {
// this.volume = volume;
// this.id = id;
// this.addr = addr;
// this.start = start;
// this.length = length;
// this.description = description;
// this.contiguousVolume = contiguousVolume;
// this.partitionFlag = partitionFlag;
// }
//
//
// public long getAddr() {
// return addr;
// }
//
// public long getStart() {
// return start;
// }
//
// public long getLength() {
// return length;
// }
//
// public String getDescription() {
// return description;
// }
//
// public boolean isContiguousVolume() {
// return contiguousVolume;
// }
//
// public TSK_VS_PART_FLAG_ENUM getPartitionFlag() {
// return partitionFlag;
// }
//
// public long getId() {
// return id;
// }
//
// public Volume getVolume() {
// return volume;
// }
//
// }
//
// private final VolumeTableDTO volData;
//
// /**
// *
// * @param vol underlying Content instance
// */
// public VolumeNodev2(VolumeTableDTO vol) {
// super(ContentNodeUtilv2.getChildren(vol.getId()), ContentNodeUtilv2.getLookup(vol.getVolume()));
// setIconBaseWithExtension("org/sleuthkit/autopsy/images/vol-icon.png");
// setDisplayName(getDisplayName(vol));
// setName(ContentNodeUtilv2.getContentName(vol.getId()));
// this.volData = vol;
//
// }
//
// private String getDisplayName(VolumeTableDTO vol) {
// // set name, display name, and icon
// String volName = "vol" + Long.toString(vol.getAddr());
// long end = vol.getStart() + (vol.getLength() - 1);
// return vol.isContiguousVolume()
// ? volName + " (" + vol.getDescription() + ": " + vol.getStart() + "-" + end + ")"
// : volName + " (" + vol.getDescription() + ": " + vol.getStart() + ")";
// }
//
// /**
// * Right click action for volume node
// *
// * @param popup
// *
// * @return
// */
// @Override
// public Action[] getActions(boolean popup) {
// List<Action> actionsList = new ArrayList<>();
// actionsList.add(new FileSystemDetailsAction(volData.getVolume()));
// actionsList.add(new NewWindowViewAction(
// NbBundle.getMessage(this.getClass(), "VolumeNode.getActions.viewInNewWin.text"), this));
// actionsList.addAll(ExplorerNodeActionVisitor.getActions(volData.getVolume()));
// actionsList.add(null);
// actionsList.addAll(Arrays.asList(super.getActions(true)));
//
// return actionsList.toArray(new Action[actionsList.size()]);
// }
//
// @Override
// protected Sheet createSheet() {
// Sheet sheet = super.createSheet();
// Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
// if (sheetSet == null) {
// sheetSet = Sheet.createPropertiesSet();
// sheet.put(sheetSet);
// }
//
// sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.name"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.displayName"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.name.desc"),
// this.getDisplayName()));
// sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.name"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.displayName"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.id.desc"),
// volData.getAddr()));
// sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.name"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.displayName"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.startSector.desc"),
// volData.getStart()));
// sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.name"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.displayName"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.lenSectors.desc"),
// volData.getLength()));
// sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.name"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.displayName"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.description.desc"),
// volData.getDescription()));
// sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.name"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.displayName"),
// NbBundle.getMessage(this.getClass(), "VolumeNode.createSheet.flags.desc"),
// Volume.vsFlagToString(volData.getPartitionFlag().getVsFlag())));
//
// return sheet;
// }
//}

View File

@ -32,7 +32,7 @@ import org.sleuthkit.autopsy.corecomponents.AbstractDataResultViewer;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.datamodel.ThreePanelDAO.SearchResultsDTO;
import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO;
/**
* A tabular result viewer that displays a summary of the selected Data Source.
@ -106,7 +106,7 @@ public class DataSourceSummaryResultViewer extends AbstractDataResultViewer {
}
@Override
public void setNode(Node node, SearchResultsDTO<?> searchResults) {
public void setNode(Node node, SearchResultsDTO searchResults) {
setNode(node);
}