/*******************************************************************************
* Copyright (c) 2012-2015 INRIA.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Generoso Pagano - initial API and implementation
******************************************************************************/
package fr.inria.soctrace.framesoc.core.bus;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Framesoc Notification Bus singleton.
*
* <p>
* This notification bus is used to exchange events among
* UI modules.
* The singleton enables also context variable storage.
*
* @author "Generoso Pagano <generoso.pagano@inria.fr>"
*/
public class FramesocBus {
/**
* Logger
*/
private static final Logger logger = LoggerFactory.getLogger(FramesocBus.class);
/**
* Listeners map: topic - list of listeners
*/
private Map<FramesocBusTopic, List<IFramesocBusListener>> listeners;
/**
* Variables map
*/
private Map<FramesocBusVariable, Object> variables;
/**
* Single instance of the FB
*/
private static FramesocBus instance = null;
/**
* Instance getter
* @return the manager instance
*/
public static FramesocBus getInstance() {
if (instance == null)
instance = new FramesocBus();
return instance;
}
/**
* Send a notification on the Framesoc Bus
* @param topic topic of the notification
* @param data data of the notification (may be null)
*/
public void send(FramesocBusTopic topic, Object data) {
logger.debug("send {} for topic {}", data, topic);
if (listeners.containsKey(topic)) {
List<IFramesocBusListener> list = listeners.get(topic);
for (IFramesocBusListener listener: list) {
try {
listener.handle(topic, data);
} catch (Exception e) {
// Continue handling the event for other listeners
// even if one of them produces an unchecked exception
logger.debug("Exception in listener " + listener);
e.printStackTrace();
}
}
}
}
/**
* Register a listener for a given topic notification
* @param topic topic of the notification
* @param listener Framesoc Bus listener
*/
public void register(FramesocBusTopic topic, IFramesocBusListener listener) {
logger.debug("register {} for topic {}", listener, topic);
if (!listeners.containsKey(topic)) {
listeners.put(topic, new LinkedList<IFramesocBusListener>());
}
if (!listeners.get(topic).contains(listener))
listeners.get(topic).add(listener);
}
/**
* Unregister a listener from a given topic notification
* @param topic topic of the notification
* @param listener Framesoc Bus listener
*/
public void unregister(FramesocBusTopic topic, IFramesocBusListener listener) {
logger.debug("unregister {} for topic {}", listener, topic);
if (listeners.containsKey(topic)) {
List<IFramesocBusListener> list = listeners.get(topic);
list.remove(listener);
if (list.size() == 0)
listeners.remove(topic);
}
}
/**
* Set a variable.
* @param name variable name
* @param value variable value
*/
public synchronized void setVariable(FramesocBusVariable variable, Object value) {
logger.debug("set variable: name={}, value={}", variable, value);
variables.put(variable, value);
}
/**
* Get a given variable value. May return null if the variable is not set.
* @param name variable
* @return the variable value, or null if not set
*/
public synchronized Object getVariable(FramesocBusVariable variable) {
logger.debug("get variable: name={}, value={}", variable, variables.get(variable));
return variables.get(variable);
}
/**
* Private constructor. Prevents instantiation.
*/
private FramesocBus() {
logger.debug("instance created");
listeners = new HashMap<FramesocBusTopic, List<IFramesocBusListener>>();
variables = new HashMap<FramesocBusVariable, Object>();
};
}