All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.openfin.desktop.InterApplicationBus Maven / Gradle / Ivy

There is a newer version: 11.0.2
Show newest version
package com.openfin.desktop;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A messaging bus that allows for pub / sub messaging between different applications.
 * Available via getInterApplicationBus() method on DesktopConnection
 */

public class InterApplicationBus {
    private final static Logger logger = LoggerFactory.getLogger(InterApplicationBus.class.getName());

    private DesktopConnection desktopConnection;
    private Map>> callbackMap; // sourceUuid -> topic -> list of BusListener
    private List subscribeListeners;

    /**
     * Constructor
     * @param desktopConnection Connection object to the AppDesktop
     */
    public InterApplicationBus(DesktopConnection desktopConnection) {
        callbackMap = new ConcurrentHashMap<>();
        subscribeListeners = new CopyOnWriteArrayList <>();
        this.desktopConnection = desktopConnection;
    }

    /**
     * Publishes a message to a topic
     *
     * @param topic Topic to which the message is published
     * @param message The JSON message to publish     *
     * @throws DesktopException if this method fails to publish a message
     * @see DesktopException
     */
    public void publish(String topic, Object message) throws DesktopException {
        publish(topic, message, null);
    }

    /**
     * Publishes a message to a topic
     *
     * @param topic Topic to which the message is published
     * @param message The JSON message to publish     *
     * @param callback AckListener for the request
     * @throws DesktopException if this method fails to publish a message
     * @see DesktopException
     */
    public void publish(String topic, Object message, AckListener callback) throws DesktopException {
        JSONObject payload = new JSONObject();

        try {
            payload.put("topic", topic).put("message", (message != null) ? message : null);
        } catch (JSONException e) {
            logger.error("Error publishing message", e);
            throw new DesktopException(e);
        }

        desktopConnection.sendAction("publish-message", payload, callback, message != null ? message : desktopConnection);
    }

    /**
     * Sends a message to an application
     *
     * @param destinationUuid UUID of the application from which messages are sent
     * @param topic Topic to which the message is published
     * @param message The JSON message to publish
     * @throws DesktopException if this method fails to send a message
     * @see DesktopException
     */
    public void send(String destinationUuid, String topic, Object message) throws DesktopException {
        send(destinationUuid, topic, message, null);
    }

    /**
     * Sends a message to an application
     *
     * @param destinationUuid UUID of the application from which messages are sent
     * @param topic Topic to which the message is published
     * @param message The JSON message to publish
     * @param listener AckListener for the message
     * @throws DesktopException if this method fails to send a message
     * @see DesktopException
     */
    public void send(String destinationUuid, String topic, Object message, AckListener listener) throws DesktopException {
        JSONObject payload = new JSONObject();

        try {
            payload.put("destinationUuid", destinationUuid)
                    .put("topic", topic)
                    .put("message", (message != null) ? message : null);
        } catch (JSONException e) {
            logger.error("Error sending message", e);
            throw new DesktopException(e);
        }

        desktopConnection.sendAction("send-message", payload, listener, message != null ? message : desktopConnection);
    }

    /**
     * Subscribes to messages on the specified topic
     *
     * @param sourceUuid The UUID of the application to which to subscribe. The wildcard "*" can be used to receive messages from all applications
     * @param topic The topic to be subscribed to
     * @param listener BusListener for the subscription
     * @see BusListener
     * @throws DesktopException if this method fails to subscribe to a topic
     * @see DesktopException
     */
    public void subscribe(String sourceUuid, String topic, BusListener listener) throws DesktopException {
        subscribe(sourceUuid, topic, listener, null);
    }

    /**
     * Subscribes to messages on the specified topic
     *
     * @param sourceUuid The UUID of the application to which to subscribe. The wildcard "*" can be used to receive messages from all applications
     * @param topic The topic to be subscribed to
     * @param listener BusListener for the subscription
     * @param callback AckListener for the message
     * @see BusListener
     * @see AckListener
     * @throws DesktopException if this method fails to subscribe to a topic
     * @see DesktopException
     */
    public void subscribe(String sourceUuid, String topic, BusListener listener, AckListener callback) throws DesktopException {
        Map> cbByTopic = callbackMap.get(sourceUuid);
        if (cbByTopic == null) {
            cbByTopic = new ConcurrentHashMap<>();
            callbackMap.put(sourceUuid, cbByTopic);
        }
        List cbList = cbByTopic.get(topic);
        if (cbList == null) {
            cbList = new CopyOnWriteArrayList();
            cbByTopic.put(topic, cbList);
        }

        cbList.add(listener);

        JSONObject payload = new JSONObject();

        try {
            payload.put("sourceUuid", sourceUuid).put("topic", topic);
        } catch (JSONException e) {
            logger.error("Error subscribing", e);
            throw new DesktopException(e);
        }

        desktopConnection.sendAction("subscribe", payload, callback, this);
    }

