Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
History.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2014 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.coreutils;
20 
21 import java.util.Objects;
22 import javafx.beans.property.ReadOnlyBooleanProperty;
23 import javafx.beans.property.ReadOnlyBooleanWrapper;
24 import javafx.beans.property.ReadOnlyObjectProperty;
25 import javafx.beans.property.ReadOnlyObjectWrapper;
26 import javafx.beans.property.SimpleListProperty;
27 import javafx.collections.FXCollections;
28 import javax.annotation.concurrent.GuardedBy;
29 import javax.annotation.concurrent.ThreadSafe;
30 
41 @ThreadSafe
42 public class History<T> {
43 
44  // Stack of things that were previously shown before an 'advance' was done
45  @GuardedBy("this")
46  private final ObservableStack<T> historyStack = new ObservableStack<>();
47 
48  // stack of things that were previously shown before a 'retreat' (i.e. a back) was done
49  @GuardedBy("this")
50  private final ObservableStack<T> forwardStack = new ObservableStack<>();
51 
52  // what is currently being shown
53  @GuardedBy("this")
54  private final ReadOnlyObjectWrapper<T> currentState = new ReadOnlyObjectWrapper<>();
55 
56  // Is the forward stack empty?
57  @GuardedBy("this")
58  private final ReadOnlyBooleanWrapper canAdvance = new ReadOnlyBooleanWrapper();
59 
60  // is the historyStack empty?
61  @GuardedBy("this")
62  private final ReadOnlyBooleanWrapper canRetreat = new ReadOnlyBooleanWrapper();
63 
64  synchronized public T getCurrentState() {
65  return currentState.get();
66  }
67 
68  synchronized public boolean canAdvance() {
69  return canAdvance.get();
70  }
71 
72  synchronized public boolean canRetreat() {
73  return canRetreat.get();
74  }
75 
76  synchronized public ReadOnlyObjectProperty<T> currentState() {
77  return currentState.getReadOnlyProperty();
78  }
79 
80  synchronized public ReadOnlyBooleanProperty getCanAdvance() {
81  return canAdvance.getReadOnlyProperty();
82  }
83 
84  synchronized public ReadOnlyBooleanProperty getCanRetreat() {
85  return canRetreat.getReadOnlyProperty();
86  }
87 
88  public History(T initialState) {
89  this();
90  currentState.set(initialState);
91  }
92 
93  public History() {
94  canAdvance.bind(forwardStack.emptyProperty().not());
95  canRetreat.bind(historyStack.emptyProperty().not());
96  }
97 
98  synchronized public void reset(T newState) {
99  forwardStack.clear();
100  historyStack.clear();
101  currentState.set(newState);
102  }
103 
110  synchronized public T advance() {
111  final T peek = forwardStack.peek();
112 
113  if (peek != null && peek.equals(currentState.get()) == false) {
114  historyStack.push(currentState.get());
115  currentState.set(peek);
116  forwardStack.pop();
117  }
118  return peek;
119  }
120 
127  synchronized public T retreat() {
128  final T pop = historyStack.pop();
129 
130  if (pop != null && pop.equals(currentState.get()) == false) {
131  forwardStack.push(currentState.get());
132  currentState.set(pop);
133  return pop;
134  } else if (pop != null && pop.equals(currentState.get())) {
135  return retreat();
136  }
137  return pop;
138  }
139 
149  synchronized public void advance(T newState) throws IllegalArgumentException {
150  if (newState != null && Objects.equals(currentState.get(), newState) == false) {
151  if (currentState.get() != null) {
152  historyStack.push(currentState.get());
153  }
154  currentState.set(newState);
155  if (newState.equals(forwardStack.peek())) {
156  forwardStack.pop();
157  } else {
158  forwardStack.clear();
159  }
160  }
161  }
162 
163  synchronized public void clear() {
164  historyStack.clear();
165  forwardStack.clear();
166  currentState.set(null);
167  }
168 
176  private static class ObservableStack<T> extends SimpleListProperty<T> {
177 
178  public ObservableStack() {
179  super(FXCollections.<T>synchronizedObservableList(FXCollections.<T>observableArrayList()));
180  }
181 
182  public void push(T item) {
183  synchronized (this) {
184  add(0, item);
185  }
186  }
187 
188  public T pop() {
189  synchronized (this) {
190  if (isEmpty()) {
191  return null;
192  } else {
193  return remove(0);
194  }
195  }
196  }
197 
198  public T peek() {
199  synchronized (this) {
200  if (isEmpty()) {
201  return null;
202  } else {
203  return get(0);
204  }
205  }
206  }
207  }
208 }
final ObservableStack< T > forwardStack
Definition: History.java:50
final ObservableStack< T > historyStack
Definition: History.java:46
synchronized boolean canRetreat()
Definition: History.java:72
synchronized void reset(T newState)
Definition: History.java:98
synchronized boolean canAdvance()
Definition: History.java:68
synchronized ReadOnlyObjectProperty< T > currentState()
Definition: History.java:76
synchronized ReadOnlyBooleanProperty getCanRetreat()
Definition: History.java:84
synchronized void advance(T newState)
Definition: History.java:149
synchronized ReadOnlyBooleanProperty getCanAdvance()
Definition: History.java:80

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.