Class AbstractHTMLContext

  • All Implemented Interfaces:
    GUIContext, HTMLContext, HTTPReplyHandler, Closeable, AutoCloseable
    Direct Known Subclasses:
    RemoteHTMLContext, SwtHtmlContext

    public abstract class AbstractHTMLContext
    extends Object
    implements HTMLContext, HTTPReplyHandler
    This GUIContext enables the usage of HTML as graphical user interface. Due to the synchronous, user-initiated communication protocol (HTTP) used with HTML, the methods and usage of this context differs from other GUI-contexts: Clients (a browser) send requests which will be processed by the server (the application using the context) and responded to. This strict request-response-protocol has to be respected.
    Requests will be retrieved via getResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply) while the application sets the corresponding response via setResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply, de.aristaflow.adept2.ui.htmlgui.HTMLContext.Response) . However, there are two special cases: The initial content which is a response that can to be set before the corresponding request has arrived, and the final response which needs to be set when the application terminates. All other communication will take place via getResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply) called by the browser request and setResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply, de.aristaflow.adept2.ui.htmlgui.HTMLContext.Response). Meanwhile the application just waits for requests from the browser until either the timeout occurs or the corresponding thread is interrupted for instance due to a signal from the outside.

    As always, the GUI of an application needs to be created when initialising the application. In case of an application using this context, the GUI will be HTML, for instance an HTML-form. This usually contains several URLs at least one for returning the data entered in the form. The application has to use the relative URLs returned by this context (getRelativeLink() and getRelativeLink(Map)), otherwise the requests from the browser cannot be assigned to this context. The created initial HTML-content can be set via setInitialContent(String) and the application can finish its initialisation. Since the strict request-response-protocol also applies to the initial content, the browser to show the created HTML needs to request it initially. Usually the browser will have a URL to GET the HTML, the content may also be provided directly by a get-method of (a subclass of) this context or by the application as response to an empty client request via getResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply). However, when setting the initial content via this class, the initial content will be used as the response to the very first request (received via getResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply).
    When running, the application usually just waits for requests from the browser. As soon as a request arrives, the application will be provided with the corresponding data. It then needs to create an appropriate response and provide this to the browser via setResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply, de.aristaflow.adept2.ui.htmlgui.HTMLContext.Response). The thread providing the browser request is blocked until the response is available.
    This HTML context allows for sophisticated request-response-scenarios for instance keeping requests from the browser unresponded when using Ajax. Therefore multiple requests need to be handled concurrently which requires to provide the reply when setting the response. Otherwise this context cannot correlate the response to the corresponding request.
    When waiting for a request from the browser, the application thread will be interrupted in case of a signal from the runtime environment to the application. Additionally, it will stop waiting when the provided timeout elapsed. This allows for instance to support a keep alive protocol to check whether the browser has been terminated meanwhile. In this case the application does not need to wait any longer since its UI has been vanished (on client-side).

    However, signals from the runtime environment (for instance a kill signal) lead to a sudden end of the application but the UI will not be notified (since the application cannot contact the UI except by responding to a request). Therefore the application should always set a final response before finally terminating. This response will be used for all requests arriving afterwards. It will not be closeable from the users but will be closed when closing this context.

    As always, methods called from the application will check for the right executing thread and will throw an InvalidExecutorThreadException if this is not the case.

    Subclasses need to provide a method for closing the HTML context. Additionally, they can override any method. This can be useful for instance to provide a special handling of the initial content.

    • Field Detail

      • DEFAULT_FINAL_RESPONSE

        public static final HTMLContext.Response DEFAULT_FINAL_RESPONSE
        A response that can be used as default for the final response.
      • logger

        protected final Logger logger
        My logger.
      • thread

        protected final WeakReference<Thread> thread
        The thread which executes the application using this context.
        To avoid memory leaks this is just a weak reference. The reference will be valid while the thread is running. Afterwards this GUI context becomes irrelevant.
      • baseURL

        @Deprecated
        protected URL baseURL
        Deprecated.
        Use relRes instead.
        The base URL for this HTML context which is a URL relative to the HTTP-service handling the HTTP-requests (containing the reply data) sent to this context.
      • relRes

        protected String relRes
        The relative path to the base resource for this HTML context which is a URL relative to the HTTP-service handling the HTTP-requests (containing the reply data) sent to this context.
      • initialContentString

        protected String initialContentString
        The initial HTML-content. This will be sent as response to the first request after replacing all baseURL with relRes.
      • replies

        protected final Map<HTMLContext.HTTPReply,​CountDownLatch> replies
        All replies that are currently pending and waiting for a response. The latches are used for signalling the replying threads that their response is available.
        This object is also used for notifying the reply handler (the component executing thread) of new replies.
      • responses

        protected final Map<HTMLContext.HTTPReply,​HTMLContext.Response> responses
        All responses that are currently set for the corresponding reply and are waiting for the corresponding replying thread to get them.
      • finalResponse

        protected final org.apache.commons.lang3.mutable.Mutable<HTMLContext.Response> finalResponse
        The final response that will be used for all HTTP-request after the reply handler has been shut down. This is null while the reply handler has not shut down yet.
      • replyHandlerTerminated

        protected volatile boolean replyHandlerTerminated
        Whether the reply handler (the component executing thread) has terminated and does not process any more HTTP-requests any more. In this case there is a finalResponse that applies to all following requests.
        As soon as this flag is set, no further replies will be enqueued.
      • httpService

        protected final HTTPService httpService
        The HTTP service for deregistering this reply handler.
      • sessionID

        protected final String sessionID
        The ID of the session in which the GUI context is needed (required for deregistering this reply handler).
      • cleanup

        protected final Cleanup<RuntimeException> cleanup
        The clean-up for closing all replies and responses of an AbstractHTMLContext. This will not be called explicitly to allow requestors to get the final response even after the corresponding GUI context has been closed.
        Subclasses needing a separate cleanup have to register it separately.
    • Constructor Detail

      • AbstractHTMLContext

        public AbstractHTMLContext​(Thread thread)
        Creates a new abstract HTML context providing the usual behaviour needed for an HTML context.
        Parameters:
        thread - The thread which executes the application using this context.
        We must not keep a strong reference to this thread! Otherwise memory leaks may occur.
      • AbstractHTMLContext

        public AbstractHTMLContext​(Thread thread,
                                   HTTPService httpService,
                                   String sessionId)
        Creates a new abstract HTML context providing the usual behaviour needed for an HTML context including deregistering from a reply handler.
        Parameters:
        thread - The thread which executes the application using this context.
        We must not keep a strong reference to this thread! Otherwise memory leaks may occur.
        httpService - The HTTP service for deregistering this reply handler.
        sessionId - The ID of the session in which the GUI context is needed (required for deregistering this reply handler).
    • Method Detail

      • getURL

        public URL getURL()
        Description copied from interface: HTMLContext
        Gets the URL which the server provides for responses and signals to the executed application corresponding to this context. For instance, the generated HTML-content may provide data via HTTP-POST or HTTP-GET to this URL. The data is handled by the server and provided via HTMLContext.waitForHTTPReply(long).
        An InvalidExecutorThreadException will be thrown if the method is not called by the main thread of the corresponding component.
        Specified by:
        getURL in interface HTMLContext
        Returns:
        The URL for submitting data from the HTML-content back to the application.
      • getRelativeLink

        public String getRelativeLink()
        Description copied from interface: HTMLContext
        Gets the path relative to the server resource corresponding to this context. This allows for relative links sending HTTP requests to this context, i. e. responses and signals to the executed application corresponding to this context. For instance, the generated HTML-content may provide data via HTTP-POST or HTTP-GET to this (relative) URL. The data is handled by the server and provided via HTMLContext.waitForHTTPReply(long).
        An InvalidExecutorThreadException will be thrown if the method is not called by the main thread of the corresponding component.
        Specified by:
        getRelativeLink in interface HTMLContext
        Returns:
        The string identifying the server resource of this context for submitting data from the HTML-content back to the application.
      • getURL

        public URL getURL​(Map<String,​String> query)
        Description copied from interface: HTMLContext
        Gets the URL which the server provides for responses and signals to the executed application corresponding to this URL context appended by the designated string map as URL query (after a '?'), that is the key and value-pairs are appended and separated by &.
        An InvalidExecutorThreadException will be thrown if the method is not called by the main thread of the corresponding component.
        Specified by:
        getURL in interface HTMLContext
        Parameters:
        query - Key-value-pairs to be appended as query to the URL for responses and signals to the executed application. The strings for keys and values will be encoded appropriately for usage in a URL.
        Returns:
        The URL for submitting data from the HTML-content back to the application appended by the designated query-string.
        See Also:
        HTMLContext.getURL()
      • getRelativeLink

        public String getRelativeLink​(Map<String,​String> query)
        Description copied from interface: HTMLContext
        Gets the path relative to the server resource corresponding to this context. This allows for relative links sending HTTP requests to this context, i. e. responses and signals to the executed application corresponding to this context. The relative link will be prepended by the designated URL query (after a '?'), that is the key and the value pars are appended by &.
        An InvalidExecutorThreadException will be thrown if the method is not called by the main thread of the corresponding component.
        Specified by:
        getRelativeLink in interface HTMLContext
        Parameters:
        query - Key-value-pairs to be appended as query to the relative path for responses and signals to the executed application. The strings for keys and values will be encoded appropriately for usage in a (relative) URL.
        Returns:
        The string identifying the server resource of this context for submitting data from the HTML-content back to the application appended by the designated query-string.
      • setInitialContent

        public void setInitialContent​(String initialContent)
        Description copied from interface: HTMLContext
        Sets the initial (HTML-)content of this context, that is the designated content is sent as response to the first to the client for visualising the executed application. Feedback/data can be retrieved via the usage of the provided URL and by HTMLContext.waitForHTTPReply(long).
        The content is only provided once. Afterwards, HTMLContext.setResponse(HTTPReply, Response) has to be used for sending HTML to the user. If you want to set the initial content, be sure to set it before the first request arrives! However, you need not set it here, you can also provide it to a received empty request.
        An InvalidExecutorThreadException will be thrown if the method is not called by the main thread of the corresponding component.
        Specified by:
        setInitialContent in interface HTMLContext
        Parameters:
        initialContent - The content of this HTML-context, that is the user-interface in HTML for the executed application.
      • setResponse

        public void setResponse​(HTMLContext.HTTPReply reply,
                                HTMLContext.Response response)
        Description copied from interface: HTMLContext
        Responds to the designated reply that has been received via HTMLContext.waitForHTTPReply(long). The response can be a simple HTML-document indicating the successful completion of the activity, some HTML as response to an Ajax-request or even the complete HTML again, that has been initially sent, in case of missing values.
        Providing the reply here again allows to handle several HTTP-requests concurrently and send responses to the corresponding replies in an arbitrary order. However, each reply waits for an appropriate response. Therefore make sure to set a response for each retrieved reply (HTTP-request).
        If the reply handler An InvalidExecutorThreadException will be thrown if the method is not called by the main thread of the corresponding component.
        This method does not wait for the server to accept the reply. Rather the reply is sent as the next reply to a HTTP-request.
        Specified by:
        setResponse in interface HTMLContext
        Parameters:
        reply - The reply to which the designated response should be assigned. This allows to handle several replies concurrently and send responses in an arbitrary order. The caller is responsible for closing, however, usually this is provided by HTMLContext.waitForHTTPReply(long) in which case this HTMLContext is responsible for closing.
        response - The response to send back to the user as response to the values provided by HTMLContext.waitForHTTPReply(long). The HTMLContext.Response will be coupled to this HTMLContext, so do not close it; clone it if required longer than this HTMLContext.
      • setFinalResponse

        public void setFinalResponse​(HTMLContext.Response response)
        Description copied from interface: HTMLContext
        Sets the designated response as feedback to currently open replies from previous calls to HTMLContext.waitForHTTPReply(long) and/or as general response for all following requests. This method indicates that no further requests (normally received by HTMLContext.waitForHTTPReply(long)) will be accepted and processed. Instead all requests will receive the designated response.
        Note that other than HTMLContext.setResponse(HTTPReply, Response) the response here must not be null!

        Be sure to call this method if you do not intend to process another request! Afterwards you must not wait for another reply since all replies will be responded to with the response set here.
        An InvalidExecutorThreadException will be thrown if the method is not called by the main thread of the corresponding component.

        Specified by:
        setFinalResponse in interface HTMLContext
        Parameters:
        response - The response to send back as general response to all outstanding and all following requests. The response will be closed after the creation.
      • close

        protected void close​(SessionToken session)
        Closes this HTML context by deregistering it from reply handling and closing all replies and responses.
        Parameters:
        session - The session token with which to deregister this HTML context.
      • setFinalResponse

        protected final void setFinalResponse​(HTMLContext.Response response,
                                              boolean checkThread)
        Sets the final response to the designated one and optionally checks for the valid executor thread. Not checking the thread is required for setting the final response from HTMLContext.close() since closing is usually not called from the executor thread.
        Parameters:
        response - The response to send back as general response to all outstanding and all following requests. The response will be closed after setting.
        checkThread - Whether to check for the valid executor thread. Usually this should be done. Only when setting from HTMLContext.close() the thread must not be checked.
      • waitForHTTPReply

        public HTMLContext.HTTPReply waitForHTTPReply​(long timeout)
                                               throws InterruptedException
        Description copied from interface: HTMLContext
        Waits for the reply of the client sent as response to the provided HTML-document. The calling thread blocks until the response arrived, a signal for the component was sent or a timeout happened. In case of the signal, the calling thread is interrupted. It should then check for signals in the environment ( RuntimeEnvironment.dispatch() ). If no signal is set, it should just reenter this method.
        In case of a timeout, null will be returned and the calling thread can handle this appropriately. The timeout allows the component to be notified in case the client showing the HTML-document is not responding. It may then signal this to the RuntimeEnvironment by failing.
        An InvalidExecutorThreadException will be thrown if the method is not called by the main thread of the corresponding component.

        Do not forget so set an appropriate response after retrieval of the reply. Since the data for the reply is sent via a HTTP-request, a corresponding response is needed. Otherwise the corresponding request will be left unanswered.
        An empty reply (not having any parameters or attachments) indicates a request for the complete initial or rather the complete current HTML.

        Specified by:
        waitForHTTPReply in interface HTMLContext
        Parameters:
        timeout - The time (in milliseconds) to wait for a HTTP-request. If the timeout elapsed before a request has been received, null will be returned.
        Returns:
        The reply sent by the client. This contains key-value-pairs or even lists of values, the values being either simple strings or attachments (binary data and/or file uploads) sent via the GET- and POST-method. The maps of the reply will be empty if the client does not send a reply. The reply will be null if the timeout occurred or the final response has already been set. The HTMLContext.HTTPReply will be coupled to this HTMLContext, so do not close it; clone it if required longer than this HTMLContext.
        Throws:
        InterruptedException - If the waiting thread is interrupted due to a signal sent by the runtime environment, an InterruptedException will be thrown.
      • checkForValidExecutorThread

        protected void checkForValidExecutorThread()
        Checks if the method is called by the main thread of the application. In case of a wrong thread, a severe message is logged and a InvalidExecutorThreadException is thrown.
        Throws:
        InvalidExecutorThreadException - If the current thread is not the dedicated thread for the component execution, a InvalidExecutorThreadException will be thrown.
      • setBaseURL

        public void setBaseURL​(URL baseURL)
        Description copied from interface: HTTPReplyHandler
        Sets the base URL on which the reply handler is reachable via HTTP. Further parameters can be arbitrarily added by the activity, as long as the resulting URL is valid.
        Specified by:
        setBaseURL in interface HTTPReplyHandler
        Parameters:
        baseURL - The URL on which this reply handler is reachable via HTTP.
      • setBaseURL

        public void setBaseURL​(URL baseURL,
                               String resName)
        Description copied from interface: HTTPReplyHandler
        Sets the base URL on which the reply handler is reachable via HTTP and the corresponding resource name, i. e. the last element of the URL path (before query parameters). Further parameters can be arbitrarily added by the activity, as long as the resulting URL is valid.
        Specified by:
        setBaseURL in interface HTTPReplyHandler
        Parameters:
        baseURL - The URL on which this reply handler is reachable via HTTP.
        resName - The resource name from the URL, i. e. the last element of its path (before query parameters), e. g. index.html (without leading slash).
      • getResponse

        public HTMLContext.Response getResponse​(HTMLContext.HTTPReply reply)
                                         throws InterruptedException
        Description copied from interface: HTTPReplyHandler
        Provides the reply handler with the parameters retrieved by the HTTP-request. A response is expected which is sent to the client. This can be an acknowledge message, an error message or even the complete HTML-document again in case of missing values.
        This methods blocks and therefore may throw an InterruptedException to indicate an exceptional situation which will not be responded to by this handler.
        Specified by:
        getResponse in interface HTTPReplyHandler
        Parameters:
        reply - The parameters sent by the HTTP-client to the URL of this handler. This must not be null! The caller is responsible for closing.
        Returns:
        The response to the parameters which is sent back to the HTTP-client. This is never null. The caller is responsible for closing.
        Throws:
        InterruptedException - If the waiting thread is interrupted and should no longer wait for a response, an InterruptedException will be thrown.