Class AbstractHTMLContext
- All Implemented Interfaces:
GUIContext,HTMLContext,HTTPReplyHandler,Closeable,AutoCloseable
- Direct Known Subclasses:
RemoteHTMLContext,SwtHtmlContext
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.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static final classThe clean-up task for closing all replies and responses of anAbstractHTMLContext.Nested classes/interfaces inherited from interface de.aristaflow.adept2.ui.htmlgui.HTMLContext
HTMLContext.Attachment, HTMLContext.CloseIgnoringAttachment, HTMLContext.HTTPReply, HTMLContext.Response -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected URLThe 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.protected final Cleanup<RuntimeException>The clean-up for closing all replies and responses of anAbstractHTMLContext.static final HTMLContext.ResponseA response that can be used as default for the final response.protected final org.apache.commons.lang3.mutable.Mutable<HTMLContext.Response>The final response that will be used for all HTTP-request after the reply handler has been shut down.protected final HTTPServiceThe HTTP service for deregistering this reply handler.protected StringThe initial HTML-content.protected final LoggerMy logger.protected StringThe 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.protected final Map<HTMLContext.HTTPReply,CountDownLatch> All replies that are currently pending and waiting for a response.protected booleanWhether the reply handler (the component executing thread) has terminated and does not process any more HTTP-requests any more.protected final Map<HTMLContext.HTTPReply,HTMLContext.Response> All responses that are currently set for the corresponding reply and are waiting for the corresponding replying thread to get them.protected final StringThe ID of the session in which the GUI context is needed (required for deregistering this reply handler).protected final WeakReference<Thread>The thread which executes the application using this context.
To avoid memory leaks this is just a weak reference. -
Constructor Summary
ConstructorsConstructorDescriptionAbstractHTMLContext(Thread thread) Creates a new abstract HTML context providing the usual behaviour needed for an HTML context.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. -
Method Summary
Modifier and TypeMethodDescriptionprotected voidChecks if the method is called by the main thread of the application.protected voidclose(SessionToken session) Gets the path relative to the server resource corresponding to this context.getRelativeLink(Map<String, String> query) Gets the path relative to the server resource corresponding to this context.getResponse(HTMLContext.HTTPReply reply) Provides the reply handler with the parameters retrieved by the HTTP-request.voidsetBaseURL(URL baseURL, String resName) Sets the base URL on which the reply handler is reachable via HTTP and the corresponding resource name, i.voidsetFinalResponse(HTMLContext.Response response) Sets the designated response as feedback to currently open replies from previous calls toHTMLContext.waitForHTTPReply(long)and/or as general response for all following requests.protected final voidsetFinalResponse(HTMLContext.Response response, boolean checkThread) Sets the final response to the designated one and optionally checks for the valid executor thread.voidsetInitialContent(String initialContent) 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.voidsetResponse(HTMLContext.HTTPReply reply, HTMLContext.Response response) Responds to the designated reply that has been received viaHTMLContext.waitForHTTPReply(long).waitForHTTPReply(long timeout) Waits for the reply of the client sent as response to the provided HTML-document.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface de.aristaflow.adept2.ui.htmlgui.HTMLContext
close
-
Field Details
-
DEFAULT_FINAL_RESPONSE
A response that can be used as default for the final response. -
logger
My logger. -
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
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
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
-
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
All responses that are currently set for the corresponding reply and are waiting for the corresponding replying thread to get them. -
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 replyHandlerTerminatedWhether the reply handler (the component executing thread) has terminated and does not process any more HTTP-requests any more. In this case there is afinalResponsethat applies to all following requests.
As soon as this flag is set, no further replies will be enqueued. -
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). -
cleanup
The clean-up for closing all replies and responses of anAbstractHTMLContext. 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 Details
-
AbstractHTMLContext
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
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 Details
-
getRelativeLink
Description copied from interface:HTMLContextGets 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 viaHTMLContext.waitForHTTPReply(long).
AnInvalidExecutorThreadExceptionwill be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
getRelativeLinkin interfaceHTMLContext- Returns:
- The string identifying the server resource of this context for submitting data from the HTML-content back to the application.
-
getRelativeLink
Description copied from interface:HTMLContextGets 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 &.
AnInvalidExecutorThreadExceptionwill be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
getRelativeLinkin interfaceHTMLContext- 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
Description copied from interface:HTMLContextSets 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 providedURLand byHTMLContext.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.
AnInvalidExecutorThreadExceptionwill be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
setInitialContentin interfaceHTMLContext- Parameters:
initialContent- The content of this HTML-context, that is the user-interface in HTML for the executed application.
-
setResponse
Description copied from interface:HTMLContextResponds to the designated reply that has been received viaHTMLContext.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 AnInvalidExecutorThreadExceptionwill 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:
setResponsein interfaceHTMLContext- 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 byHTMLContext.waitForHTTPReply(long)in which case thisHTMLContextis responsible for closing.response- The response to send back to the user as response to the values provided byHTMLContext.waitForHTTPReply(long). The HTMLContext.Response will be coupled to thisHTMLContext, so do not close it; clone it if required longer than thisHTMLContext.
-
setFinalResponse
Description copied from interface:HTMLContextSets the designated response as feedback to currently open replies from previous calls toHTMLContext.waitForHTTPReply(long)and/or as general response for all following requests. This method indicates that no further requests (normally received byHTMLContext.waitForHTTPReply(long)) will be accepted and processed. Instead all requests will receive the designated response.
Note that other thanHTMLContext.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.
AnInvalidExecutorThreadExceptionwill be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
setFinalResponsein interfaceHTMLContext- 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
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
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 fromHTMLContext.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 fromHTMLContext.close()the thread must not be checked.
-
waitForHTTPReply
Description copied from interface:HTMLContextWaits 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,nullwill 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 theRuntimeEnvironmentby failing.
AnInvalidExecutorThreadExceptionwill 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:
waitForHTTPReplyin interfaceHTMLContext- Parameters:
timeout- The time (in milliseconds) to wait for a HTTP-request. If the timeout elapsed before a request has been received,nullwill 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
nullif the timeout occurred or the final response has already been set. The HTMLContext.HTTPReply will be coupled to thisHTMLContext, so do not close it; clone it if required longer than thisHTMLContext. - Throws:
InterruptedException- If the waiting thread is interrupted due to a signal sent by the runtime environment, anInterruptedExceptionwill 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 aInvalidExecutorThreadExceptionis thrown.- Throws:
InvalidExecutorThreadException- If the current thread is not the dedicated thread for the component execution, aInvalidExecutorThreadExceptionwill be thrown.
-
setBaseURL
Description copied from interface:HTTPReplyHandlerSets 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:
setBaseURLin interfaceHTTPReplyHandler- 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
Description copied from interface:HTTPReplyHandlerProvides 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 anInterruptedExceptionto indicate an exceptional situation which will not be responded to by this handler.- Specified by:
getResponsein interfaceHTTPReplyHandler- 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, anInterruptedExceptionwill be thrown.
-