Merge pull request #1198 from rcordovano/msg_infrastructure

Add messaging/event infrastructure
This commit is contained in:
Richard Cordovano 2015-04-17 09:50:41 -04:00
commit a68f6be8fb
12 changed files with 463 additions and 113 deletions

View File

@ -18,7 +18,7 @@
*/
package org.sleuthkit.autopsy.casemodule;
import org.sleuthkit.autopsy.core.messenger.Messenger;
import org.sleuthkit.autopsy.messaging.Messenger;
import java.awt.Frame;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
@ -26,8 +26,12 @@ import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
@ -37,6 +41,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.logging.Level;
import javax.jms.JMSException;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openide.util.Lookup;
@ -46,6 +51,7 @@ import org.openide.util.actions.SystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.services.Services;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -54,6 +60,8 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.datamodel.*;
import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
import org.sleuthkit.autopsy.events.AutopsyEventSubscriber;
/**
* Stores all information for a given case. Only a single case can currently be
@ -176,7 +184,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
private final SleuthkitCase db;
// Track the current case (only set with changeCase() method)
private static Case currentCase = null;
private CaseType caseType;
private final CaseType caseType;
private final Services services;
private static final Logger logger = Logger.getLogger(Case.class.getName());
static final String CASE_EXTENSION = "aut"; //NON-NLS
@ -185,7 +193,23 @@ public class Case implements SleuthkitCase.ErrorObserver {
// we cache if the case has data in it yet since a few places ask for it and we dont' need to keep going to DB
private boolean hasData = false;
private Messenger messenger;
/**
* Multi-user cases send and receiveEvent event messages from other Autopsy
* nodes using a Messenger and publish remote events using a
* AutopsyEventPublisher. The AutopsyEventPublisher is static to allow
* subscribers to register once for all cases.
*/
private static final Collection<String> REMOTE_EVENT_NAMES = new ArrayList<>(Arrays.asList(
Events.NAME.toString(),
Events.NUMBER.toString(),
Events.EXAMINER.toString(),
Events.DATA_SOURCE_ADDED.toString(),
Events.DATA_SOURCE_ADDED.toString(),
Events.DATA_SOURCE_DELETED.toString(),
Events.REPORT_ADDED.toString()));
private static final AutopsyEventPublisher eventPublisher = new AutopsyEventPublisher();
private final EventSubscriber eventSubscriber;
private final Messenger messenger;
/**
* Constructor for the Case class
@ -199,7 +223,8 @@ public class Case implements SleuthkitCase.ErrorObserver {
this.caseType = type;
this.db = db;
this.services = new Services(db);
// messenger = new Messenger(this.name);
this.eventSubscriber = new EventSubscriber();
this.messenger = new Messenger(this.name, eventPublisher);
}
/**
@ -208,6 +233,16 @@ public class Case implements SleuthkitCase.ErrorObserver {
*/
private void init() {
db.addErrorObserver(this);
if (CaseType.MULTI_USER_CASE == this.caseType) {
addRemoteEventSubscriber(REMOTE_EVENT_NAMES, eventSubscriber);
try {
messenger.start(UserPreferences.getMessageServiceConnectionInfo());
} catch (URISyntaxException | JMSException ex) {
// RJCTODO: Add some sort of notification to user.
logger.log(Level.SEVERE, "Failed to start messenger", ex);
}
}
}
/**
@ -351,7 +386,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
String indexName = caseName + "_" + dateFormat.format(date);
String dbName = null;
// figure out the database name and index name for text extraction
if (caseType == CaseType.SINGLE_USER_CASE) {
dbName = caseDir + File.separator + "autopsy.db"; //NON-NLS
@ -381,7 +416,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
*/
Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
newCase.init();
// newCase.messenger.start();
changeCase(newCase);
}
@ -442,7 +476,6 @@ public class Case implements SleuthkitCase.ErrorObserver {
*/
Case openedCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
openedCase.init();
// openedCase.messenger.start();
changeCase(openedCase);
@ -591,8 +624,11 @@ public class Case implements SleuthkitCase.ErrorObserver {
public void closeCase() throws CaseActionException {
changeCase(null);
Case.eventPublisher.removeSubscriber(REMOTE_EVENT_NAMES, eventSubscriber);
try {
// messenger.stop();
if (CaseType.MULTI_USER_CASE == this.caseType) {
messenger.stop();
}
services.close();
this.xmlcm.close(); // close the xmlcm
this.db.close();
@ -797,12 +833,13 @@ public class Case implements SleuthkitCase.ErrorObserver {
/**
* Get the case type.
* @return
*
* @return
*/
public CaseType getCaseType() {
return this.caseType;
}
/**
* Gets the full path to the temp directory of this case
*
@ -952,6 +989,50 @@ public class Case implements SleuthkitCase.ErrorObserver {
pcs.removePropertyChangeListener(listener);
}
/**
* Adds an subscriber to events from other Autopsy nodes when a multi-user
* case is open.
*
* @param eventNames The events the subscriber is interested in.
* @param subscriber The subscriber to add.
*/
public static void addRemoteEventSubscriber(Collection<String> eventNames, AutopsyEventSubscriber subscriber) {
eventPublisher.addSubscriber(eventNames, subscriber);
}
/**
* Adds an subscriber to events from other Autopsy nodes when a multi-user
* case is open.
*
* @param eventNames The event the subscriber is interested in.
* @param subscriber The subscriber to add.
*/
public static void addRemoteEventSubscriber(String eventName, AutopsyEventSubscriber subscriber) {
eventPublisher.addSubscriber(eventName, subscriber);
}
/**
* Removes a subscriber to events from other Autopsy nodes when a multi-user
* case is open.
*
* @param eventName The event the subscriber is no longer interested in.
* @param subscriber The subscriber to add.
*/
public static void removeRemoteEventSubscriber(String eventName, AutopsyEventSubscriber subscriber) {
eventPublisher.removeSubscriber(eventName, subscriber);
}
/**
* Removes a subscriber to events from other Autopsy nodes when a multi-user
* case is open.
*
* @param eventNames The event the subscriber is no longer interested in.
* @param subscriber The subscriber to add.
*/
public static void removeRemoteEventSubscriber(Collection<String> eventNames, AutopsyEventSubscriber subscriber) {
eventPublisher.removeSubscriber(eventNames, subscriber);
}
/**
* Check if image from the given image path exists.
*
@ -1305,4 +1386,16 @@ public class Case implements SleuthkitCase.ErrorObserver {
}
return hasData;
}
private final class EventSubscriber implements AutopsyEventSubscriber {
/**
* @inheritDoc
*/
@Override
public void receiveEvent(AutopsyEvent event) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}

View File

@ -18,7 +18,7 @@
*/
package org.sleuthkit.autopsy.core;
import org.sleuthkit.autopsy.core.messenger.MessageServiceConnectionInfo;
import org.sleuthkit.autopsy.messaging.MessageServiceConnectionInfo;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
import org.openide.util.NbPreferences;

View File

@ -1,96 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-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.core.messenger;
import java.beans.PropertyChangeEvent;
import java.util.logging.Level;
import javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.sleuthkit.autopsy.coreutils.Logger;
public final class Messenger implements MessageListener {
private static final String ALL_MESSAGE_SELECTOR = "All";
private static final Logger logger = Logger.getLogger(Messenger.class.getName());
private final String caseName;
private Connection connection;
private Session session;
private MessageProducer producer;
Messenger(String caseName) {
this.caseName = caseName;
}
void start(MessageServiceConnectionInfo info) {
try {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(info.getUserName(), info.getPassword(), info.getURI());
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(caseName);
producer = session.createProducer(topic);
MessageConsumer consumer = session.createConsumer(topic, "events = '" + ALL_MESSAGE_SELECTOR + "'", true);
consumer.setMessageListener(this);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Startup error", ex);
}
}
void stop() {
try {
session.close();
connection.close();
} catch (Exception ex) {
logger.log(Level.SEVERE, "Shutdown error", ex);
}
}
public void send(PropertyChangeEvent event) {
try {
ObjectMessage message = session.createObjectMessage();
message.setStringProperty("events", ALL_MESSAGE_SELECTOR);
message.setObject(event);
producer.send(message);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Publishing error", ex);
}
}
@Override
public void onMessage(Message message) {
try {
if (message instanceof ObjectMessage) {
ObjectMessage objMessage = (ObjectMessage) message;
String event = (String) objMessage.getObject();
logger.log(Level.INFO, "Received {0}", event);
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Publishing error", ex);
}
}
}

View File

@ -15,7 +15,7 @@ import org.openide.util.NbBundle;
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
import org.sleuthkit.datamodel.TskData.DbType;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.core.messenger.MessageServiceConnectionInfo;
import org.sleuthkit.autopsy.messaging.MessageServiceConnectionInfo;
import org.sleuthkit.autopsy.coreutils.Logger;
public final class MultiUserSettingsPanel extends javax.swing.JPanel {

View File

@ -0,0 +1,57 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-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.events;
import java.beans.PropertyChangeEvent;
import java.io.Serializable;
/**
* A base class for events that can be published locally as well as to other
* Autopsy nodes when a multi-user case is open. It extends PropertyChangeEvent
* to integrate with the legacy use of JavaBeans PropertyChangeEvents and
* PropertyChangeListeners as a local event system.
*/
public class AutopsyEvent extends PropertyChangeEvent implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Events have a source field set to local or remote to allow event
* subscribers to filter events by source type.
*/
public enum SourceType {
Local,
Remote
};
/**
* Constructs an event that can be published locally and to other Autopsy
* nodes when a multi-user case is open.
*
* @param source The source of the event, local or remote.
* @param eventName The event name.
* @param oldValue The "old" value to associate with the event. May be null.
* @param newValue The "new" value to associate with the event. May be null.
*/
AutopsyEvent(SourceType source, String eventName, Object oldValue, Object newValue) {
super(source, eventName, oldValue, newValue);
}
}

View File

@ -0,0 +1,112 @@
/*
* 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.events;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Provides thread-safe support for publishing events to registered subscribers.
*/
public class AutopsyEventPublisher {
private static final Logger logger = Logger.getLogger(AutopsyEventPublisher.class.getName());
private final Map<String, Set<AutopsyEventSubscriber>> subscribersByEvent;
/**
* Constructs an object for publishing events to registered subscribers.
*/
public AutopsyEventPublisher() {
subscribersByEvent = new HashMap<>();
}
/**
* Adds an event subscriber to this publisher.
*
* @param eventNames The events the subscriber is interested in.
* @param subscriber The subscriber to add.
*/
synchronized public void addSubscriber(Collection<String> eventNames, AutopsyEventSubscriber subscriber) {
for (String eventName : eventNames) {
addSubscriber(eventName, subscriber);
}
}
/**
* Adds an event subscriber to this publisher.
*
* @param eventName The event the subscriber is interested in.
* @param subscriber The subscriber to add.
*/
synchronized public void addSubscriber(String eventName, AutopsyEventSubscriber subscriber) {
subscribersByEvent.putIfAbsent(eventName, new HashSet<>());
Set<AutopsyEventSubscriber> subscribers = subscribersByEvent.get(eventName);
subscribers.add(subscriber);
}
/**
* Removes an event subscriber from this publisher.
*
* @param eventNames The events the subscriber is no longer interested in.
* @param subscriber The subscriber to remove.
*/
synchronized public void removeSubscriber(Collection<String> eventNames, AutopsyEventSubscriber subscriber) {
for (String eventName : eventNames) {
removeSubscriber(eventName, subscriber);
}
}
/**
* Removes an event subscriber from this publisher.
*
* @param eventNames The event the subscriber is no longer interested in.
* @param subscriber The subscriber to remove.
*/
synchronized public void removeSubscriber(String eventName, AutopsyEventSubscriber subscriber) {
Set<AutopsyEventSubscriber> subscribers = subscribersByEvent.getOrDefault(eventName, null);
if (null != subscribers) {
subscribers.remove(subscriber);
}
}
/**
* Publishes an event to all registered subscribers, even if a subscriber
* throws an exception.
*
* @param event The event to be published.
*/
synchronized public void publish(AutopsyEvent event) {
Set<AutopsyEventSubscriber> subscribers = subscribersByEvent.getOrDefault(event.getPropertyName(), null);
if (null != subscribers) {
for (AutopsyEventSubscriber subscriber : subscribers) {
try {
subscriber.receiveEvent(event);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Exception thrown by subscriber", ex);
}
}
}
}
}

View File

@ -0,0 +1,33 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-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.events;
/**
* An interface to be implemented by classes that want to register to receiveEvent
events.
*/
public interface AutopsyEventSubscriber {
/**
* Receives a subscribed event.
*
* @param event The event.
*/
void receiveEvent(AutopsyEvent event);
}

View File

@ -24,6 +24,7 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
@ -43,6 +44,8 @@ import org.openide.util.Cancellable;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.events.AutopsyEventSubscriber;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.datamodel.AbstractFile;
@ -268,6 +271,9 @@ public class IngestManager {
ingestThreadActivitySnapshots.put(threadId, new IngestThreadActivitySnapshot(threadId));
}
/**
* Subscribes this ingest manager to local and remote case-related events.
*/
private void subscribeToCaseEvents() {
Case.addPropertyChangeListener(new PropertyChangeListener() {
@Override
@ -281,8 +287,23 @@ public class IngestManager {
}
}
});
}
Collection<String> remoteEventNames = new ArrayList<>(Arrays.asList(
IngestJobEvent.STARTED.toString(),
IngestJobEvent.COMPLETED.toString(),
IngestJobEvent.CANCELLED.toString(),
IngestModuleEvent.DATA_ADDED.toString(),
IngestModuleEvent.CONTENT_CHANGED.toString(),
IngestModuleEvent.FILE_DONE.toString()));
Case.addRemoteEventSubscriber(remoteEventNames, new AutopsyEventSubscriber() {
@Override
public void receiveEvent(AutopsyEvent event) {
throw new UnsupportedOperationException("Not supported yet.");
}
});
}
synchronized void handleCaseOpened() {
this.jobCreationIsEnabled = true;
clearIngestMessageBox();

View File

@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.core.messenger;
package org.sleuthkit.autopsy.messaging;
import java.net.URI;
import java.net.URISyntaxException;
@ -33,7 +33,7 @@ public final class MessageServiceConnectionInfo {
private final String port;
/**
* Constructs an object containing the connection info for a Java Message
* Constructs an object containing connection info for a Java Message
* Service (JMS) provider.
*
* @param userName The user name to use for a message service connection.

View File

@ -0,0 +1,130 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-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.messaging;
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import java.net.URISyntaxException;
import java.util.logging.Level;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Uses a message service to send and receives event messages between Autopsy
* nodes when a multi-user case is open.
*/
public final class Messenger implements MessageListener {
private static final Logger logger = Logger.getLogger(Messenger.class.getName());
private static final String ALL_MESSAGE_SELECTOR = "All";
private final String caseName;
private final AutopsyEventPublisher eventPublisher;
private Connection connection;
private Session session;
private MessageProducer producer;
/**
* Creates a messenger to send and receive event messages between Autopsy
* nodes when a multi-user case is open.
*
* @param caseName The name of the multi-user case.
* @param eventPublisher An event publisher that will be used to publish
* remote events locally.
*/
public Messenger(String caseName, AutopsyEventPublisher eventPublisher) {
this.caseName = caseName;
this.eventPublisher = eventPublisher;
}
/**
* Starts this messenger, causing it to connect to the message service.
*
* @param info Connection info for the message service.
* @throws URISyntaxException if the URI in the connection info is
* malformed.
* @throws JMSException if the connection to the message service cannot be
* made.
*/
public void start(MessageServiceConnectionInfo info) throws URISyntaxException, JMSException {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(info.getUserName(), info.getPassword(), info.getURI());
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(caseName);
producer = session.createProducer(topic);
MessageConsumer consumer = session.createConsumer(topic, "events = '" + ALL_MESSAGE_SELECTOR + "'", true);
consumer.setMessageListener(this);
}
/**
* Stops this messenger, causing it to disconnect from the message service.
*/
public void stop() {
try {
session.close();
connection.close();
} catch (JMSException ex) {
logger.log(Level.SEVERE, "Failed to close connection to message service", ex);
}
}
/**
* Sends an event message via the message service.
*
* @param event The event to send.
*/
public void send(AutopsyEvent event) throws JMSException {
ObjectMessage message = session.createObjectMessage();
message.setStringProperty("events", ALL_MESSAGE_SELECTOR);
message.setObject(event);
producer.send(message);
}
/**
* Receives an event message via the message service and publishes it
* locally.
*
* @param message The message.
*/
@Override
public void onMessage(Message message) {
try {
if (message instanceof ObjectMessage) {
ObjectMessage objectMessage = (ObjectMessage) message;
Object object = objectMessage.getObject();
if (object instanceof AutopsyEvent) {
AutopsyEvent event = (AutopsyEvent) object;
eventPublisher.publish(event);
}
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Error receiving message", ex);
}
}
}

View File

@ -1,5 +1,5 @@
#Updated by build script
#Wed, 15 Apr 2015 18:11:08 -0400
#Thu, 16 Apr 2015 17:09:30 -0400
LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=314
SPLASH_WIDTH=538

View File

@ -1,5 +1,5 @@
#Updated by build script
#Wed, 15 Apr 2015 18:11:08 -0400
#Thu, 16 Apr 2015 17:09:30 -0400
CTL_MainWindow_Title=Autopsy 3.1.2
CTL_MainWindow_Title_No_Project=Autopsy 3.1.2