Class AbstractHTMLContext
- java.lang.Object
-
- de.aristaflow.adept2.ui.htmlgui.AbstractHTMLContext
-
- All Implemented Interfaces:
GUIContext
,HTMLContext
,HTTPReplyHandler
,Closeable
,AutoCloseable
- Direct Known Subclasses:
RemoteHTMLContext
,SwtHtmlContext
public abstract class AbstractHTMLContext extends Object implements HTMLContext, HTTPReplyHandler
ThisGUIContext
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 viagetResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply)
while the application sets the corresponding response viasetResponse(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 viagetResponse(de.aristaflow.adept2.ui.htmlgui.HTMLContext.HTTPReply)
called by the browser request andsetResponse(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()
andgetRelativeLink(Map)
), otherwise the requests from the browser cannot be assigned to this context. The created initial HTML-content can be set viasetInitialContent(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 viagetResponse(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 viagetResponse(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 viasetResponse(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 Classes Modifier and Type Class Description protected static class
AbstractHTMLContext.HtmlContextCleanupTask
The 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
Fields Modifier and Type Field Description protected URL
baseURL
Deprecated.UserelRes
instead.protected Cleanup<RuntimeException>
cleanup
The clean-up for closing all replies and responses of anAbstractHTMLContext
.static HTMLContext.Response
DEFAULT_FINAL_RESPONSE
A response that can be used as default for the final response.protected 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.protected HTTPService
httpService
The HTTP service for deregistering this reply handler.protected String
initialContentString
The initial HTML-content.protected Logger
logger
My logger.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.protected Map<HTMLContext.HTTPReply,CountDownLatch>
replies
All replies that are currently pending and waiting for a response.protected boolean
replyHandlerTerminated
Whether the reply handler (the component executing thread) has terminated and does not process any more HTTP-requests any more.protected 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.protected String
sessionID
The ID of the session in which the GUI context is needed (required for deregistering this reply handler).protected WeakReference<Thread>
thread
The thread which executes the application using this context.
To avoid memory leaks this is just a weak reference.
-
Constructor Summary
Constructors Constructor Description AbstractHTMLContext(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
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected void
checkForValidExecutorThread()
Checks if the method is called by the main thread of the application.protected void
close(SessionToken session)
String
getRelativeLink()
Gets the path relative to the server resource corresponding to this context.String
getRelativeLink(Map<String,String> query)
Gets the path relative to the server resource corresponding to this context.HTMLContext.Response
getResponse(HTMLContext.HTTPReply reply)
Provides the reply handler with the parameters retrieved by the HTTP-request.URL
getURL()
Gets the URL which the server provides for responses and signals to the executed application corresponding to this context.URL
getURL(Map<String,String> query)
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 '?')void
setBaseURL(URL baseURL)
Sets the base URL on which the reply handler is reachable via HTTP.void
setBaseURL(URL baseURL, String resName)
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).void
setFinalResponse(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 void
setFinalResponse(HTMLContext.Response response, boolean checkThread)
Sets the final response to the designated one and optionally checks for the valid executor thread.void
setInitialContent(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.void
setResponse(HTMLContext.HTTPReply reply, HTMLContext.Response response)
Responds to the designated reply that has been received viaHTMLContext.waitForHTTPReply(long)
.HTMLContext.HTTPReply
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, wait
-
Methods inherited from interface de.aristaflow.adept2.ui.htmlgui.HTMLContext
close
-
-
-
-
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.UserelRes
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
-
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 afinalResponse
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 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 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 viaHTMLContext.waitForHTTPReply(long)
.
AnInvalidExecutorThreadException
will be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
getURL
in interfaceHTMLContext
- 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 viaHTMLContext.waitForHTTPReply(long)
.
AnInvalidExecutorThreadException
will be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
getRelativeLink
in interfaceHTMLContext
- 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 &.
AnInvalidExecutorThreadException
will be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
getURL
in interfaceHTMLContext
- 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 &.
AnInvalidExecutorThreadException
will be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
getRelativeLink
in 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
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 providedURL
and 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.
AnInvalidExecutorThreadException
will be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
setInitialContent
in interfaceHTMLContext
- 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 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 AnInvalidExecutorThreadException
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 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 thisHTMLContext
is 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
public void setFinalResponse(HTMLContext.Response response)
Description copied from interface:HTMLContext
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. 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.
AnInvalidExecutorThreadException
will be thrown if the method is not called by the main thread of the corresponding component.- Specified by:
setFinalResponse
in 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
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 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
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 theRuntimeEnvironment
by failing.
AnInvalidExecutorThreadException
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 interfaceHTMLContext
- 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 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, anInterruptedException
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 aInvalidExecutorThreadException
is thrown.- Throws:
InvalidExecutorThreadException
- If the current thread is not the dedicated thread for the component execution, aInvalidExecutorThreadException
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 interfaceHTTPReplyHandler
- 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 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
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 anInterruptedException
to indicate an exceptional situation which will not be responded to by this handler.- Specified by:
getResponse
in 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, anInterruptedException
will be thrown.
-
-