Class QueryObject

java.lang.Object
org.spiderwiz.core.DataObject
org.spiderwiz.core.QueryObject

@WizQuery
public abstract class QueryObject
extends DataObject
A base class for Query Objects.

Query objects are a special sort of data objects used for round-trip query and response. The inquirer sets query property fields and posts the query. The responder that receives the query needs just to set response property fields and the framework carries the response back to the inquirer.

Note that the inquirer side is the producer of the query object, while the responder is the consumer.

The following is a general description of the class methods. For a detailed description, see below.

At the inquirer side, post a query by calling post(expires) or post(expires, destinations). The first version broadcasts the query to all the consumers of this query type, the latter posts it to the specified destination(s).

You can handle the response synchronously or asynchronously. To handle synchronously, call waitForReply() after posting the query. When the method ends, if the query has been replied properly the object response properties will be set. Asynchronous response handling is done by overriding onReply(). You may override onExpire() to do something in case the query expires before it is replied.

At the responder side, handle the query by overriding onInquire(). Reply by setting the appropriate property fields and return true when you quit the method. Alternatively you commit the response by calling replyNow() before you quit. If you need to reply by sending back a stream of data in multiple items, set object properties and call replyNext() for each item, then finalize the response by calling replyEnd().

A query can be closed or open. A closed query expects only one response after which the query is discarded. An open query can receive multiple responses from one or more responders and it remains active until it expires. To indicate an open query override isOpenQuery().

You can mark the query as urgent by overriding DataObject.isUrgent(). Urgent queries have priority over other items circulated by the framework.

  • Constructor Details

    • QueryObject

      public QueryObject()
      Object constructor.

      Normally you would not instantiate objects of this class directly but use Main.createQuery().

  • Method Details

    • post

      public final void post​(long expires)
      Posts the query.

      Posts the query to all potential responders. (You can still filter destinations by using DataObject.filterDestination()). The expires parameter tells how long to wait for a reply before the query expires and discarded. A non positive value means no waiting (which usually makes sense only if the query is responded from the application itself).

      Parameters:
      expires - query expiring period in milliseconds.
    • post

      public final void post​(long expires, String destinations)
      Posts the query to specific destination.

      Posts the query to the destinations specified by the destinations parameter as a list of application UUIDs concatenated by the semicolon (';') character. The expires parameter tells how long to wait for a reply before the query expires and discarded. A non positive value means no waiting (which usually makes sense only if the query is responded from the application itself).

      Parameters:
      expires - query expiring period in milliseconds.
      destinations - a list of UUIDs concatenated by the semicolon (';') character. The null value means a general broadcast.
    • waitForReply

      public final boolean waitForReply()
      Waits until the query is replied or expires.

      Blocks the caller thread until the query is replied fully or partially, or expires. Full reply is when this is a closed query (that returns false in isOpenQuery()), and either onReply() or onReplyEnd() are activated. Partial reply is when onReplyNext() was activated but onReplyEnd() was not, or a reply was received for an open query (that returns true in isOpenQuery()).

      Note that in case of a partial reply, each call to waitForReply() activates a new expiration cycle with the length equal to the value set when post() was called.

      The method returns true if the query was replied, fully or partially, since the previous call to this method, and false when the query expired.

      Returns:
      true if the query has been replied, fully or partially, and false when it has expired.
    • onInquire

      protected boolean onInquire()
      Handles a query on the responder side.

      Override this method to reply to a query. You would need to examine the property fields pertaining to the query, set the property fields pertaining to the response, and quit the method with the value true. Replying a query by this way would fire onReply() at the inquirer side.

      Alternatively you can handle the query by responding with a multi-item stream. For each item, set the appropriate response properties and call replyNext(). When you have done, call replyEnd(). When you use this mechanism exit with the value false to indicate that you have committed the response and the framework shall not take any further action.

      If you want to send a single-item response before you quit the method, call replyNow() from anywhere in the method. In this case also exit with the value false.

      Returns:
      true if the query has been fully replied and the framework shall send the reply back to the inquirer, false otherwise.
    • replyNow

      protected final void replyNow() throws Exception
      Commits a query response.

      Call this method if you want to commit the query response before you exit onInquire(). If you do, exit that method with the value false to notify the framework that no further process is needed. Replying a query by this way would fire onReply() at the inquirer side.

      Throws:
      Exception
    • replyNext

      protected final boolean replyNext() throws Exception
      Commits a single item of a multi-item response stream.

      Use this method to reply a query by streaming, i.e. sending a bulk of data piece by piece. For instance, when the query is executed by querying a database table and the response is a record set that you want to deliver record by record. For each item set appropriate property fields and call replyNext(). Replying a query by this way would fire onReplyNext() at the inquirer side. Having sent the entire response call replyEnd(). You would usually do this by forking a new thread from onInquire() to handle the streaming in the background.

      When you use this method exit onInquire() with the value false to notify the framework that you take care of the entire response mechanism by yourself.

      Note that the use of this method includes rate moderation. Every call to replyNext() pauses execution for a period determined by getStreamingRate(). To stream continuously without moderation implement that method to return zero.

      The method returns true if the response item is committed successfully. If the query is not active anymore (replyEnd() or replyNow() were called, or it has expired), the method returns false.

      Returns:
      true if the item is committed successfully, false if the query had completed or expired.
      Throws:
      Exception
    • replyEnd

      protected final void replyEnd() throws Exception
      Notifies the end of a multi-item response stream.

      Call this method when you have completed a series of replyNext() calls. onReplyEnd() would be fired at the inquirer side.

      Throws:
      Exception
    • onReply

      protected void onReply()
      Handles a query response.

      Override this method to handle a single-item query response. To handle a multiple item response stream, override onReplyNext() and onReplyEnd().

    • onReplyNext

      protected void onReplyNext()
      Handles one response item of a multi-item response stream.

      Override this method to handle one response item of a multi-item response stream, committed at the responder side by calling replyNext().

    • onReplyEnd

      protected void onReplyEnd()
      Handles the notification of the end of a multi-item response stream.

      Override this method to handle the notification of the end of a multi-item response stream, notified at the responder side by calling replyEnd().

    • onExpire

      protected void onExpire()
      Handles query expiration.

      Override this method to do something when the query expires or is aborted before completion.

    • isOpenQuery

      protected boolean isOpenQuery()
      Returns true if this is an open query.

      A query can be closed or open. A closed query expects only one response after which the query is discarded. An open query can receive multiple responses from one or more responders and it remains active until it expires. Override this method to indicate that this is an open query. The default implementation returns false.

      Returns:
      true if and only if this is an open query.
    • notForMe

      protected boolean notForMe()
      Returns true if your application does not handle this query.

      Override this method to tell the framework that your application will not handle this query. This is more resource-saving than implementing onReply() that returns false. The default implementation returns false.

      Returns:
      true if and only if your application does not handle this query.
    • isComplete

      protected final boolean isComplete()
      Returns true if the query has been completely replied.

      A query is considered to be completely replied if it is a closed query (see isOpenQuery()) and either a single-item response or the end of a multi-item response stream were received for it, or if the query was aborted.

      Returns:
      true if and only if the query has been completely replied.
    • abort

      public final boolean abort()
      Aborts the query.

      Call this method, usually from the inquirer side, to abort the query. This notifies potential responders that there is no need any more to handle the query.

      Returns:
      true if the query was active before this method is called.
    • getStreamingRate

      protected int getStreamingRate()
      Returns the streaming rate of a multi-item stream response.

      A streamed query response, i.e. when a query is replied by a series of replyNext() calls, is moderated by default. In order to avoid network congestion, replyNext() would pause for a while after each item. The default streaming rate is 100 items per second. Override this method to define a different rate. Return zero to indicate a continuous streaming with no pausing.

      Returns:
      number of stream items per second, or zero for continuous streaming with no pausing. The default is 100 items per second.
    • getParentCode

      protected String getParentCode()
      Returns the object code of the parent of this query.

      By default, the method returns null for query objects.

      Specified by:
      getParentCode in class DataObject
      Returns:
      the object code of the parent of this query, which is null by default.
    • isDisposable

      protected boolean isDisposable()
      Returns true if the query is disposable (the default).
      Specified by:
      isDisposable in class DataObject
      Returns:
      true if the query is disposable (the default).
    • cleanup

      public void cleanup()
      Cleans up query resources.

      This method overrides DataObject.cleanup() to perform query object specific cleanup. If you override this method do not forget to call super.cleanup().

      Overrides:
      cleanup in class DataObject