connect historymanager to filtered events through property: back is broken

This commit is contained in:
jmillman 2014-08-26 17:36:49 -04:00
parent 054bb6cf34
commit 3b1586fd2d
8 changed files with 122 additions and 136 deletions

View File

@ -36,11 +36,11 @@ public class HistoryManager<T> {
private final ReadOnlyObjectWrapper<T> currentState = new ReadOnlyObjectWrapper<>();
public ReadOnlyObjectWrapper<T> getCurrentState() {
public ReadOnlyObjectWrapper<T> currentState() {
return currentState;
}
public T currentState() {
public T getCurrentState() {
return currentState.get();
}
@ -78,7 +78,7 @@ public class HistoryManager<T> {
return peek;
}
synchronized private void advance(T newState) {
synchronized public void advance(T newState) {
if (currentState.equals(newState) == false) {
historyStack.push(currentState.get());

View File

@ -46,12 +46,12 @@ import org.openide.windows.WindowManager;
*/
public class ProgressWindow extends JFrame {
private final SwingWorker<?,?> worker;
private final SwingWorker<?, ?> worker;
/**
* Creates new form TimelineProgressDialog
*/
public ProgressWindow(Component parent, boolean modal, SwingWorker<?,?> worker) {
public ProgressWindow(Component parent, boolean modal, SwingWorker<?, ?> worker) {
super();
initComponents();
@ -60,18 +60,13 @@ public class ProgressWindow extends JFrame {
setAlwaysOnTop(modal);
//set icon the same as main app
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
setIconImage(WindowManager.getDefault().getMainWindow().getIconImage());
}
});
//progressBar.setIndeterminate(true);
setName("Advanced Timeline");
setTitle("Generating Advanced Timeline data");
setName("Timeline");
setTitle("Generating Timeline data");
// Close the dialog when Esc is pressed
String cancelName = "cancel";
InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
@ -89,66 +84,42 @@ public class ProgressWindow extends JFrame {
}
public void updateProgress(final int progress) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
progressBar.setValue(progress);
}
});
}
public void updateProgress(final int progress, final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
progressBar.setValue(progress);
progressBar.setString(message);
}
});
}
public void updateProgress(final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
progressBar.setString(message);
}
});
}
public void setProgressTotal(final int total) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
progressBar.setIndeterminate(false);
progressBar.setMaximum(total);
progressBar.setStringPainted(true);
}
});
}
public void updateHeaderMessage(final String headerMessage) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
progressHeader.setText(headerMessage);
}
});
}
public void setIndeterminate() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
progressBar.setIndeterminate(true);
progressBar.setStringPainted(true);
}
});
}
@ -206,9 +177,7 @@ public class ProgressWindow extends JFrame {
}//GEN-LAST:event_closeDialog
public void cancel() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
if (isVisible()) {
int showConfirmDialog = JOptionPane.showConfirmDialog(ProgressWindow.this, "Do you want to cancel time line creation?", "Cancel timeline creation?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (showConfirmDialog == JOptionPane.YES_OPTION) {
@ -217,7 +186,6 @@ public class ProgressWindow extends JFrame {
} else {
close();
}
}
});
}

View File

