Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
AbstractTimeLineView.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2018 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  */
19 package org.sleuthkit.autopsy.timeline.ui;
20 
21 import com.google.common.collect.ImmutableList;
22 import com.google.common.eventbus.Subscribe;
23 import java.util.concurrent.ExecutionException;
24 import java.util.logging.Level;
25 import javafx.application.Platform;
26 import javafx.beans.InvalidationListener;
27 import javafx.beans.Observable;
28 import javafx.beans.property.ReadOnlyBooleanProperty;
29 import javafx.beans.property.ReadOnlyBooleanWrapper;
30 import javafx.concurrent.Task;
31 import javafx.scene.Cursor;
32 import javafx.scene.Node;
33 import javafx.scene.layout.BorderPane;
34 import javafx.scene.layout.StackPane;
35 import org.controlsfx.control.MaskerPane;
36 import org.openide.util.NbBundle;
44 
49 public abstract class AbstractTimeLineView extends BorderPane {
50 
51  private static final Logger logger = Logger.getLogger(AbstractTimeLineView.class.getName());
52 
57  private final ReadOnlyBooleanWrapper hasVisibleEvents = new ReadOnlyBooleanWrapper(true);
58 
64  private final ReadOnlyBooleanWrapper needsRefresh = new ReadOnlyBooleanWrapper(false);
65 
70  private InvalidationListener updateListener = (Observable any) -> refresh();
71 
75  private Task<Boolean> updateTask;
76 
78  private final EventsModel filteredEvents;
79 
86  this.controller = controller;
87  this.filteredEvents = controller.getEventsModel();
88  this.filteredEvents.registerForEvents(this);
89  this.filteredEvents.modelParamsProperty().addListener(updateListener);
90  TimeLineController.timeZoneProperty().addListener(updateListener);
91  }
92 
99  @Subscribe
101  refresh();
102  }
103 
104 
111  public boolean needsRefresh() {
112  return needsRefresh.get();
113  }
114 
122  public ReadOnlyBooleanProperty needsRefreshProperty() {
123  return needsRefresh.getReadOnlyProperty();
124  }
125 
132  return controller;
133  }
134 
142  protected final synchronized void refresh() {
143  if (updateTask != null) {
144  updateTask.cancel(true);
145  updateTask = null;
146  }
147  updateTask = getNewUpdateTask();
148  updateTask.stateProperty().addListener((Observable observable) -> {
149  switch (updateTask.getState()) {
150  case CANCELLED:
151  case FAILED:
152  case READY:
153  case RUNNING:
154  case SCHEDULED:
155  break;
156  case SUCCEEDED:
157  try {
158  this.hasVisibleEvents.set(updateTask.get());
159  } catch (InterruptedException | ExecutionException ex) {
160  logger.log(Level.SEVERE, "Unexpected exception updating view", ex); //NON-NLS
161  }
162  break;
163  }
164  });
165  getController().monitorTask(updateTask);
166  }
167 
174  return filteredEvents;
175  }
176 
184  protected abstract Task<Boolean> getNewUpdateTask();
185 
191  protected abstract ViewMode getViewMode();
192 
199  abstract protected ImmutableList<Node> getSettingsControls();
200 
207  abstract protected boolean hasCustomTimeNavigationControls();
208 
215  abstract protected ImmutableList<Node> getTimeNavigationControls();
216 
220  final synchronized void dispose() {
221  //cancel and gc updateTask
222  if (updateTask != null) {
223  updateTask.cancel(true);
224  updateTask = null;
225  }
226  //remvoe and gc updateListener
227  this.filteredEvents.modelParamsProperty().removeListener(updateListener);
228  TimeLineController.timeZoneProperty().removeListener(updateListener);
229  updateListener = null;
230  filteredEvents.unRegisterForEvents(this);
231  controller.unRegisterForEvents(this);
232  }
233 
241  boolean hasVisibleEvents() {
242  return hasVisibleEventsProperty().get();
243  }
244 
252  ReadOnlyBooleanProperty hasVisibleEventsProperty() {
253  return hasVisibleEvents.getReadOnlyProperty();
254  }
255 
260  void setNeedsRefresh() {
261  needsRefresh.set(true);
262  }
263 
267  @ThreadConfined(type = ThreadConfined.ThreadType.JFX)
268  abstract protected void clearData();
269 
276  protected abstract class ViewRefreshTask<AxisValuesType> extends LoggedTask<Boolean> {
277 
278  private final Node center;
279 
287  protected ViewRefreshTask(String taskName, boolean logStateChanges) {
288  super(taskName, logStateChanges);
289  this.center = getCenter();
290  }
291 
302  @NbBundle.Messages(value = {"ViewRefreshTask.preparing=Analyzing zoom and filter settings"})
303  @Override
304  protected Boolean call() throws Exception {
305  updateProgress(-1, 1);
306  updateMessage(Bundle.ViewRefreshTask_preparing());
307  Platform.runLater(() -> {
308  MaskerPane maskerPane = new MaskerPane();
309  maskerPane.textProperty().bind(messageProperty());
310  maskerPane.progressProperty().bind(progressProperty());
311  setCenter(new StackPane(center, maskerPane));
312  setCursor(Cursor.WAIT);
313  });
314  return true;
315  }
316 
322  @Override
323  protected void succeeded() {
324  super.succeeded();
325  needsRefresh.set(false);
326  cleanup();
327  }
328 
333  @Override
334  protected void cancelled() {
335  super.cancelled();
336  cleanup();
337  }
338 
343  @Override
344  protected void failed() {
345  super.failed();
346  cleanup();
347  }
348 
353  private void cleanup() {
354  setCenter(center); //clear masker pane installed in call()
355  setCursor(Cursor.DEFAULT);
356  }
357 
364  protected abstract void setDateValues(AxisValuesType values);
365 
373  protected void resetView(AxisValuesType axisValues) {
374  Platform.runLater(() -> {
375  clearData();
376  setDateValues(axisValues);
377  });
378  }
379  }
380 }
synchronized void unRegisterForEvents(Object subscriber)
abstract ImmutableList< Node > getTimeNavigationControls()
abstract ImmutableList< Node > getSettingsControls()
synchronized void unRegisterForEvents(Object listener)
static ReadOnlyObjectProperty< TimeZone > timeZoneProperty()
final ReadOnlyObjectWrapper< EventsModelParams > modelParamsProperty
synchronized void monitorTask(final Task<?> task)
synchronized void registerForEvents(Object subscriber)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.