DataType - the type of the data to be accessed. This type is strongly
recommended to be immutable or effectively immutable.public interface AsyncDataLink<DataType>
Instances of AsyncDataLink usually only need to store the input
needed to find the actual data. For example: A AsyncDataLink intended
to load a particular file, needs to store the path to the file only. And
later load the content of the file when requested to do so.
The link to the data is intended to be permanent, so users should not hope that the underlying data will change. Note however, that sometimes it is impossible to the implementation to guarantee that it will provide the same data always when requested.
To combine AsyncDataLink instances see the useful utility methods in
AsyncLinks.
AsyncDataLink, it needs to invoke the
getData
method and provide a listener to which the data will be forwarded when ready.
The data need to forwarded by calling the
onDataArrive method of the
listener passing the data as an argument.
The data is intended to be provided iteratively with each progress providing a more accurate or simply a super set of the previously provided data. Providing possibly incomplete data however is optional and implementations may only provide the final complete data. However providing the final data is mandatory (unless when providing the data is canceled). The intention of this definition is that when a new data is forwarded to the listener, previously provided datas can be safely ignored and be discarded.
It is important to note that the datas must be provided one after another and must never be forwarded concurrently to the same listener. This is because listeners are not required to be thread-safe.
As an example when a AsyncDataLink implementation loads an image
based on a file path it can iteratively forward an incomplete image until
all the pixels of the image was loaded. Once the image has been loaded: the
final complete image must be forwarded to the listener.
The data retrieval process can be canceled when the requested data is no
longer needed. Cancellation requests are detected through the passed
CancellationToken. Note that implementation may ignore cancellation
attempts but good implementations should at least make a best attempt to
stop retrieving the requested data.
onDoneReceive method
of the listener. The report can contain an exception as well to describe the
failure which may have occurred. Note that once the client requested the
data to be loaded, it is mandatory for every AsyncDataListener
implementation to sooner or later call the onDoneReceive method.
AsyncDataController object and also query the current progress of
the loading process. Controlling the loading process is done by sending an
object through the controlData
method of the returned AsyncDataController. How and what can be
controlled is completely implementation dependant but it most not affect the
final data to be forwarded to the listener. It may affect the time needed to
provide the final data but not the actual result. Note that due to some
sources being unreliable, this may not be achievable but a best effort must
be done to adhere to this contract. Controlling the data is merely intended
to be used to affect intermediate datas.
The second generic feature of the AsyncDataController is that it can
be used to retrieve the current status of the loading process. The most
important property of this status is the estimated progress of loading
process. Implementations however are recommended to provide other valuable
information about the progress.
AsyncDataLink and AsyncDataQuery instances can be
attached in a convoluted way, it can be very helpful if the
toString() method returns a human readable string
describing what the AsyncDataLink will do. The string representation
is not intended to be parsed or even be parsable it is only intended to
contain helpful information when debugging an application. To be consistent
with the string representation provided by implementations in JTrim,
the following guidelines should be used:
AsyncDataLink or AsyncDataQuery wraps another
query, the string representation of the subquery or sublink should be
indented. The indentations should be done using the appendIndented
methods of the AsyncFormatHelper class.
AsyncFormatHelper contains methods to format them so.
AsyncFormatHelper should be used whenever possible
for better consistency.
getData method must return reasonably
fast, must never do expensive tasks synchronously and especially not depend
on some external resources.| Modifier and Type | Method and Description |
|---|---|
AsyncDataController |
getData(CancellationToken cancelToken,
AsyncDataListener<? super DataType> dataListener)
Starts retrieving the data which is linked to this
AsyncDataLink. |
AsyncDataController getData(CancellationToken cancelToken, AsyncDataListener<? super DataType> dataListener)
AsyncDataLink.
The data will be forwarded to the specified listener usually
asynchronously on a separate thread. Note however that this method may
also forward the data synchronously on the current thread to the listener
if it is readily available and does not need some expensive operation to
load.
Once this method has been called successfully, the
onDoneReceive method
of the listener must be called eventually regardless what happens.
Failing to call this method is a serious failure of the
AsyncDataLink implementation.
cancelToken - the CancellationToken signaling if the data
retrieval process need to be canceled. Implementations may ignore
cancellation requests but they should cancel the data retrieval and
call the onDoneReceive method of the listener, signaling that
the data retrieval cannot be completed due to cancellation. This
argument cannot be null.dataListener - the listener to which the data is to be forwarded.
This argument cannot be null.AsyncDataController which can be used to
control the way it is being loaded and request the progress of the
data retrieving process. This method must never return null.NullPointerException - thrown if the specified listener or the
CancellationToken is null