    /**
     * Unsubscribes to messages on the specified topic
     *
     * @param sourceUuid UUID of the application
     * @param topic The topic to be subscribed to
     * @param listener BusListener for the subscription
     * @see BusListener
     * @throws DesktopException if this method fails to unsubscribe a topic
     * @see DesktopException
     */
    public void unsubscribe(String sourceUuid, String topic, BusListener listener) throws DesktopException {
        unsubscribe(sourceUuid, topic, listener, null);
    }

    /**
     * Unsubscribes to messages on the specified topic
     *
     * @param sourceUuid UUID of the application
     * @param topic The topic to be subscribed to
     * @param listener BusListener for the subscription
     * @param callback AckListener for the message
     * @see BusListener
     * @see AckListener
     * @throws DesktopException if this method fails t unsubscribe a topic
     * @see DesktopException
     */
    public void unsubscribe(String sourceUuid, String topic, BusListener listener, AckListener callback) throws DesktopException {

        Map> cbMap = callbackMap.get(sourceUuid);
        if (cbMap != null) {
            List cbList = cbMap.get(topic);
            if (cbList != null) {
                if (cbList.remove(listener)) {
                    JSONObject payload = new JSONObject();
                    try {
                        payload.put("sourceUuid", sourceUuid).put("topic", topic);
                    } catch (JSONException e) {
                        logger.error("Error unsubscribing", e);
                        throw new DesktopException(e);
                    }
                    desktopConnection.sendAction("unsubscribe", payload, callback, this);
                }
            }
        }
    }

    /**
     * Dispatches a messages to listeners
     * @param sourceUuid UUID of the application from which messages are sent
     * @param topic Topic to which the mssage is published
     * @param message The JSON message to be dispatched
     */
    void dispatchMessageToCallbacks(String sourceUuid, String topic, Object message) {
        if (callbackMap.containsKey("*")) {
            dispatchMessageToCallbacks(callbackMap.get("*"), sourceUuid, topic, message);
        }
        dispatchMessageToCallbacks(callbackMap.get(sourceUuid), sourceUuid, topic, message);
    }

    private void dispatchMessageToCallbacks(Map> cbByTopic, String sourceUuid, String topic, Object message) {
        if (cbByTopic != null) {
            dispatchMessageToCallbacks(cbByTopic.get(topic), sourceUuid, topic, message);
            // wildcard topic
            dispatchMessageToCallbacks(cbByTopic.get("*"), sourceUuid, topic, message);
        }
    }

    private void dispatchMessageToCallbacks(List cbList, String sourceUuid, String topic, Object message) {
        if (cbList != null) {
            for (BusListener cb : cbList) {
                cb.onMessageReceived(sourceUuid, topic, message);
            }
        }
    }

    /**
     *  Registers a listener which is called whenever a subscription occurs.
     *  A function that is called whenever a subscription occurs.
     *  It is passed the topic and application UUID that trigered the event.
     * @param listener Listener to add
     */
    public void addSubscribeListener(SubscriptionListener listener)
    {
        subscribeListeners.add(listener);
    }

    /// 
    ///     Removes the passed listener.
    ///     It is no longer called for subscription events.
    /// 
    /// The listener to remove.

    /**
     *  Removes the passed listener.
     *  It is no longer called for subscription events.
     * @param listener Listener to remove
     */
    public void removeSubscribeListener(SubscriptionListener listener) {
        subscribeListeners.remove(listener);
    }

    /**
     *  Dispatches to subscription listeners
     * @param uuid The subscribing application
     * @param topic The topic that is subscribed to
     */
    void dispatchToSubscribeListeners(String uuid, String topic)
    {
        for (SubscriptionListener listener : subscribeListeners) {
            listener.subscribed(uuid, topic);
        }
    }

    /**
     * Dispatches to unsubscription listeners
     *
     * @param uuid The unsubscribing application
     * @param topic The topic that was subscribed to
     */
    ///     Dispatches to unsubscription listeners
    /// 
    /// The unsubscribing application.
    /// The topic that was unsubscribed from.
    void dispatchToUnsubscribeListeners(String uuid, String topic)
    {
        for (SubscriptionListener listener : subscribeListeners) {
            listener.unsubscribed(uuid, topic);
        }
    }

    /**
     * remove all registered listeners.
     */
    void reset() {
    	logger.info("remove all listeners");
    	this.subscribeListeners.clear();
    	this.callbackMap.clear();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy