mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-16 01:37:43 +00:00
Merge pull request #4708 from esaunders/4910_paging_child_factory
4910 paging child factory
This commit is contained in:
commit
d1c3dea4f0
@ -76,6 +76,7 @@ public final class UserPreferences {
|
||||
public static final String DISPLAY_TRANSLATED_NAMES = "DisplayTranslatedNames";
|
||||
public static final String EXTERNAL_HEX_EDITOR_PATH = "ExternalHexEditorPath";
|
||||
public static final String SOLR_MAX_JVM_SIZE = "SolrMaxJVMSize";
|
||||
public static final String RESULTS_TABLE_PAGE_SIZE = "ResultsTablePageSize";
|
||||
|
||||
// Prevent instantiation.
|
||||
private UserPreferences() {
|
||||
@ -491,6 +492,24 @@ public final class UserPreferences {
|
||||
preferences.putInt(SOLR_MAX_JVM_SIZE, maxSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum number of results to display in a result table.
|
||||
*
|
||||
* @return Saved value or default (0) which indicates no max.
|
||||
*/
|
||||
public static int getResultsTablePageSize() {
|
||||
return preferences.getInt(RESULTS_TABLE_PAGE_SIZE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of results to display in a result table.
|
||||
*
|
||||
* @param pageSize
|
||||
*/
|
||||
public static void setResultsTablePageSize(int pageSize) {
|
||||
preferences.putInt(RESULTS_TABLE_PAGE_SIZE, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HdX path.
|
||||
*
|
||||
|
234
Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java
Normal file
234
Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 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 com.google.common.collect.Lists;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
/**
|
||||
* Abstract child factory that provides paging and filtering functionality to
|
||||
* subclasses.
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class BaseChildFactory<T extends Content> extends ChildFactory.Detachable<T> {
|
||||
|
||||
private final Predicate<T> filter;
|
||||
private boolean isPageChangeEvent;
|
||||
|
||||
private final PagingSupport pagingSupport;
|
||||
|
||||
/**
|
||||
* This static map is used to facilitate communication between the UI and
|
||||
* the child factory.
|
||||
*/
|
||||
public static Map<String, EventBus> nodeNameToEventBusMap = new ConcurrentHashMap<>();
|
||||
|
||||
public BaseChildFactory(String nodeName) {
|
||||
pagingSupport = new PagingSupport(nodeName);
|
||||
pagingSupport.initialize();
|
||||
isPageChangeEvent = false;
|
||||
filter = new KnownAndSlackFilter<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addNotify() {
|
||||
onAdd();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeNotify() {
|
||||
onRemove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses implement this to construct a collection of keys.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract List<T> makeKeys();
|
||||
|
||||
/**
|
||||
* Subclasses implement this to initialize any required resources.
|
||||
*/
|
||||
protected abstract void onAdd();
|
||||
|
||||
/**
|
||||
* Subclasses implement this to clean up any resources they acquired in
|
||||
* onAdd()
|
||||
*/
|
||||
protected abstract void onRemove();
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<T> toPopulate) {
|
||||
// For page chage events we simply return the previously calculated
|
||||
// keys, otherwise we make a new set of keys.
|
||||
if (!isPageChangeEvent) {
|
||||
List<T> allKeys = makeKeys();
|
||||
|
||||
// Filter keys
|
||||
allKeys.stream().filter(filter).collect(Collectors.toList());
|
||||
|
||||
pagingSupport.splitKeysIntoPages(allKeys);
|
||||
}
|
||||
|
||||
toPopulate.addAll(pagingSupport.getCurrentPage());
|
||||
|
||||
// Reset page change event flag
|
||||
isPageChangeEvent = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event used to let subscribers know that the user has
|
||||
* navigated to a different page.
|
||||
*/
|
||||
public static class PageChangeEvent {
|
||||
|
||||
private final int pageNumber;
|
||||
|
||||
public PageChangeEvent(int newPageNumber) {
|
||||
pageNumber = newPageNumber;
|
||||
}
|
||||
|
||||
public int getPageNumber() {
|
||||
return pageNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event used to let subscribers know that the number of
|
||||
* pages has changed.
|
||||
*/
|
||||
public static class PageCountChangeEvent {
|
||||
|
||||
private final int pageCount;
|
||||
|
||||
public PageCountChangeEvent(int newPageCount) {
|
||||
pageCount = newPageCount;
|
||||
}
|
||||
|
||||
public int getPageCount() {
|
||||
return pageCount;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event used to let subscribers know that paging is no
|
||||
* longer required.
|
||||
*/
|
||||
public static class PagingDestroyedEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that supplies paging related functionality to the base child
|
||||
* factory class.
|
||||
*/
|
||||
class PagingSupport {
|
||||
|
||||
private final String nodeName;
|
||||
private final int pageSize;
|
||||
private int currentPage;
|
||||
private List<List<T>> pages;
|
||||
private EventBus bus;
|
||||
|
||||
/**
|
||||
* Construct PagingSupport instance for the given node name.
|
||||
*
|
||||
* @param nodeName Name of the node in the tree for which results are
|
||||
* being displayed. The node name is used to allow
|
||||
* communication between the UI and the ChildFactory via
|
||||
* an EventBus.
|
||||
*/
|
||||
PagingSupport(String nodeName) {
|
||||
pageSize = UserPreferences.getResultsTablePageSize();
|
||||
this.currentPage = 1;
|
||||
pages = new ArrayList<>();
|
||||
this.nodeName = nodeName;
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
if (pageSize > 0) {
|
||||
// Only configure an EventBus if paging functionality is enabled.
|
||||
if (nodeNameToEventBusMap.containsKey(nodeName)) {
|
||||
bus = nodeNameToEventBusMap.get(nodeName);
|
||||
} else {
|
||||
bus = new EventBus(nodeName);
|
||||
nodeNameToEventBusMap.put(bus.identifier(), bus);
|
||||
}
|
||||
bus.register(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of keys at the current page.
|
||||
*
|
||||
* @return List of keys.
|
||||
*/
|
||||
List<T> getCurrentPage() {
|
||||
if (!pages.isEmpty()) {
|
||||
return pages.get(currentPage - 1);
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the given collection of keys into pages based on page size.
|
||||
*
|
||||
* @param keys
|
||||
*/
|
||||
void splitKeysIntoPages(List<T> keys) {
|
||||
int oldPageCount = pages.size();
|
||||
|
||||
/**
|
||||
* If pageSize is set split keys into pages, otherwise create a
|
||||
* single page containing all keys.
|
||||
*/
|
||||
pages = Lists.partition(keys, pageSize > 0 ? pageSize : keys.size());
|
||||
if (pages.size() != oldPageCount) {
|
||||
// Number of pages has changed so we need to send out a notification.
|
||||
bus.post(new PageCountChangeEvent(pages.size()));
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void subscribeToPageChange(PageChangeEvent event) {
|
||||
// Receives page change events from UI components and
|
||||
// triggers a refresh in the child factory.
|
||||
if (event != null) {
|
||||
currentPage = event.getPageNumber();
|
||||
isPageChangeEvent = true;
|
||||
refresh(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 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.function.Predicate;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
|
||||
/**
|
||||
* Predicate that can be used to filter known and/or slack files from
|
||||
* Content collections based on user preferences.
|
||||
*/
|
||||
class KnownAndSlackFilter<T extends Content> implements Predicate<T> {
|
||||
|
||||
@Override
|
||||
public boolean test(T t) {
|
||||
AbstractFile af = null;
|
||||
|
||||
if (t instanceof BlackboardArtifact) {
|
||||
try {
|
||||
af = ((BlackboardArtifact) (t)).getSleuthkitCase().getAbstractFileById(((BlackboardArtifact) t).getObjectID());
|
||||
} catch (TskCoreException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
}
|
||||
} else if (t instanceof AbstractFile) {
|
||||
af = (AbstractFile) t;
|
||||
}
|
||||
|
||||
if (af != null) {
|
||||
if (af.getKnown() == TskData.FileKnown.KNOWN && UserPreferences.hideKnownFilesInViewsTree()) {
|
||||
return false;
|
||||
}
|
||||
if (af.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) && UserPreferences.hideSlackFilesInViewsTree()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user