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

Copyright © 2012-2018 Basis Technology. Generated on: Tue Dec 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.