/** This module defines a KQML based msg communication protocol and formats to

    be used on the application side of the Communicator. That is, the

    application is the agent or entity which has incorporated the Communicator

    module as its mechanism for communicating with external agents.

    InternalKQMLmessage extends KQMLmessage by implementing the methods of the

    InternalMsg interface defined in the Communicator. Msgs in the application

    that conform to the InternalMsg interface can be handed to the Communicator

    for transmission. The Communicator will translate an InternalMsg to an

    ExternalMsg before sending it out to the external agent. The internal msgs

    and external msgs may use the same base protocol, such as KQML, or they

    may use different protocols. The only requirement is that they implement

    the InternalMsg and ExternalMsg interfaces respectively since the

    Communicator views all msgs it sends or receives from these abstract

    points of view.



    Implement the methods of the InternalMsg interface on top of the 

    methods of KQMLmessage.

    NOTE: The idea here would be to allow any basic communication protocol,

          KQML being just one example, to be extended with an implementation

          of the InternalMsg interface on top of an existing class for the

          protocol. New protocols could be substituted by doing the same

          subclassing off their existing class. Use of the subclass can be

          localized to a few well defined places (I think/hope) such as

          constructor calls (should we also have a createMsg() interface

          method in AgentMsg whose implementation calls the actual subclass

          constructor to even further reduce the number of places where

          code need be changed when substituting a new protocol?). The actual

          objects passed around (as method args for example) would just be

          declared as type InternalMsg with only the interface methods being

          used as accessors into the actual msg. I need to think more about

          whether this provides the necessary structure for flexible plug and

          play of different protocols on the internal and external sides of the

          Communicator to accomodate a variety of agents. Is this the right

          view of the abstraction needed?

   

          In addition, for implementing a new protocol, which did not have a

          previous java class already implemented, one would simply build it

          by directly implementing the required abstract methods - there would

          be nothing to subclass from. (I just wanted to state the obvious.)

*/   

public class InternalKQMLmessage extends KQMLmessage implements InternalMsg {



  /** A constructor that creates a new InternalMsg without

      any fields present initially.

  */

  public InternalKQMLmessage() {



  /** A constructor that creates a new InternalMsg from a string

      representation of an InternalMsg.

  */

  public InternalKQMLmessage(String internalMsgString) {



  //------------------------------------------------------------

  // Next we implement methods from the AgentMsg interface.

  //------------------------------------------------------------



  /** Return the value of the performative, null if there is none.

  */

  public synchronized String getPerformative() {



  /** Set the performative to the indicated value. Create it

      if it did not exist. Return the previous value, null

      if did not exist previously.

  */

  public synchronized String setPerformative(String performative) {



  /** Return the value of the given field, null if the field does

      not exist.

  */

  public synchronized String getField(String fieldName) {



  /** Set the given field to the indicated value. Create the field

      if it did not exist. Return the previous value held in the

      field, null if did not exist previously.

      NOTE: This is similar to addFieldValuePair() in KQMLmessage class.

  */

  public synchronized String setField(String fieldName, String value) {



  /** Return true if a field exists, even if its value is null.

  */

  public synchronized boolean existsField(String fieldName) {



  /** Return true if a field exists and its value is not null.

  */

  public synchronized boolean existsNonNullField(String fieldName) {



  /** Return true if a field exists and its value is not

      empty, i.e. it is not just a whitespace string.

  */

  public synchronized boolean existsNonEmptyField(String fieldName) {



  /** Produce a String representation of the msg suitable for:

         - printing

         - passing around internally, in lieu of an InternalMsg,

           when simple strings seem more appropriate (perhaps as

           args in external query functions)

      This method should know how to produce a string representation

      of the msg in the correct format of the particular msg class

      implementing the AgentMsg interface. (NOTE: Do we want to have

      a more uniquely named method instead such as "toStringMsg()"?)

  */

  public synchronized String toString() {



  /** Determine if the  pairs represented in the

      msg constitute a valid msg in the context of an instantiation

      of the particular msg class implementing the AgentMsg interface.



      Test if the InternalMsg meets the minimal requirements for an

      InternalMsg. This means that it should have the set of required

      fields (those specified for an AgentMsg plus any others added for

      this protocol) and the set of internal fields specified for an

      InternalMsg. Validity means that all those fields are present in the

      msg and that the 2 required fields, SENDER and RECEIVER, plus all

      the internal fields have actual values, i.e., the values are more than

      just whitespace strings. The actual test for a valid msg is probably

      most often done inside the Communicator just before it sends the msg

      out via a Connection to an external agent. The Communicator depends

      on the required and internal fields when doing the actual IO. It is

      not uncommon for the application side to pass an invalid InternalMsg

      into the Communicator. In particular, the Communicator API the

      application side uses to send a msg to an external server agent takes

      an InternalMsg arg and a ConnectionDescriptor arg. The Communicator

      method uses the ConnectionDescriptor to fill in the internal fields

      of the msg with the information about the Connection. It then calls

      isValidMsg() to make sure the msg is complete before passing it down

      into the Communicator's low level IO routines. While the internal fields

      and the SENDER and RECEIVER fields must have actual values in order for

      the Communicator to send the msg, other required fields such as

      CONTENT, REPLY_WITH, and IN_REPLY_TO may be empty since they are not

      strictly essential to the Communicator. However, we do require that

      those non-essential fields be present in the msg even with empty values

      since we want to enforce a notion of uniformity in the basic format

      of inter-agent msgs. An empty value can be the null string (i.e., "")

      or any whitespace string (eg., " ", " \t\n", etc.)

  */

  public synchronized boolean isValidMsg() {



  // NOTE: It would be nice to have this as a static method but I wouldn't

  //       be able to put it in InternalMsg since interfaces can't have

  //       static methods. But I do want it to be in every class that

  //       implements InternalMsg. So I have to keep it as an instance method.

  //

  /** When an agent needs to send a reply msg to an external agent, he

      can use the external agent's msg being replied to in order to

      build the reply msg. The method here assumes that the msg instance

      here is the external agent's msg we want to reply to. So the method

      takes this msg and clones it, swaps sender and receiver, assigns new

      performative and content and reply-with, and sets in-reply-to from

      this msgs's reply-with. The msg built is returned as the reply msg.

  */

  public synchronized InternalMsg buildReplyMsg(String performative,

                                                String content,

                                                String replyWith)



  /** This method overloads buildReplyMsg() to leave the reply-with

      field empty. This is intended for use with Communicator msg send

      methods that fill in the reply-with field to perform synchronized

      communication (with blocking) with the external agent or to establish

      a redirection of msgs from the external agent into a Provision queue.

  */

  public synchronized InternalMsg buildReplyMsg(String performative,

                                                String content)