@ -172,17 +172,16 @@ public class TimeLineController {
/** list based stack to hold history, 'top' is at index 0; */
@GuardedBy("this")
private final ObservableStack<ZoomParams> historyStack = new ObservableStack<>();
private final HistoryManager<ZoomParams> historyManager = new HistoryManager<>();
@GuardedBy("this")
private final ObservableStack<ZoomParams> forwardStack = new ObservableStack<>();
synchronized public ObservableStack<ZoomParams> getHistoryStack() {
return historyStack;
return historyManager.getHistoryStack();
}
synchronized public ObservableStack<ZoomParams> getForwardStack() {
return forwardStack;
return historyManager.getForwardStack();
}
//all members should be access with the intrinsict lock of this object held
@ -221,17 +220,17 @@ public class TimeLineController {
public TimeLineController() {
//initalize repository and filteredEvents on creation
eventsRepository = new EventsRepository();
eventsRepository = new EventsRepository(historyManager.currentState());
filteredEvents = eventsRepository.getEventsModel();
InitialZoomState = new ZoomParams(filteredEvents.getSpanningInterval(),
EventTypeZoomLevel.BASE_TYPE,
Filter.getDefaultFilter(),
DescriptionLOD.SHORT);
filteredEvents.requestZoomState(InitialZoomState, true);
historyManager.currentState().set(InitialZoomState);
//persistent listener instances
caseListener = new AutopsyCaseListener();
}
/** @return a shared events model */
@ -354,7 +353,7 @@ public class TimeLineController {
LOGGER.log(Level.SEVERE, "Unexpected error when generating timeline, ", ex);
}
}
@SuppressWarnings("deprecation")
private long getCaseLastArtifactID(final SleuthkitCase sleuthkitCase) {
long caseLastArtfId = -1;
try (ResultSet runQuery = sleuthkitCase.runQuery("select Max(artifact_id) as max_id from blackboard_artifacts")) {
@ -502,50 +501,51 @@ public class TimeLineController {
}
synchronized public ZoomParams goForward() {
final ZoomParams currentZoom = filteredEvents.getRequestedZoomParamters().get();
final ZoomParams fpeek = forwardStack.peek();
if (fpeek != null && currentZoom.equals(fpeek) == false) {
historyStack.push(currentZoom);
filteredEvents.requestZoomState(fpeek, false);
forwardStack.pop();
}
return fpeek;
return historyManager.advance();
//
// final ZoomParams currentZoom = filteredEvents.getRequestedZoomParamters().get();
//
// final ZoomParams fpeek = forwardStack.peek();
//
// if (fpeek != null && currentZoom.equals(fpeek) == false) {
// historyStack.push(currentZoom);
// filteredEvents.requestZoomState(fpeek, false);
// forwardStack.pop();
// }
// return fpeek;
}
synchronized public ZoomParams goBack() {
final ZoomParams currentZoom = filteredEvents.getRequestedZoomParamters().get();
final ZoomParams peek = historyStack.peek();
if (peek != null && peek.equals(currentZoom) == false) {
forwardStack.push(currentZoom);
filteredEvents.requestZoomState(historyStack.pop(), false);
} else if (peek != null && peek.equals(currentZoom)) {
historyStack.pop();
return goBack();
}
return peek;
return historyManager.retreat();
// final ZoomParams currentZoom = filteredEvents.getRequestedZoomParamters().get();
// final ZoomParams peek = historyStack.peek();
//
// if (peek != null && peek.equals(currentZoom) == false) {
// forwardStack.push(currentZoom);
// filteredEvents.requestZoomState(historyStack.pop(), false);
// } else if (peek != null && peek.equals(currentZoom)) {
// historyStack.pop();
// return goBack();
// }
// return peek;
}
synchronized private void pushZoom(ZoomParams newState) {
synchronized private void pushZoom(ZoomParams zCrumb) {
final ZoomParams currentZoom = filteredEvents.getRequestedZoomParamters().get();
if ( currentZoom.equals(zCrumb) == false) {
historyStack.push(currentZoom);
filteredEvents.requestZoomState(zCrumb, false);
if (zCrumb.equals(forwardStack.peek())) {
forwardStack.pop();
} else {
forwardStack.clear();
historyManager.advance(newState);
// final ZoomParams currentZoom = filteredEvents.getRequestedZoomParamters().get();
//
// if (currentZoom.equals(zCrumb) == false) {
// historyStack.push(currentZoom);
// filteredEvents.requestZoomState(zCrumb, false);
// if (zCrumb.equals(forwardStack.peek())) {
// forwardStack.pop();
// } else {
// forwardStack.clear();
// }
// }
}
}
}
public void selectTimeAndType(Interval interval, EventType type) {
final Interval timeRange = filteredEvents.getSpanningInterval().overlap(interval);

View File

@ -56,7 +56,7 @@ import org.sleuthkit.autopsy.timeline.ui.filtering.FilterSetPanel;
import org.sleuthkit.autopsy.timeline.zooming.ZoomSettingsPane;
/**
* TopComponent for the advanced timeline module.
* TopComponent for the timeline feature.
*/
@ConvertAsProperties(
dtd = "-//org.sleuthkit.autopsy.timeline//TimeLine//EN",

View File

@ -19,10 +19,11 @@
package org.sleuthkit.autopsy.timeline.events;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javafx.beans.Observable;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javax.annotation.concurrent.GuardedBy;
@ -88,13 +89,29 @@ public class FilteredEventsModel {
@GuardedBy("this")
private final EventsRepository repo;
public FilteredEventsModel(EventsRepository repo) {
public FilteredEventsModel(EventsRepository repo, ObjectProperty<ZoomParams> currentStateProperty) {
this.repo = repo;
requestedZoomParamters.set(new ZoomParams(new Interval(repo.getMinTime(), repo.getMaxTime(), DateTimeZone.UTC),
EventTypeZoomLevel.BASE_TYPE,
Filter.getDefaultFilter(),
DescriptionLOD.SHORT,
EnumSet.noneOf(ZoomParams.Field.class)));
requestedZoomParamters.bind(currentStateProperty);
// currentStateProperty.set(new ZoomParams(new Interval(repo.getMinTime(), repo.getMaxTime(), DateTimeZone.UTC), EventTypeZoomLevel.BASE_TYPE,
// Filter.getDefaultFilter(),
// DescriptionLOD.SHORT,
// EnumSet.noneOf(ZoomParams.Field.class)));
requestedZoomParamters.addListener((Observable observable) -> {
final ZoomParams zoomParams = requestedZoomParamters.get();
if (zoomParams.getTypeZoomLevel().equals(requestedTypeZoom.get()) == false
|| zoomParams.getDescrLOD().equals(requestedLOD.get()) == false
|| zoomParams.getFilter().equals(requestedFilter.get()) == false
|| zoomParams.getTimeRange().equals(requestedTimeRange.get()) == false) {
// requestedZoomParamters.set(zoomParams);
requestedTypeZoom.set(zoomParams.getTypeZoomLevel());
requestedFilter.set(zoomParams.getFilter().copyOf());
requestedTimeRange.set(zoomParams.getTimeRange());
requestedLOD.set(zoomParams.getDescrLOD());
}
});
this.requestedTimeRange.set(getSpanningInterval());
}
@ -233,18 +250,18 @@ public class FilteredEventsModel {
return requestedTypeZoom.get();
}
synchronized public void requestZoomState(ZoomParams zCrumb, boolean force) {
if (force
|| zCrumb.getTypeZoomLevel().equals(requestedTypeZoom.get()) == false
|| zCrumb.getDescrLOD().equals(requestedLOD.get()) == false
|| zCrumb.getFilter().equals(requestedFilter.get()) == false
|| zCrumb.getTimeRange().equals(requestedTimeRange.get()) == false) {
requestedZoomParamters.set(zCrumb);
requestedTypeZoom.set(zCrumb.getTypeZoomLevel());
requestedFilter.set(zCrumb.getFilter().copyOf());
requestedTimeRange.set(zCrumb.getTimeRange());
requestedLOD.set(zCrumb.getDescrLOD());
}
}
// synchronized public void requestZoomState(ZoomParams zCrumb, boolean force) {
// if (force
// || zCrumb.getTypeZoomLevel().equals(requestedTypeZoom.get()) == false
// || zCrumb.getDescrLOD().equals(requestedLOD.get()) == false
// || zCrumb.getFilter().equals(requestedFilter.get()) == false
// || zCrumb.getTimeRange().equals(requestedTimeRange.get()) == false) {
//
// requestedZoomParamters.set(zCrumb);
// requestedTypeZoom.set(zCrumb.getTypeZoomLevel());
// requestedFilter.set(zCrumb.getFilter().copyOf());
// requestedTimeRange.set(zCrumb.getTimeRange());
// requestedLOD.set(zCrumb.getDescrLOD());
// }
// }
}

View File

@ -50,6 +50,7 @@ import org.joda.time.DateTimeZone;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.timeline.TimeLineController;
import org.sleuthkit.autopsy.timeline.events.AggregateEvent;
import org.sleuthkit.autopsy.timeline.events.TimeLineEvent;
@ -67,12 +68,11 @@ import org.sleuthkit.autopsy.timeline.zooming.DescriptionLOD;
import org.sleuthkit.autopsy.timeline.zooming.EventTypeZoomLevel;
import org.sleuthkit.autopsy.timeline.zooming.TimeUnits;
import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.TskData;
import org.sqlite.SQLiteJDBCLoader;
/**
* This class provides access to the Advanced Timeline SQLite database. This
* This class provides access to the Timeline SQLite database. This
* class borrows a lot of ideas and techniques from {@link SleuthkitCase},
* Creating an abstract base class for sqlite databases, or using a higherlevel
* persistence api may make sense in the future.

View File

@ -32,11 +32,14 @@ import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import javafx.beans.property.ObjectProperty;
import javax.annotation.concurrent.GuardedBy;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.Interval;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.timeline.ProgressWindow;
import org.sleuthkit.autopsy.timeline.events.AggregateEvent;
import org.sleuthkit.autopsy.timeline.events.FilteredEventsModel;
@ -47,8 +50,6 @@ import org.sleuthkit.autopsy.timeline.events.type.FileSystemTypes;
import org.sleuthkit.autopsy.timeline.events.type.RootEventType;
import org.sleuthkit.autopsy.timeline.filters.Filter;
import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.SleuthkitCase;
@ -103,7 +104,7 @@ public class EventsRepository {
return modelInstance;
}
public EventsRepository() {
public EventsRepository(ObjectProperty<ZoomParams> currentStateProperty) {
//TODO: we should check that case is open, or get passed a case object/directory -jm
this.eventDB = EventDB.getEventDB(Case.getCurrentCase().getCaseDirectory());
@ -118,7 +119,7 @@ public class EventsRepository {
}).build(CacheLoader.from(eventDB::getAggregatedEvents));
maxCache = CacheBuilder.newBuilder().build(CacheLoader.from(eventDB::getMaxTime));
minCache = CacheBuilder.newBuilder().build(CacheLoader.from(eventDB::getMinTime));
this.modelInstance = new FilteredEventsModel(this);
this.modelInstance = new FilteredEventsModel(this, currentStateProperty);
}