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

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

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

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Creates instances of ExternalMessageResultHandler and sends the total result to the AppDesktop.
 *
 * @author wche
 * @since 4/30/14
 */

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

    private Map handlers = new HashMap();
    private DesktopConnection desktopConnection;
    private String uuid;
    private JSONObject request;               // The payload from the AppDesktop
    private boolean sentToDesktop = false;    // Has a result already been sent to the AppDesktop
    private int nHandlers = 0;            // The total number of ExternalMessageResultHandlers created
    private int nProcessed = 0;           // How many ExternalMessageResultHandler have set their success/fail result
    private boolean allDispatched = false;    // True when no more ExternalMessageResultHandlers are expected to be created.

    /**
     *
     * @param uuid The UUID of the DesktopConnection that owns this factory. Used for dispatching to the AppDesktop
     * @param desktopConnection for sending the success/fail result payload to the AppDesktop
     * @param request The payload from the AppDesktop
     */
    public ExternalMessageResultHandlerFactory(String uuid, DesktopConnection desktopConnection, JSONObject request) {
        this.request = request;
        this.desktopConnection = desktopConnection;
        this.uuid = uuid;
    }

    /**
     *
     * Sends the AND combination of all results and concetenated messages to the AppDesktop
     * if allDispatched() has been called and all result handlers have completed.
     *
     */
    private void sendIfAllResultsDispatchedAndComplete() {
        if (allDispatched && nProcessed == nHandlers) {
            // Default to success with no data
            boolean totalResult = true;
            String totalMessage = "";

            // If no result handlers have been created for this factory
            if (nHandlers == 0)  {
                totalResult = false;
                totalMessage = "No external message handler has been registered!";
            }
            // AND the result and concatenate messages from all result handlers.
            for (Map.Entry entry: handlers.entrySet()) {
                totalResult &= entry.getValue().result;
                totalMessage += entry.getValue().message;
            }
            // Send totalResult and totalMessage to the AppDesktop
            try {
                JSONObject payload = new JSONObject();
                payload.put("uuid", uuid);
                payload.put("connectionId", request.getInt("connectionId"));
                payload.put("result", totalResult);
                payload.put("message", totalMessage);
                String action = "external-message-result";
                this.desktopConnection.sendAction(action, payload);

                // Remember that the result has been sent to the desktop for this factory.
                sentToDesktop = true;
            } catch (Exception ex) {
                logger.error("Error", ex);
            }
        }
    }

    /**
     * Marks that no more result handlers will be created.
     * Sends result status to the AppDesktop immediately if all result handlers have already set their success/fail and messages.
     *
     */
    public synchronized void allDispatched() {
        this.allDispatched = true;
        this.sendIfAllResultsDispatchedAndComplete();
    }

    /**
     * Factory method to create and track a result handler
     * @return result handler
     */
    public synchronized ExternalMessageResultHandler makeResultHandler()  {
        ExternalMessageResultHandlerImpl requestHandler = new ExternalMessageResultHandlerImpl(this);
        handlers.put(requestHandler.getId(), new ResultHandlerMetaInfo());
        ++this.nHandlers;
        return requestHandler;
    }

    /**
     * Updates the stored meta information and sends to the container if all results have been received
     *
     * @param id UUID of the ExternalMessageResultHandler the result came from
     * @param result true for success, false for failure
     * @param message A string response to be sent back over HTTP/HTTPS
     * @return
     */
    public synchronized boolean handleResult(String id, boolean result, String message) {
        boolean handled = false;
        ResultHandlerMetaInfo handlerMetaInfo = this.handlers.get(id);
        if (!this.sentToDesktop && handlerMetaInfo != null && !handlerMetaInfo.processed) {
            // Update the meta information
            handlerMetaInfo.processed = true;
            handlerMetaInfo.result = result;
            handlerMetaInfo.message = message;
            // Track that the updates happened in the factory
            handled = true;
            ++this.nProcessed;
            this.sendIfAllResultsDispatchedAndComplete();
        }
        return handled;
    }

    private static class ResultHandlerMetaInfo {
        public boolean processed;  // True when the result handler has invoked send()
        public boolean result;     // The success/fail state
        public String message;  // Message set on send()

        public ResultHandlerMetaInfo() {
            processed = false;
            result = true;
            message = "";
        }
    }

    private static class ExternalMessageResultHandlerImpl implements ExternalMessageResultHandler {
        private String id;
        private boolean sent;
        private  ExternalMessageResultHandlerFactory externalMessageResultHandlerFactory;

        public ExternalMessageResultHandlerImpl(ExternalMessageResultHandlerFactory externalMessageResultHandlerFactory) {
            this.externalMessageResultHandlerFactory = externalMessageResultHandlerFactory;
            this.sent = false;
            this.id = UUID.randomUUID().toString();
        }

        public String getId() {
            return this.id;
        }


        @Override
        public boolean send(boolean result, String message) {
            boolean didSend = false;
            if (!this.sent) {
                this.sent = true;
                didSend = this.externalMessageResultHandlerFactory.handleResult(this.id, result, message);
            }
            return didSend;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy