Module jtrim.query

Class AsyncLinks

java.lang.Object
org.jtrim2.concurrent.query.AsyncLinks

public final class AsyncLinks extends Object
Contains static factory methods for useful AsyncDataLink implementations.

This class cannot be inherited or instantiated.

Thread safety

Unless otherwise noted, methods of this class are safe to use by multiple threads concurrently.

Synchronization transparency

Methods of this class are synchronization transparent.
See Also:
  • Method Details

    • interceptData

      public static <DataType> AsyncDataLink<DataType> interceptData(AsyncDataLink<? extends DataType> wrappedLink, DataInterceptor<? super DataType> interceptor)
      Creates an AsyncDataLink which will provide the same data as the specified AsyncDataLink but has a chance to intercept every the data being retrieved. It is also possible for the interceptor to filter out some of the data objects being retrieved.

      The methods of the interceptor object are called in the listener of the data retrieval request, so they must be quick, non-blocking methods.

      Type Parameters:
      DataType - the type of the data being provided by the returned AsyncDataLink (and also the specified one)
      Parameters:
      wrappedLink - the AsyncDataLink which actually provides the data and whose data objects are being intercepted. This argument cannot be null.
      interceptor - the DataInterceptor to be notified before data was received by the listener listening for the requested data. This argument cannot be null.
      Returns:
      the AsyncDataLink providing the same data as the specified AsyncDataLink but intercepts every returned data and the data notification of the data retrieval completion. This method never returns null.
      Throws:
      NullPointerException - thrown if any of the arguments is null
    • convertResultSync

      public static <OldType, NewType> AsyncDataLink<NewType> convertResultSync(AsyncDataLink<? extends OldType> input, DataConverter<? super OldType,? extends NewType> converter)
      Creates an AsyncDataLink which will provide the same data as the specified AsyncDataLink but applies a conversion on the provided data. That is, it will call converter.convertData on every data object provided by the specified AsyncDataLink.

      For example, if the specified AsyncDataLink provides a string: "dummy", and the converter returns the length of the passed string as an Integer, then the returned AsyncDataLink will provide the Integer value 5.

      Type Parameters:
      OldType - the type of the data objects provided by the specified AsyncDataLink, which is also the type of the input of the conversion
      NewType - the type of the data objects provided by the returned AsyncDataLink, which is also the type of the output of the conversion
      Parameters:
      input - the AsyncDataLink of which provided data is to be converted. This argument cannot be null.
      converter - the DataConverter defining the conversion of the results of input. This argument cannot be null.
      Returns:
      the AsyncDataLink which will provide the same data as the specified AsyncDataLink but applies a conversion on the provided data. This method never returns null.
      Throws:
      NullPointerException - thrown if any of the arguments is null
      See Also:
    • convertResultAsync

      public static <OldType, NewType> AsyncDataLink<NewType> convertResultAsync(AsyncDataLink<? extends OldType> input, AsyncDataQuery<? super OldType,? extends NewType> converter)
      Creates an AsyncDataLink which will provide the same data as the specified AsyncDataLink but applies a conversion on the provided data defined by an AsyncDataQuery. That is, it will pass every data received by the input AsyncDataLink and pass it as an input to the AsyncDataQuery and will return the data provided by the AsyncDataLink returned by the AsyncDataQuery.

      This method is best used when the conversion requires to much time to be executed directly in a listener. For example, if the specified AsyncDataLink provides a Path from an external source to a file and the converter loads the image from a given path, these can be combined to create an AsyncDataLink which loads an image file from this external source.

      Note that in the above example the input AsyncDataLink is unlikely to provide more and more accurate data. However in general, it is possible that both the input AsyncDataLink and the AsyncDataLink instances returned by the converter AsyncDataQuery can return more data objects with increasing accuracy. The returned AsyncDataLink assumes that the conversion cannot make a data (provided by the input AsyncDataLink) more accurate than the subsequent inputs AsyncDataLink (after the first conversion).

      As a general and simple example assume that the input AsyncDataLink returns the string "A" and "B", so "A" is more accurate than "B". Also assume that the converter query for every inputs provides two strings: The first provided string is the input string with "C" appended and second is with "D" appended. Therefore the returned AsyncDataLink will provide the following strings: "AC", "AD", "BC", "BD" and the accuracy is the same as the order of these strings. Note that the returned query can only provide the strings in this order but may omit any subset of them except for the last one ("BD" which will always be provided).

      When an LinkedDataControl object is passed to control the data retrieval process, the main control data is sent to the specified AsyncDataLink and the secondary control data is sent to the AsyncDataLink created by the specified query defining the conversion.

      Type Parameters:
      OldType - the type of the data objects provided by the specified AsyncDataLink, which is also the type of the input of the conversion
      NewType - the type of the data objects provided by the returned AsyncDataLink, which is also the type of the output of the conversion
      Parameters:
      input - the AsyncDataLink of which provided data is to be converted. This argument cannot be null.
      converter - the AsyncDataQuery defining the conversion of the results of input. This argument cannot be null.
      Returns:
      the AsyncDataLink which will provide the same data as the specified AsyncDataLink but applies a conversion on the provided data. This method never returns null.
      Throws:
      NullPointerException - thrown if any of the arguments is null
      See Also:
    • extractCachedResult

      public static <DataType> AsyncDataLink<DataType> extractCachedResult(AsyncDataLink<RefCachedData<DataType>> link)
      Returns an AsyncDataLink which retrieves the data part from the RefCachedData results of the given AsyncDataLink.

      The returned AsyncDataLink will return the same number of results as the specified AsyncDataLink. That is the returned AsyncDataLink will simply return the data part for each received RefCachedData in the same order.

      Type Parameters:
      DataType - the type of the data to be provided by the returned AsyncDataLink
      Parameters:
      link - the AsyncDataLink from which the data part is to be extracted. This argument cannot be null.
      Returns:
      the AsyncDataLink providing the data part of the specified AsyncDataLink. This method never returns null.
      Throws:
      NullPointerException - thrown if the specified AsyncDataLink is null
      See Also:
    • removeUidFromResult

      public static <DataType> AsyncDataLink<DataType> removeUidFromResult(AsyncDataLink<DataWithUid<DataType>> link)
      Returns an AsyncDataLink which retrieves the data part from the DataWithUid results of the given AsyncDataLink.

      The returned AsyncDataLink will return the same number of results as the specified AsyncDataLink. That is the returned AsyncDataLink will simply return the data part for each received DataWithUid in the same order.

      Type Parameters:
      DataType - the type of the data to be provided by the returned AsyncDataLink
      Parameters:
      link - the AsyncDataLink from which the data part is to be extracted. This argument cannot be null.
      Returns:
      the AsyncDataLink providing the data part of the specified AsyncDataLink. This method never returns null.
      Throws:
      NullPointerException - thrown if the specified AsyncDataLink is null
      See Also:
    • markResultWithUid

      public static <DataType> AsyncDataLink<DataWithUid<DataType>> markResultWithUid(AsyncDataLink<? extends DataType> link)
      Returns an AsyncDataLink which returns the same results as the specified AsyncDataLink but creates a DataWithUid object with a new unique ID from the results of the specified AsyncDataLink.

      The returned AsyncDataLink will return the same number of results as the specified AsyncDataLink. That is the returned AsyncDataLink will simply return a new DataWithUid with the same data and a unique ID.

      The ID of the provided datas will be unique, so that no other object equals to them.

      Type Parameters:
      DataType - the type of the data provided by the specified AsyncDataLink
      Parameters:
      link - the AsyncDataLink from which the data part is to be derived for the results of the returned AsyncDataLink. This argument cannot be null.
      Returns:
      the AsyncDataLink providing the DataWithUid objects with the data parts provided by the specified AsyncDataLink. This method never returns null.
      Throws:
      NullPointerException - thrown if the specified AsyncDataLink is null
      See Also:
    • cacheResult

      public static <DataType> AsyncDataLink<DataType> cacheResult(AsyncDataLink<? extends DataType> wrappedDataLink, ReferenceType refType, ObjectCache refCreator)
      Returns an AsyncDataLink which will return the same datas as the specified AsyncDataLink but will cache its results. The actual caching mechanism is defined by the specified ObjectCache and therefore the cached data is stored in a VolatileReference.

      Requesting data

      The first time the data is requested from the returned AsyncDataLink, it will fallback to requesting the data from the specified AsyncDataLink and provide exactly the same data as provided by this underlying AsyncDataLink. Once the final data is available, it will be cached using the given cache. Subsequent data requests will simply return this final cached data.

      In case the cached data expires (no longer available in the cache), the data will be returned as if it has never been requested. Note that the returned AsyncDataLink implementation will never query the data from the specified AsyncDataLink if not required. That is, if it is currently in the process of requesting the data, it will not start a concurrent request but will return the data from the ongoing request.

      Canceling requests

      Attempting to cancel a data request will not cancel the requesting of the data from the specified AsyncDataLink but will only do so if there are no active requests (only canceled or completed) and even in this case only after one second has elapsed since the last active request.

      Controlling requests

      In case the data is currently being requested from the specified AsyncDataLink, the control objects will be forwarded to this underlying request. Note however, that AsyncDataController objects created by the returned AsyncDataLink may forward the control requests to the same underlying request.
      Type Parameters:
      DataType - the type of the data provided by the specified AsyncDataLink which is the same type as the returned AsyncDataLink
      Parameters:
      wrappedDataLink - the AsyncDataLink from which the data is to be requested when the data is not currently cached. This argument cannot be null.
      refType - the ReferenceType to be used to reference the cached data using the specified ObjectCache. This argument cannot be null.
      refCreator - the ObjectCache to use to cache the data. This argument can be null in which case ObjectCache.javaRefCache() is used as the ObjectCache.
      Returns:
      the AsyncDataLink which will provide the same data as the specified AsyncDataLink but will cache its result. This method never returns null.
      Throws:
      NullPointerException - thrown if any of the arguments is null except for the ObjectCache which is allowed to be null
      See Also:
    • cacheResult

      public static <DataType> AsyncDataLink<DataType> cacheResult(AsyncDataLink<? extends DataType> wrappedDataLink, ReferenceType refType, ObjectCache refCreator, long dataCancelTimeout, TimeUnit timeUnit)
      Returns an AsyncDataLink which will return the same datas as the specified AsyncDataLink but will cache its results. The actual caching mechanism is defined by the specified ObjectCache and therefore the cached data is stored in a VolatileReference.

      Requesting data

      The first time the data is requested from the returned AsyncDataLink, it will fallback to requesting the data from the specified AsyncDataLink and provide exactly the same data as provided by this underlying AsyncDataLink. Once the final data is available, it will be cached using the given cache. Subsequent data requests will simply return this final cached data.

      In case the cached data expires (no longer available in the cache), the data will be returned as if it has never been requested. Note that the returned AsyncDataLink implementation will never query the data from the specified AsyncDataLink if not required. That is, if it is currently in the process of requesting the data, it will not start a concurrent request but will return the data from the ongoing request.

      Canceling requests

      Attempting to cancel a data request will not cancel the requesting of the data from the specified AsyncDataLink but will only do so if there are no active requests (only canceled or completed) and even in this case only after the given timeout has elapsed since the last active request.

      Controlling requests

      In case the data is currently being requested from the specified AsyncDataLink, the control objects will be forwarded to this underlying request. Note however, that AsyncDataController objects created by the returned AsyncDataLink may forward the control requests to the same underlying request.
      Type Parameters:
      DataType - the type of the data provided by the specified AsyncDataLink which is the same type as the returned AsyncDataLink
      Parameters:
      wrappedDataLink - the AsyncDataLink from which the data is to be requested when the data is not currently cached. This argument cannot be null.
      refType - the ReferenceType to be used to reference the cached data using the specified ObjectCache. This argument cannot be null.
      refCreator - the ObjectCache to use to cache the data. This argument can be null in which case ObjectCache.javaRefCache() is used as the ObjectCache.
      dataCancelTimeout - the time in the given unit to wait before actually canceling abandoned requests. Before this time elapses, it is possible to start requesting the data and continuing where the request was left off. This argument must be greater than or equal to zero. In case this argument is zero, the data requesting will be canceled as soon as the data is detected to be not required.
      timeUnit - the time unit of the dataCancelTimeout argument. This argument cannot be null.
      Returns:
      the AsyncDataLink which will provide the same data as the specified AsyncDataLink but will cache its result. This method never returns null.
      Throws:
      NullPointerException - thrown if any of the arguments is null except for the ObjectCache which is allowed to be null
      See Also:
    • refCacheResult

      public static <DataType> AsyncDataLink<RefCachedData<DataType>> refCacheResult(AsyncDataLink<? extends DataType> wrappedDataLink, ReferenceType refType, ObjectCache refCreator)
      Returns an AsyncDataLink which will return the same datas as the specified AsyncDataLink but will cache its results and also return the cached reference. The actual caching mechanism is defined by the specified ObjectCache and therefore the cached data is stored in a VolatileReference.

      Requesting data

      The first time the data is requested from the returned AsyncDataLink, it will fallback to requesting the data from the specified AsyncDataLink and provide exactly the same data as provided by this underlying AsyncDataLink. Once the final data is available, it will be cached using the given cache. Subsequent data requests will simply return this final cached data.

      In case the cached data expires (no longer available in the cache), the data will be returned as if it has never been requested. Note that the returned AsyncDataLink implementation will never query the data from the specified AsyncDataLink if not required. That is, if it is currently in the process of requesting the data, it will not start a concurrent request but will return the data from the ongoing request.

      Canceling requests

      Attempting to cancel a data request will not cancel the requesting of the data from the specified AsyncDataLink but will only do so if there are no active requests (only canceled or completed) and even in this case only after one second has elapsed since the last active request.

      Controlling requests

      In case the data is currently being requested from the specified AsyncDataLink, the control objects will be forwarded to this underlying request. Note however, that AsyncDataController objects created by the returned AsyncDataLink may forward the control requests to the same underlying request.
      Type Parameters:
      DataType - the type of the data provided by the specified AsyncDataLink which is the same type as the returned AsyncDataLink
      Parameters:
      wrappedDataLink - the AsyncDataLink from which the data is to be requested when the data is not currently cached. This argument cannot be null.
      refType - the ReferenceType to be used to reference the cached data using the specified ObjectCache. This argument cannot be null.
      refCreator - the ObjectCache to use to cache the data. This argument can be null in which case ObjectCache.javaRefCache() is used as the ObjectCache.
      Returns:
      the AsyncDataLink which will provide the same data as the specified AsyncDataLink but will cache its result. This method never returns null.
      Throws:
      NullPointerException - thrown if any of the arguments is null except for the ObjectCache which is allowed to be null
      See Also:
    • refCacheResult

      public static <DataType> AsyncDataLink<RefCachedData<DataType>> refCacheResult(AsyncDataLink<? extends DataType> wrappedDataLink, ReferenceType refType, ObjectCache refCreator, long dataCancelTimeout, TimeUnit timeUnit)
      Returns an AsyncDataLink which will return the same datas as the specified AsyncDataLink but will cache its results and also return the cached reference. The actual caching mechanism is defined by the specified ObjectCache and therefore the cached data is stored in a VolatileReference.

      Requesting data

      The first time the data is requested from the returned AsyncDataLink, it will fallback to requesting the data from the specified AsyncDataLink and provide exactly the same data as provided by this underlying AsyncDataLink. Once the final data is available, it will be cached using the given cache. Subsequent data requests will simply return this final cached data.

      In case the cached data expires (no longer available in the cache), the data will be returned as if it has never been requested. Note that the returned AsyncDataLink implementation will never query the data from the specified AsyncDataLink if not required. That is, if it is currently in the process of requesting the data, it will not start a concurrent request but will return the data from the ongoing request.

      Canceling requests

      Attempting to cancel a data request will not cancel the requesting of the data from the specified AsyncDataLink but will only do so if there are no active requests (only canceled or completed) and even in this case only after the given timeout has elapsed since the last active request.

      Controlling requests

      In case the data is currently being requested from the specified AsyncDataLink, the control objects will be forwarded to this underlying request. Note however, that AsyncDataController objects created by the returned AsyncDataLink may forward the control requests to the same underlying request.
      Type Parameters:
      DataType - the type of the data provided by the specified AsyncDataLink which is the same type as the returned AsyncDataLink
      Parameters:
      wrappedDataLink - the AsyncDataLink from which the data is to be requested when the data is not currently cached. This argument cannot be null.
      refType - the ReferenceType to be used to reference the cached data using the specified ObjectCache. This argument cannot be null.
      refCreator - the ObjectCache to use to cache the data. This argument can be null in which case ObjectCache.javaRefCache() is used as the ObjectCache.
      dataCancelTimeout - the time in the given unit to wait before actually canceling abandoned requests. Before this time elapses, it is possible to start requesting the data and continuing where the request was left off. This argument must be greater than or equal to zero. In case this argument is zero, the data requesting will be canceled as soon as the data is detected to be not required.
      timeUnit - the time unit of the dataCancelTimeout argument. This argument cannot be null.
      Returns:
      the AsyncDataLink which will provide the same data as the specified AsyncDataLink but will cache its result. This method never returns null.
      Throws:
      NullPointerException - thrown if any of the arguments is null except for the ObjectCache which is allowed to be null
      See Also:
    • convertGradually

      public static <InputType, ResultType> AsyncDataLink<ResultType> convertGradually(InputType input, List<? extends AsyncDataConverter<InputType,ResultType>> transformers)
      Creates a new AsyncDataLink which will return the given input data transformed by the specified AsyncDataConverter, assuming that subsequent converters in the list provide more and more accurate conversion. That is, the returned AsyncDataLink will first return the input transformed by the first AsyncDataConverter, the transformed by the second AsyncDataConverter and so on.
      Type Parameters:
      InputType - the type of the input to be transformed
      ResultType - the type of the result of the transformation
      Parameters:
      input - the input to be transformed and returned. This argument can only be null if the AsyncDataConverter implementations accept null inputs.
      transformers - the list of AsyncDataConverter instances to transform the input data. Every element of the list defines a more accurate conversion than previous elements of the list. So every element of this list defines the same conversion except with different accuracy. This argument cannot be null, cannot contain null elements and also must contain at least a single element.
      Returns:
      the AsyncDataLink which will transform the given input using the specified conversions. This method never returns null.
      Throws:
      NullPointerException - thrown if the convert list or any of the converters is null
      IllegalArgumentException - thrown if there are no transformations specified
    • createStateReporterLink

      public static <DataType> AsyncDataLink<DataType> createStateReporterLink(AsyncDataLink<DataType> wrappedLink, AsyncStateReporter<DataType> reporter, long period, TimeUnit periodUnit)
      Creates a new AsyncDataLink which will provide the exact same data as the specified AsyncDataLink but will periodically report the state of the data retrieving process.

      The state will be reported through the provided AsyncStateReporter.reportState(AsyncDataLink, AsyncDataListener, AsyncDataController) method. This method will be invoked on a separate thread which may be shared by other state reports. That is, multiple AsyncDataLink instances created by this method may share the same thread to handle state reports. Therefore it is important for the AsyncStateReporter instances not to depend on each other.

      The reporting of the state of progress will end once the data providing is done (reporting is done separately for every data providing process). Note however, that it does not mean that once the onDoneReceive notification was received no more state report will be done but state reporting will end eventually after the onDoneReceive notification.

      Type Parameters:
      DataType - the type of the data provided by the specified AsyncDataLink which is the same type as the returned AsyncDataLink
      Parameters:
      wrappedLink - the AsyncDataLink which is to provide the data for the returned AsyncDataLink and whose state of progress is to be reported. This argument cannot be null.
      reporter - the AsyncStateReporter to which the state of data providing progress will be reported periodically. This argument cannot be null.
      period - the period of time in the specified time unit in which the state of data providing progress is to be reported. This argument must be greater than or equal to zero.
      periodUnit - the time unit of the period argument. This argument cannot be null.
      Returns:
      the AsyncDataLink which will provide the exact same data as the specified AsyncDataLink but will periodically report the state of the data retrieving process. This method never returns null.
      Throws:
      IllegalArgumentException - thrown if the specified time period is lesser than zero
      NullPointerException - thrown if any of the arguments is null
      See Also:
    • createStateReporterLink

      public static <DataType> AsyncDataLink<DataType> createStateReporterLink(UpdateTaskExecutor reportExecutor, AsyncDataLink<DataType> wrappedLink, AsyncStateReporter<DataType> reporter, long period, TimeUnit periodUnit)
      Creates a new AsyncDataLink which will provide the exact same data as the specified AsyncDataLink but will periodically report the state of the data retrieving process.

      This method works exactly the same way as its cousin createStateReporterLink method except that it will forward state of progress notifications to the specified UpdateTaskExecutor instead of directly invoking the AsyncStateReporter.reportState(AsyncDataLink, AsyncDataListener, AsyncDataController) method.

      The state will be reported through the provided AsyncStateReporter.reportState(AsyncDataLink, AsyncDataListener, AsyncDataController) method. This method will be invoked in the context of the specified UpdateTaskExecutor.

      The reporting of the state of progress will end once the data providing is done (reporting is done separately for every data providing process). Note however, that it does not mean that once the onDoneReceive notification was received no more state report will be done but state reporting will end eventually after the onDoneReceive notification.

      Type Parameters:
      DataType - the type of the data provided by the specified AsyncDataLink which is the same type as the returned AsyncDataLink
      Parameters:
      reportExecutor - the UpdateTaskExecutor to use to report the state of data loading progress. This argument cannot be null.
      wrappedLink - the AsyncDataLink which is to provide the data for the returned AsyncDataLink and whose state of progress is to be reported. This argument cannot be null.
      reporter - the AsyncStateReporter to which the state of data providing progress will be reported periodically. This argument cannot be null.
      period - the period of time in the specified time unit in which the state of data providing progress is to be reported. This argument must be greater than or equal to zero.
      periodUnit - the time unit of the period argument. This argument cannot be null.
      Returns:
      the AsyncDataLink which will provide the exact same data as the specified AsyncDataLink but will periodically report the state of the data retrieving process. This method never returns null.
      Throws:
      IllegalArgumentException - thrown if the specified time period is lesser than zero
      NullPointerException - thrown if any of the arguments is null
      See Also:
    • createPreparedLink

      public static <DataType> AsyncDataLink<DataType> createPreparedLink(DataType data, AsyncDataState state)
      Creates and returns an AsyncDataLink which will provide the given data.

      This method acts as a gateway between statically available data and AsyncDataLink. The returned AsyncDataLink will always provide the specified data immediately in the AsyncDataLink.getData(org.jtrim2.cancel.CancellationToken, AsyncDataListener) method and not on a separate thread. Therefore once the getData method returns it is guaranteed that the data providing has completed (i.e.: the onDoneReceive has been called).

      Type Parameters:
      DataType - the type of the data to be provided
      Parameters:
      data - the data to be provided by the returned AsyncDataLink. That is, exactly this object (and only this), will be provided. This argument can be null but in this case the returned AsyncDataLink will provided null as a data.
      state - the state of progress to be returned by the returned AsyncDataLink when data is requested. Since after the data has been requested, the providing is immediately completed this state must always report the current progress as 1.0. This argument can be null but in this case the returned state will always be null which is not recommended.
      Returns:
      AsyncDataLink which will provide the specified data. This method never returns null.