Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
BaseChildFactory.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2019 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.datamodel;
20
21import com.google.common.collect.Lists;
22import com.google.common.eventbus.EventBus;
23import com.google.common.eventbus.Subscribe;
24import java.util.ArrayList;
25import java.util.Collections;
26import java.util.List;
27import java.util.Map;
28import java.util.concurrent.ConcurrentHashMap;
29import java.util.function.Predicate;
30import java.util.logging.Level;
31import org.sleuthkit.autopsy.coreutils.Logger;
32import java.util.prefs.PreferenceChangeEvent;
33import java.util.stream.Collectors;
34import org.openide.nodes.ChildFactory;
35import org.openide.util.NbBundle.Messages;
36import org.sleuthkit.autopsy.core.UserPreferences;
37import org.sleuthkit.datamodel.Content;
38
45public abstract class BaseChildFactory<T extends Content> extends ChildFactory.Detachable<T> {
46
47 private static final Logger logger = Logger.getLogger(BaseChildFactory.class.getName());
48
49 private Predicate<T> filter;
50 private boolean isPageChangeEvent;
51 private boolean isPageSizeChangeEvent;
52
54
59 private static Map<String, EventBus> nodeNameToEventBusMap = new ConcurrentHashMap<>();
60
61 @Messages({
62 "# {0} - node name", "BaseChildFactory.NoSuchEventBusException.message=No event bus for node: {0}"
63 })
64 public static class NoSuchEventBusException extends Exception {
65
66 public NoSuchEventBusException(String nodeName) {
67 super(Bundle.BaseChildFactory_NoSuchEventBusException_message(nodeName));
68 }
69 }
70
78 public static void register(String nodeName, Object subscriber) {
79 EventBus bus = nodeNameToEventBusMap.get(nodeName);
80 if (bus == null) {
81 bus = new EventBus(nodeName);
82 nodeNameToEventBusMap.put(nodeName, bus);
83 }
84 bus.register(subscriber);
85 }
86
96 public static void post(String nodeName, Object event) throws NoSuchEventBusException {
97 EventBus bus = nodeNameToEventBusMap.get(nodeName);
98 if (bus == null) {
99 throw new NoSuchEventBusException(nodeName);
100 }
101 bus.post(event);
102 }
103
104 public BaseChildFactory(String nodeName) {
108 this(nodeName, x -> true);
109 }
110
111 public BaseChildFactory(String nodeName, Predicate<T> filter) {
112 pagingSupport = new PagingSupport(nodeName);
113 pagingSupport.initialize();
114 isPageChangeEvent = false;
115 isPageSizeChangeEvent = false;
116 this.filter = filter;
117 }
118
119 @Override
120 protected void addNotify() {
121 onAdd();
122 }
123
124 @Override
125 protected void finalize() throws Throwable {
126 super.finalize();
127 onRemove();
128 }
129
135 protected abstract List<T> makeKeys();
136
140 protected abstract void onAdd();
141
146 protected abstract void onRemove();
147
148 @Override
149 protected boolean createKeys(List<T> toPopulate) {
156 List<T> allKeys = makeKeys();
157
158 pagingSupport.splitKeysIntoPages(allKeys.stream().filter(filter).collect(Collectors.toList()));
159 }
160
161 toPopulate.addAll(pagingSupport.getCurrentPage());
162
163 // Reset page change and page size change event flags
164 isPageChangeEvent = false;
165 isPageSizeChangeEvent = false;
166
167 return true;
168 }
169
173 public static class RefreshKeysEvent {
174 }
175
180 public static class PageChangeEvent {
181
182 private final int pageNumber;
183
184 public PageChangeEvent(int newPageNumber) {
185 pageNumber = newPageNumber;
186 }
187
188 public int getPageNumber() {
189 return pageNumber;
190 }
191 }
192
196 public static class PageCountChangeEvent {
197
198 private final int pageCount;
199
200 public PageCountChangeEvent(int newPageCount) {
201 pageCount = newPageCount;
202 }
203
204 public int getPageCount() {
205 return pageCount;
206 }
207 }
208
212 public static class PageSizeChangeEvent {
213
214 private final int pageSize;
215
216 public PageSizeChangeEvent(int newPageSize) {
217 pageSize = newPageSize;
218 }
219
220 public int getPageSize() {
221 return pageSize;
222 }
223 }
224
229 private class PagingSupport {
230
231 private final String nodeName;
232 private int pageSize;
233 private int currentPage;
234 private List<List<T>> pages;
235
244 PagingSupport(String nodeName) {
245 currentPage = 1;
247 pages = new ArrayList<>();
248 this.nodeName = nodeName;
249 }
250
251 void initialize() {
256 UserPreferences.addChangeListener((PreferenceChangeEvent evt) -> {
257 if (evt.getKey().equals(UserPreferences.RESULTS_TABLE_PAGE_SIZE)) {
259 }
260 });
261
262 register(nodeName, this);
263 }
264
270 List<T> getCurrentPage() {
271 if (!pages.isEmpty()) {
272 return pages.get(currentPage - 1);
273 }
274
275 return Collections.emptyList();
276 }
277
283 void splitKeysIntoPages(List<T> keys) {
284 int oldPageCount = pages.size();
285
290 if (keys.isEmpty() && !pages.isEmpty()) {
297 pages = new ArrayList<>();
298 } else {
299 pages = Lists.partition(keys, pageSize > 0 ? pageSize : keys.size());
300 }
301
302 if (pages.size() != oldPageCount) {
303 try {
304 // Number of pages has changed so we need to send out a notification.
305 post(nodeName, new PageCountChangeEvent(pages.size()));
306 } catch (NoSuchEventBusException ex) {
307 logger.log(Level.WARNING, "Failed to post page change event.", ex);
308 }
309 }
310 }
311
318 @Subscribe
320 if (event != null) {
321 currentPage = event.getPageNumber();
322 isPageChangeEvent = true;
323 refresh(true);
324 }
325 }
326
333 @Subscribe
335 if (event != null) {
336 int newPageSize = event.getPageSize();
337 if (pageSize == newPageSize) {
338 // No change...nothing to do.
339 return;
340 }
341
342 pageSize = newPageSize;
343 splitKeysIntoPages(pages.stream().flatMap(List::stream).collect(Collectors.toList()));
344
345 currentPage = 1;
347 refresh(true);
348 }
349 }
350
351 @Subscribe
353 if (event != null) {
354 refresh(true);
355 }
356 }
357 }
358}
static void addChangeListener(PreferenceChangeListener listener)
synchronized static Logger getLogger(String name)
Definition Logger.java:124
static void post(String nodeName, Object event)
static Map< String, EventBus > nodeNameToEventBusMap
BaseChildFactory(String nodeName, Predicate< T > filter)
static void register(String nodeName, Object subscriber)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.