Class Promise<RESPONSE,​RESULT>

  • Type Parameters:
    RESPONSE - This type is the 'Reponse Type' that is produced by the Asynchronous I/O. In the case of the WebSocket's Processor used by the Browser Remote Debugging Protocol, this type will always be JsonObject.

    The web-browser Remote Debugging Protocol solely uses JSON in those communications.
    RESULT - This type indicates the type used by return-value that's ultimately received by the user. This type is the class which is actually returned when a user makes a call to Promise.await().
    All Implemented Interfaces:
    java.io.Serializable

    public class Promise<RESPONSE,​RESULT>
    extends java.lang.Object
    implements java.io.Serializable
    A promise keeps the processing logic for converting a response from an asychronous connection into a result that the end-user can utilize.

    The three classes, Script, Promise and Sender are designed to allow for the creation of 'Asynchronous Scripts' that may be executed and made to appear to be synchronous through the Promise.await() method.

    These three classes are made use of in the Browser Remote Debugging Protocol Package. Theoretically, they could be used by any asynchronous communication system.
    See Also:
    Serialized Form


    • Method Summary

       
      Retrieve the Promise' State
      Modifier and Type Method
      Ret5<Boolean,
           ​Boolean,
           ​RESULT,
           ​Integer,
           ​String>
      getState()
      boolean hadError()
      boolean hadResponse()
       
      Report State to the Promise
      Modifier and Type Method
      void acceptError​(int errorCode, String errorMessage)
      void acceptResponse​(RESPONSE response)
       
      Await for Script Completion to get Promise Result
      Modifier and Type Method
      RESULT await()
       
      Retrieve the Promise Result
      Modifier and Type Method
      RESULT result()
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • serialVersionUID

        🡇    
        protected static final long serialVersionUID
        This fulfils the SerialVersion UID requirement for all classes that implement Java's interface java.io.Serializable. Using the Serializable Implementation offered by java is very easy, and can make saving program state when debugging a lot easier. It can also be used in place of more complicated systems like "hibernate" to store data as well.
        See Also:
        Constant Field Values
        Code:
        Exact Field Declaration Expression:
        protected static final long serialVersionUID = 1;
        
      • receiver

        🡅  🡇    
        public final java.util.function.Function<RESPONSE,​RESULT> receiver
        This is the "Respone Processor". As of the writing of this class, the only use that the three classes: Script, Promise & Sender has been for implementing the Google Chrome Browser Remote Debug Protocol. (Although perhaps these classes will one day be used with a different asychronous protocol) In this current case (Browser RDP), this receiver is actually doing the "JSON Binding" to bind the JsonObject received from the Browser into a Java Class that the user can actually use.
        Code:
        Exact Field Declaration Expression:
        public final Function<RESPONSE, RESULT> receiver;
        
    • Constructor Detail

      • Promise

        🡅  🡇    
        public Promise​(java.util.function.Function<RESPONSE,​RESULT> receiver)
        Constructing an instance of Promise only requires this response-processor (a.k.a. a 'receiver').
        Parameters:
        receiver - This receiver needs to be able to convert the raw asynchronous response - which is just a JsonObject when used by the Browser RDP Web-Socket Channel - into an instance of 'RESULT' that the end user can actually use.
    • Method Detail

      • hadError

        🡅  🡇    
        public boolean hadError()
        Asks 'this' instance of Promise whether or not an error has been reported.
        Returns:
        TRUE if there were errors reported by the asynchronous channel, and FALSE otherwise.
        Code:
        Exact Method Body:
         return error;
        
      • hadResponse

        🡅  🡇    
        public boolean hadResponse()
        Asks 'this' instance of Promise whether any response has been reported. This shall return TRUE if either an error, or a response has been received.
        Returns:
        TRUE if a response or an error has been reported to 'this' instance, and FALSE otherwise.
        Code:
        Exact Method Body:
         return response || error;
        
      • getState

        🡅  🡇    
        public Ret5<java.lang.Boolean,​java.lang.Boolean,​RESULT,​java.lang.Integer,​java.lang.String> getState
                    ()
        
        Gets all current-state of this Promise
        Returns:
        The current state of this Promise, as an instance of Ret5.

        • Ret5.a (Boolean):
          Whether or not a response has been reported

        • Ret5.b (Boolean):
          Whether or not an error has been reported

        • Ret5.c (RESULT):
          The result that has been returned, or null no result has been received

        • Ret5.d (Integer):
          The error-code that was received, or 0 if no errors have been reported

        • Ret5.e (String):
          The error-message (if an error was reported), or null.
        Code:
        Exact Method Body:
         return new Ret5<>(response, error, result, errorCode, errorMessage);
        
      • result

        🡅  🡇    
        public RESULT result()
        This allows a user to retrieve the result of 'this' asynchronous Promise. Note that if no result has been received yet, this method throws an exception.
        Returns:
        The result of the asynchronous call.
        Throws:
        AynchronousException - This throws if this Promise has not received a result yet.
        Code:
        Exact Method Body:
         if (! response) throw new AsynchronousException("No response has been received yet");
         return result;
        
      • acceptResponse

        🡅  🡇    
        public final void acceptResponse​(RESPONSE response)
        When building a communication-system that uses these Script & Promise classes, that system needs to invoke 'acceptResponse' whenever a server-response has been received.

        With a WebSocket connection to a Web-Browser via the Remote Debugging Port, mapping the response & request is done by checking the request-ID, and keeping a mapping of ID => "un-answered Promise Objects."
        Parameters:
        response - The response received from the communications channel, Web-Socket, browser etc...
        Code:
        Exact Method Body:
         if (this.error) throw new AsynchronousException(
             "This Promise cannot accept a response object because it has already received " +
             "an rrror.  Current Error Code: [" +
             this.errorCode + "]" +
             ((errorMessage != null) ? ("\nCurrent Error Message: \"" + errorMessage + "\"") : "")
         );
        
         if (this.response) throw new AsynchronousException
             ("This Promise has already received a response.  A second response is not allowed.");
        
         this.result     = receiver.apply(response);
         this.response   = true;
        
      • acceptError

        🡅  🡇    
        public final void acceptError​(int errorCode,
                                      java.lang.String errorMessage)
        If an error occurs in communications-channel logic, that error may be reported to this Promise by calling 'acceptError'.
        Parameters:
        errorCode - A meaningful error-code.
        errorMessage - A meaningful error-message
        Throws:
        AsynchronousException - If 'this' instance of 'Promise' has already received an error (via 'acceptError'), or if 'this' has accepted a response (via acceptResponse(Object)).
        Code:
        Exact Method Body:
         if (this.error) throw new AsynchronousException(
             "There has already been an error reported to this Promise.  Current Error Code: [" +
             this.errorCode + "]" +
             ((errorMessage != null) ? ("\nError Message: \"" + errorMessage + "\"") : "")
         );
        
         if (this.response) throw new AsynchronousException
             ("This Promise has already received a response.  It is too late to report an error.");
        
         this.error          = true;
         this.errorCode      = errorCode;
         this.errorMessage   = errorMessage;
        
      • await

        🡅    
        public final RESULT await()
        This method will cede the current Thread's control until the Asynchronous Channel has called this class' acceptResponse(Object) method.
        Returns:
        Once 'this' instance of 'Promise' has been notified of a result, it will return that result, as an instance of Type-Parameter 'RESULT'.
        Throws:
        AsynchronousException - If a java.lang.InterruptedException is thrown while awating this Promise, that exception will be wrapped into an instance of 'AsynchronousException', and then thrown. This wrapper-exception is an un-checked, RuntimeException.
        Code:
        Exact Method Body:
         try
         {
             while ((result == null) && (errorCode == 0)) this.wait();
             return result;
         }
         catch (InterruptedException e)
         {
             throw new AsynchronousException
                 ("While awaiting this Promise, an InterruptedException was thrown", e);
         }