mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
Add local/remote event support for Case events
This commit is contained in:
parent
c1a505b9f1
commit
23344ce98b
@ -45,6 +45,7 @@ import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CallableSystemAction;
|
||||
import org.openide.util.actions.SystemAction;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.services.Services;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl;
|
||||
@ -53,6 +54,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Version;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||
import org.sleuthkit.datamodel.*;
|
||||
@ -75,11 +77,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
*/
|
||||
public static final String propStartup = "LBL_StartupDialog"; //NON-NLS
|
||||
|
||||
// RJCTODO: Replace PropertyChangeSupport with AutopsyEventPublisher.
|
||||
private static final PropertyChangeSupport pcs = new PropertyChangeSupport(Case.class);
|
||||
private static final Set<String> eventNames = Stream.of(Events.values())
|
||||
.map(Events::toString)
|
||||
.collect(Collectors.toSet());
|
||||
private static final AutopsyEventPublisher eventPublisher = new AutopsyEventPublisher();
|
||||
|
||||
/**
|
||||
@ -90,12 +87,9 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
|
||||
/**
|
||||
* Property name that indicates the name of the current case has
|
||||
* changed. When a case is opened, "old name" is empty string and "new
|
||||
* name" is the name. When a case is closed, "old name" is the case name
|
||||
* and "new name" is empty string. When a case is renamed, "old name"
|
||||
* has the original name and "new name" has the new name.
|
||||
* changed. The old value is the old case name, the new value is the new
|
||||
* case name.
|
||||
*/
|
||||
// @@@ BC: I propose that this is no longer called for case open/close.
|
||||
NAME,
|
||||
/**
|
||||
* Property name that indicates the number of the current case has
|
||||
@ -205,16 +199,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
this.caseType = type;
|
||||
this.db = db;
|
||||
this.services = new Services(db);
|
||||
if (CaseType.MULTI_USER_CASE == this.caseType) {
|
||||
try {
|
||||
eventPublisher.openRemoteEventChannel(name);
|
||||
} catch (AutopsyEventException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to start remote event publisher", ex);
|
||||
MessageNotifyUtil.Message.error(NbBundle.getMessage(Case.class,
|
||||
"Case.OpenEventChannel.ErrMsg",
|
||||
name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -261,58 +245,30 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
Case oldCase = Case.currentCase;
|
||||
Case.currentCase = null;
|
||||
if (oldCase != null) {
|
||||
doCaseChange(null); //closes windows, etc
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(Events.CURRENT_CASE.toString(), oldCase, null);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(Case.class, "Case.moduleErr"),
|
||||
NbBundle.getMessage(Case.class,
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
doCaseNameChange("");
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(Events.NAME.toString(), oldCase.name, "");
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(Case.class, "Case.moduleErr"),
|
||||
NbBundle.getMessage(Case.class,
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
doCaseChange(null); //closes windows, etc
|
||||
eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), oldCase, null));
|
||||
if (CaseType.MULTI_USER_CASE == oldCase.getCaseType()) {
|
||||
eventPublisher.closeRemoteEventChannel();
|
||||
}
|
||||
}
|
||||
|
||||
if (newCase != null) {
|
||||
currentCase = newCase;
|
||||
|
||||
Logger.setLogDirectory(currentCase.getLogDirectoryPath());
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(Events.CURRENT_CASE.toString(), null, currentCase);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(Case.class, "Case.moduleErr"),
|
||||
NbBundle.getMessage(Case.class,
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
doCaseChange(currentCase);
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(Events.NAME.toString(), "", currentCase.name);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(Case.class, "Case.moduleErr"),
|
||||
NbBundle.getMessage(Case.class,
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
doCaseNameChange(currentCase.name);
|
||||
|
||||
updateMainWindowTitle(currentCase.name);
|
||||
RecentCases.getInstance().addRecentCase(currentCase.name, currentCase.configFilePath); // update the recent cases
|
||||
if (CaseType.MULTI_USER_CASE == newCase.getCaseType()) {
|
||||
try {
|
||||
eventPublisher.openRemoteEventChannel(newCase.getName());
|
||||
} catch (AutopsyEventException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to start remote event publisher", ex);
|
||||
MessageNotifyUtil.Message.error(NbBundle.getMessage(Case.class,
|
||||
"Case.OpenEventChannel.ErrMsg",
|
||||
newCase.getName()));
|
||||
}
|
||||
}
|
||||
eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase));
|
||||
} else {
|
||||
Logger.setLogDirectory(PlatformUtil.getLogDirectory());
|
||||
}
|
||||
@ -525,25 +481,14 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* @param imgPaths the paths of the image that being added
|
||||
* @param imgId the ID of the image that being added
|
||||
* @param timeZone the timeZone of the image where it's added
|
||||
* @deprecated Use notifyNewDataSource() instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public Image addImage(String imgPath, long imgId, String timeZone) throws CaseActionException {
|
||||
logger.log(Level.INFO, "Adding image to Case. imgPath: {0} ID: {1} TimeZone: {2}", new Object[]{imgPath, imgId, timeZone}); //NON-NLS
|
||||
|
||||
try {
|
||||
Image newImage = db.getImageById(imgId);
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(Events.DATA_SOURCE_ADDED.toString(), null, newImage); // the new value is the instance of the image
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
CoreComponentControl.openCoreWindows();
|
||||
return newImage;
|
||||
Image newDataSource = db.getImageById(imgId);
|
||||
notifyNewDataSource(newDataSource);
|
||||
return newDataSource;
|
||||
} catch (Exception ex) {
|
||||
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.addImg.exception.msg"), ex);
|
||||
}
|
||||
@ -554,6 +499,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
* reopens windows if needed.
|
||||
*
|
||||
* @param newDataSource new data source added
|
||||
* @deprecated Use notifyNewDataSource() instead.
|
||||
*/
|
||||
@Deprecated
|
||||
void addLocalDataSource(Content newDataSource) {
|
||||
@ -563,20 +509,10 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
/**
|
||||
* Notifies the UI that a new data source has been added.
|
||||
*
|
||||
*
|
||||
* @param newDataSource new data source added
|
||||
*/
|
||||
void notifyNewDataSource(Content newDataSource) {
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(Events.DATA_SOURCE_ADDED.toString(), null, newDataSource);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
eventPublisher.publish(new DataSourceAddedEvent(newDataSource));
|
||||
CoreComponentControl.openCoreWindows();
|
||||
}
|
||||
|
||||
@ -603,9 +539,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
public void closeCase() throws CaseActionException {
|
||||
changeCase(null);
|
||||
try {
|
||||
if (CaseType.MULTI_USER_CASE == this.caseType) {
|
||||
eventPublisher.closeRemoteEventChannel();
|
||||
}
|
||||
services.close();
|
||||
this.xmlcm.close(); // close the xmlcm
|
||||
this.db.close();
|
||||
@ -655,17 +588,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
xmlcm.setCaseName(newCaseName); // set the case
|
||||
name = newCaseName; // change the local value
|
||||
RecentCases.getInstance().updateRecentCase(oldCaseName, oldPath, newCaseName, newPath); // update the recent case
|
||||
try {
|
||||
pcs.firePropertyChange(Events.NAME.toString(), oldCaseName, newCaseName);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
doCaseNameChange(newCaseName);
|
||||
|
||||
eventPublisher.publish(new AutopsyEvent(Events.NAME.toString(), oldCaseName, newCaseName));
|
||||
updateMainWindowTitle(newCaseName);
|
||||
} catch (Exception e) {
|
||||
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateCaseName.exception.msg"), e);
|
||||
}
|
||||
@ -681,15 +605,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
try {
|
||||
xmlcm.setCaseExaminer(newExaminer); // set the examiner
|
||||
examiner = newExaminer;
|
||||
try {
|
||||
pcs.firePropertyChange(Events.EXAMINER.toString(), oldExaminer, newExaminer);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
eventPublisher.publish(new AutopsyEvent(Events.EXAMINER.toString(), oldExaminer, newExaminer));
|
||||
} catch (Exception e) {
|
||||
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateExaminer.exception.msg"), e);
|
||||
}
|
||||
@ -705,16 +621,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
try {
|
||||
xmlcm.setCaseNumber(newCaseNumber); // set the case number
|
||||
number = newCaseNumber;
|
||||
|
||||
try {
|
||||
pcs.firePropertyChange(Events.NUMBER.toString(), oldCaseNumber, newCaseNumber);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Case listener threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "Case.moduleErr"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"Case.changeCase.errListenToCaseUpdates.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
eventPublisher.publish(new AutopsyEvent(Events.NUMBER.toString(), oldCaseNumber, newCaseNumber));
|
||||
} catch (Exception e) {
|
||||
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateCaseNum.exception.msg"), e);
|
||||
}
|
||||
@ -917,12 +824,14 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the PropertyChangeSupport of this class
|
||||
* Gets a new PropertyChangeSupport object.
|
||||
*
|
||||
* @return PropertyChangeSupport
|
||||
* @return A new PropertyChangeSupport object with source set to null.
|
||||
* @deprecated Do not use.
|
||||
*/
|
||||
@Deprecated
|
||||
public static PropertyChangeSupport getPropertyChangeSupport() {
|
||||
return pcs;
|
||||
return new PropertyChangeSupport(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -958,20 +867,35 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
return timezones;
|
||||
}
|
||||
|
||||
// RJCTODO: Deprecate in favor of addEventSubscriber() and remove use of PropertyChangeSupport
|
||||
/**
|
||||
* Adds a subscriber to all case events from this Autopsy node and other
|
||||
* Autopsy nodes. To subscribe to only specific events, use one of the
|
||||
* overloads of addEventSubscriber().
|
||||
*
|
||||
* @param listener The subscriber to add.
|
||||
*/
|
||||
public static synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
pcs.addPropertyChangeListener(listener);
|
||||
// eventPublisher.addSubscriber(eventNames, listener);
|
||||
}
|
||||
|
||||
// RJCTODO: Deprecate in favor of removeEventSubscriber() and remove use of PropertyChangeSupport
|
||||
public static synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
pcs.removePropertyChangeListener(listener);
|
||||
// eventPublisher.removeSubscriber(eventNames, listener);
|
||||
addEventSubscriber(Stream.of(Events.values())
|
||||
.map(Events::toString)
|
||||
.collect(Collectors.toSet()), listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subscriber to events from this Autopsy node and other Autopsy nodes.
|
||||
* Removes a subscriber from all case events from this Autopsy node and
|
||||
* other Autopsy nodes. To remove a subscription to only specific events,
|
||||
* use one of the overloads of removeEventSubscriber().
|
||||
*
|
||||
* @param listener The subscriber to add.
|
||||
*/
|
||||
public static synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
removeEventSubscriber(Stream.of(Events.values())
|
||||
.map(Events::toString)
|
||||
.collect(Collectors.toSet()), listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subscriber to events from this Autopsy node and other Autopsy
|
||||
* nodes.
|
||||
*
|
||||
* @param eventNames The events the subscriber is interested in.
|
||||
* @param subscriber The subscriber to add.
|
||||
@ -981,7 +905,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subscriber to events from this Autopsy node and other Autopsy nodes.
|
||||
* Adds a subscriber to events from this Autopsy node and other Autopsy
|
||||
* nodes.
|
||||
*
|
||||
* @param eventNames The event the subscriber is interested in.
|
||||
* @param subscriber The subscriber to add.
|
||||
@ -991,7 +916,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subscriber to events from this Autopsy node and other Autopsy nodes.
|
||||
* Adds a subscriber to events from this Autopsy node and other Autopsy
|
||||
* nodes.
|
||||
*
|
||||
* @param eventName The event the subscriber is no longer interested in.
|
||||
* @param subscriber The subscriber to add.
|
||||
@ -1001,7 +927,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a subscriber to events from this Autopsy node and other Autopsy nodes.
|
||||
* Removes a subscriber to events from this Autopsy node and other Autopsy
|
||||
* nodes.
|
||||
*
|
||||
* @param eventNames The event the subscriber is no longer interested in.
|
||||
* @param subscriber The subscriber to add.
|
||||
@ -1301,7 +1228,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
|
||||
//case name change helper
|
||||
private static void doCaseNameChange(String newCaseName) {
|
||||
private static void updateMainWindowTitle(String newCaseName) {
|
||||
// update case name
|
||||
if (!newCaseName.equals("")) {
|
||||
Frame f = WindowManager.getDefault().getMainWindow();
|
||||
@ -1309,15 +1236,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
}
|
||||
}
|
||||
|
||||
//delete image helper
|
||||
private void doDeleteImage() {
|
||||
// no more image left in this case
|
||||
if (currentCase.hasData()) {
|
||||
// close all top components
|
||||
CoreComponentControl.closeCoreWindows();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveError(String context, String errorMessage) {
|
||||
MessageNotifyUtil.Notify.error(context, errorMessage);
|
||||
@ -1336,12 +1254,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
|
||||
*/
|
||||
public void addReport(String localPath, String srcModuleName, String reportName) throws TskCoreException {
|
||||
Report report = this.db.addReport(localPath, srcModuleName, reportName);
|
||||
try {
|
||||
Case.pcs.firePropertyChange(Events.REPORT_ADDED.toString(), null, report);
|
||||
} catch (Exception ex) {
|
||||
String errorMessage = String.format("A Case %s listener threw an exception", Events.REPORT_ADDED.toString()); //NON-NLS
|
||||
logger.log(Level.SEVERE, errorMessage, ex);
|
||||
}
|
||||
eventPublisher.publish(new AutopsyEvent(Events.REPORT_ADDED.toString(), null, report));
|
||||
}
|
||||
|
||||
public List<Report> getAllReports() throws TskCoreException {
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2015 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.casemodule.events;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Event published when a data source is added to a case.
|
||||
*/
|
||||
public final class DataSourceAddedEvent extends AutopsyEvent implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(DataSourceAddedEvent.class.getName());
|
||||
private transient Content dataSource;
|
||||
|
||||
/**
|
||||
* Constructs an event published when a data source is added to a case.
|
||||
*
|
||||
* @param dataSource The data source that was added.
|
||||
*/
|
||||
public DataSourceAddedEvent(Content dataSource) {
|
||||
/**
|
||||
* Putting the object id of the data source into newValue to allow for
|
||||
* lazy loading of the Content object. This bypasses the issues related
|
||||
* to the serialization and de-serialization of Content objects when the
|
||||
* event is published over a network.
|
||||
*/
|
||||
super(Case.Events.DATA_SOURCE_ADDED.toString(), null, dataSource.getId());
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data source that was added.
|
||||
*
|
||||
* @return The data source.
|
||||
*/
|
||||
@Override
|
||||
public Object getNewValue() {
|
||||
/**
|
||||
* The dataSource field is set in the constructor, but it is transient
|
||||
* so it will become null when the event is serialized for publication
|
||||
* over a network. Doing a lazy load of the Content object bypasses the
|
||||
* issues related to the serialization and de-serialization of Content
|
||||
* objects and may also save database round trips from other nodes since
|
||||
* subscribers to this event are often not interested in the event data.
|
||||
*/
|
||||
if (null != dataSource) {
|
||||
return dataSource;
|
||||
}
|
||||
try {
|
||||
long id = (Long) super.getOldValue();
|
||||
dataSource = Case.getCurrentCase().getSleuthkitCase().getContentById(id);
|
||||
return dataSource;
|
||||
} catch (IllegalStateException | TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error doing lazy load for remote event", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -27,6 +27,7 @@ import java.beans.PropertyVetoException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
@ -117,7 +118,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
subscribeToChangeEvents();
|
||||
associateLookup(ExplorerUtils.createLookup(em, getActionMap()));
|
||||
|
||||
|
||||
this.pcs = new PropertyChangeSupport(this);
|
||||
|
||||
// set the back & forward list and also disable the back & forward button
|
||||
@ -144,7 +144,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
}
|
||||
}
|
||||
});
|
||||
Case.addPropertyChangeListener(this);
|
||||
Case.addEventSubscriber(new HashSet<>(Arrays.asList(Case.Events.CURRENT_CASE.toString(), Case.Events.DATA_SOURCE_ADDED.toString())), this);
|
||||
this.em.addPropertyChangeListener(this);
|
||||
IngestManager.getInstance().addIngestJobEventListener(this);
|
||||
IngestManager.getInstance().addIngestModuleEventListener(this);
|
||||
@ -245,9 +245,11 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
forwardList.addLast(currentNodePath);
|
||||
forwardButton.setEnabled(true);
|
||||
|
||||
/* We peek instead of poll because we use its existence
|
||||
* in the list later on so that we do not reset the forward list
|
||||
* after the selection occurs. */
|
||||
/*
|
||||
* We peek instead of poll because we use its existence in the list
|
||||
* later on so that we do not reset the forward list after the selection
|
||||
* occurs.
|
||||
*/
|
||||
String[] newCurrentNodePath = backList.peekLast();
|
||||
|
||||
// enable / disable the back and forward button
|
||||
@ -388,7 +390,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
|
||||
root = new DirectoryTreeFilterNode(root, true);
|
||||
|
||||
|
||||
em.setRootContext(root);
|
||||
em.getRootContext().setName(currentCase.getName());
|
||||
em.getRootContext().setDisplayName(currentCase.getName());
|
||||
@ -407,7 +408,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
tree.expandNode(resultsChilds.findChild(KeywordHits.NAME));
|
||||
tree.expandNode(resultsChilds.findChild(ExtractedContent.NAME));
|
||||
|
||||
|
||||
Node views = childNodes.findChild(ViewsNode.NAME);
|
||||
Children viewsChilds = views.getChildren();
|
||||
for (Node n : viewsChilds.getNodes()) {
|
||||
@ -421,7 +421,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
dataResult.open(); // open the data result top component as well when the directory tree is opened
|
||||
}
|
||||
|
||||
|
||||
// select the first image node, if there is one
|
||||
// (this has to happen after dataResult is opened, because the event
|
||||
// of changing the selected node fires a handler that tries to make
|
||||
@ -534,22 +533,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
String changed = evt.getPropertyName();
|
||||
Object oldValue = evt.getOldValue();
|
||||
Object newValue = evt.getNewValue();
|
||||
|
||||
// change in the case name
|
||||
if (changed.equals(Case.Events.NAME.toString())) {
|
||||
// set the main title of the window
|
||||
String oldCaseName = oldValue.toString();
|
||||
String newCaseName = newValue.toString();
|
||||
|
||||
|
||||
// update the case name
|
||||
if ((!oldCaseName.equals("")) && (!newCaseName.equals(""))) {
|
||||
// change the root name and display name
|
||||
em.getRootContext().setName(newCaseName);
|
||||
em.getRootContext().setDisplayName(newCaseName);
|
||||
}
|
||||
} // changed current case
|
||||
else if (changed.equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
if (changed.equals(Case.Events.CURRENT_CASE.toString())) { // changed current case
|
||||
// When a case is closed, the old value of this property is the
|
||||
// closed Case object and the new value is null. When a case is
|
||||
// opened, the old value is null and the new value is the new Case
|
||||
@ -563,7 +547,13 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
Node emptyNode = new AbstractNode(Children.LEAF);
|
||||
em.setRootContext(emptyNode);
|
||||
} else if (newValue != null) {
|
||||
// A new case has been opened. Reset the forward and back
|
||||
// A new case has been opened. Reset the ExplorerManager.
|
||||
Case newCase = (Case) newValue;
|
||||
String newCaseName = newCase.getName();
|
||||
em.getRootContext().setName(newCaseName);
|
||||
em.getRootContext().setDisplayName(newCaseName);
|
||||
|
||||
// Reset the forward and back
|
||||
// buttons. Note that a call to CoreComponentControl.openCoreWindows()
|
||||
// by the new Case object will lead to a componentOpened() call
|
||||
// that will repopulate the tree.
|
||||
@ -574,12 +564,10 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
} // if the image is added to the case
|
||||
else if (changed.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
|
||||
componentOpened();
|
||||
}
|
||||
// change in node selection
|
||||
} // change in node selection
|
||||
else if (changed.equals(ExplorerManager.PROP_SELECTED_NODES)) {
|
||||
respondSelection((Node[]) oldValue, (Node[]) newValue);
|
||||
}
|
||||
else if (changed.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
|
||||
} else if (changed.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
|
||||
// nothing to do here.
|
||||
// all nodes should be listening for these events and update accordingly.
|
||||
} else if (changed.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
|
||||
@ -615,7 +603,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Some lock that prevents certain Node operations is set during the
|
||||
// ExplorerManager selection-change, so we must handle changes after the
|
||||
// selection-change event is processed.
|
||||
@ -630,7 +617,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
|
||||
// make sure dataResult is open, redundant?
|
||||
//dataResult.open();
|
||||
|
||||
Node treeNode = DirectoryTreeTopComponent.this.getSelectedNode();
|
||||
if (treeNode != null) {
|
||||
DirectoryTreeFilterNode.OriginalNode origin = treeNode.getLookup().lookup(DirectoryTreeFilterNode.OriginalNode.class);
|
||||
@ -687,10 +673,11 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
Node selectedNode = selectedNodes[0];
|
||||
String selectedNodeName = selectedNode.getName();
|
||||
|
||||
/* get the previous entry to make sure we don't duplicate it.
|
||||
* Motivation for this is also that if we used the back button,
|
||||
* then we already added the 'current' node to 'back' and we will
|
||||
* detect that and not reset the forward list.
|
||||
/*
|
||||
* get the previous entry to make sure we don't duplicate it. Motivation
|
||||
* for this is also that if we used the back button, then we already
|
||||
* added the 'current' node to 'back' and we will detect that and not
|
||||
* reset the forward list.
|
||||
*/
|
||||
String[] currentLast = backList.peekLast();
|
||||
String lastNodeName = null;
|
||||
@ -783,7 +770,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
|
||||
//final TreeView tree = getTree();
|
||||
//tree.expandNode(imagesNode);
|
||||
|
||||
setSelectedNode(selectedPath, DataSourcesNode.NAME);
|
||||
|
||||
}
|
||||
@ -838,7 +824,6 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
// //@@@ setSelectedNode(selectedPath, ResultsNode.NAME);
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* Set the selected node using a path to a previously selected node.
|
||||
*
|
||||
@ -975,11 +960,11 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
}
|
||||
treeNode = extractedChilds.findChild(type.getLabel());
|
||||
}
|
||||
|
||||
|
||||
if (treeNode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
em.setExploredContextAndSelection(treeNode, new Node[]{treeNode});
|
||||
} catch (PropertyVetoException ex) {
|
||||
@ -1025,7 +1010,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
||||
logger.log(Level.SEVERE, "DirectoryTreeTopComponent listener threw exception", e); //NON-NLS
|
||||
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "DirectoryTreeTopComponent.moduleErr"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"DirectoryTreeTopComponent.moduleErr.msg"),
|
||||
"DirectoryTreeTopComponent.moduleErr.msg"),
|
||||
MessageNotifyUtil.MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -125,18 +125,28 @@ public final class AutopsyEventPublisher {
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event.
|
||||
* Publishes an event to this Autopsy node and other Autopsy nodes.
|
||||
*
|
||||
* @param event The event to publish.
|
||||
* @throws JMSException
|
||||
*/
|
||||
synchronized public void publish(AutopsyEvent event) throws JMSException {
|
||||
event.setSourceType(AutopsyEvent.SourceType.LOCAL);
|
||||
localPublisher.publish(event);
|
||||
synchronized public void publish(AutopsyEvent event) {
|
||||
publishLocally(event);
|
||||
if (null != remotePublisher) {
|
||||
event.setSourceType(AutopsyEvent.SourceType.REMOTE);
|
||||
remotePublisher.send(event);
|
||||
try {
|
||||
remotePublisher.publish(event);
|
||||
} catch (JMSException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to publish %s event remotely", event.getPropertyName()), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to this Autopsy node only.
|
||||
*
|
||||
* @param event The event to publish.
|
||||
*/
|
||||
synchronized public void publishLocally(AutopsyEvent event) {
|
||||
localPublisher.publish(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ final class RemoteEventPublisher {
|
||||
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
Topic topic = session.createTopic(eventChannelName);
|
||||
producer = session.createProducer(topic);
|
||||
MessageConsumer consumer = session.createConsumer(topic, "events = '" + ALL_MESSAGE_SELECTOR + "'", true);
|
||||
MessageConsumer consumer = session.createConsumer(topic, "events = '" + ALL_MESSAGE_SELECTOR + "'", true); // RJCTODO: Can I use the empty string?
|
||||
receiver = new MessageReceiver();
|
||||
consumer.setMessageListener(receiver);
|
||||
} catch (URISyntaxException | JMSException ex) {
|
||||
@ -102,9 +102,9 @@ final class RemoteEventPublisher {
|
||||
/**
|
||||
* Sends an event message to the message service.
|
||||
*
|
||||
* @param event The event to send.
|
||||
* @param event The event to publish.
|
||||
*/
|
||||
synchronized void send(AutopsyEvent event) throws JMSException {
|
||||
synchronized void publish(AutopsyEvent event) throws JMSException {
|
||||
ObjectMessage message = session.createObjectMessage();
|
||||
message.setStringProperty("events", ALL_MESSAGE_SELECTOR);
|
||||
message.setObject(event);
|
||||
@ -131,6 +131,7 @@ final class RemoteEventPublisher {
|
||||
Object object = objectMessage.getObject();
|
||||
if (object instanceof AutopsyEvent) {
|
||||
AutopsyEvent event = (AutopsyEvent) object;
|
||||
event.setSourceType(AutopsyEvent.SourceType.REMOTE);
|
||||
localPublisher.publish(event);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2011 Basis Technology Corp.
|
||||
* Copyright 2011-2015 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -160,7 +160,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
|
||||
|
||||
private static List<String> createTimeZoneList() {
|
||||
|
||||
List<String> timeZones = new ArrayList<String>();
|
||||
List<String> timeZones = new ArrayList<>();
|
||||
|
||||
if (Case.existsCurrentCase()) {
|
||||
// get the latest case
|
||||
@ -241,7 +241,7 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
|
||||
Object oldValue = evt.getOldValue();
|
||||
Object newValue = evt.getNewValue();
|
||||
|
||||
if (changed.equals(Case.Events.CURRENT_CASE.toString().toString())) {
|
||||
if (changed.equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
// create or open a case
|
||||
if (newValue != null) {
|
||||
DateSearchFilter.this.updateTimeZoneList();
|
||||
|
@ -38,7 +38,6 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.jms.JMSException;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
@ -283,15 +282,13 @@ public class IngestManager {
|
||||
* Subscribes this ingest manager to local and remote case-related events.
|
||||
*/
|
||||
private void subscribeToCaseEvents() {
|
||||
Case.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
if (event.getPropertyName().equals(Case.Events.CURRENT_CASE.toString())) {
|
||||
if (event.getNewValue() != null) {
|
||||
handleCaseOpened();
|
||||
} else {
|
||||
handleCaseClosed();
|
||||
}
|
||||
if (event.getNewValue() != null) {
|
||||
handleCaseOpened();
|
||||
} else {
|
||||
handleCaseClosed();
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -309,16 +306,16 @@ public class IngestManager {
|
||||
} catch (AutopsyEventException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to open remote job events channel", ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(NbBundle.getMessage(IngestManager.class,
|
||||
"IngestManager.OpenEventChannel.ErrMsg",
|
||||
caseName));
|
||||
"IngestManager.OpenEventChannel.ErrMsg",
|
||||
caseName));
|
||||
}
|
||||
try {
|
||||
moduleEventPublisher.openRemoteEventChannel(String.format(MODULE_EVENT_CHANNEL_NAME, caseName));
|
||||
} catch (AutopsyEventException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to open remote module events channel", ex); //NON-NLS
|
||||
MessageNotifyUtil.Message.error(NbBundle.getMessage(IngestManager.class,
|
||||
"IngestManager.OpenEventChannel.ErrMsg",
|
||||
caseName));
|
||||
"IngestManager.OpenEventChannel.ErrMsg",
|
||||
caseName));
|
||||
}
|
||||
}
|
||||
} catch (IllegalStateException ex) {
|
||||
@ -889,11 +886,7 @@ public class IngestManager {
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
publisher.publish(event);
|
||||
} catch (JMSException ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to publish %s event to remote subscribers", event.getPropertyName()), ex);
|
||||
}
|
||||
publisher.publish(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ public final class FileAnalyzedEvent extends AutopsyEvent implements Serializabl
|
||||
* event is published over a network.
|
||||
*/
|
||||
super(IngestManager.IngestModuleEvent.FILE_DONE.toString(), file.getId(), null);
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user