Accessing Services Using Java

You can also access Microsoft Agent services from a Java™ applet. Many of the functions accessible through the Microsoft Agent interfaces return values through parameters passed by reference. In order to pass these parameters from Java, it is necessary to create single-element arrays in your code and pass them as parameters to the appropriate function. If you're using Microsoft Visual J++™ and have run the Java Type Library Wizard on the Microsoft Agent server, refer to the summary.txt file to review which functions require array arguments. The procedure is similar to that in C; you use the IAgent interface to create an instance of the server, then load the character:

private IAgent            m_Agent = null;
private IAgentCharacter    m_Merlin[] = {null};
private int                m_MerlinID[] = {-1};
private int                m_RequestID[] = {0};
private final String    m_CharacterPath = "c:\\agentx\\agtchared\\merlin.acs";

public void start()
{
        // Start the Microsoft Agent Server

        m_Agent = (IAgent) new AgentServer();

        try
        {
            // The filespec parameter of the Load method is a 
            // COM variant to accept alternate Agent data providers.
            // We want a standard provider so we can just specify
            // the filespec for our character.

            Variant characterPath = new Variant();
            characterPath.putString(m_CharacterPath);

            // Load the character

            m_Agent.Load(characterPath,
                         m_MerlinID,
                         m_RequestID);
        }

The procedure is slightly different when loading characters from a HTTP remote location such as a Web site. In this case the Load method is asynchronous and will raise a COM exception of E_PENDING (0x8000000a). You will need to catch this exception and handle it correctly as is done in the following functions:

// Constants used in asynchronous character loads

private final int E_PENDING = 0x8000000a;
private final int NOERROR = 0;


// This function loads a character from the specified path.
// It correctly handles the loading of characters from
// remote sites.

// This sample doesn't care about the request id returned
// from the Load call.  Real production code might use the
// request id and the RequestComplete callback to check for
// a successful character load before proceeding.

public int LoadCharacter(Variant path, int[] id)
{
   int requestid[] = {-1};
   int hRes = 0;

   try
   {
      // Load the character

      m_Agent.Load(path, id, requestid);
   }
   catch(com.ms.com.ComException e)
   {
      // Get the HRESULT

      hRes = e.getHResult();
      
      // If the error code is E_PENDING, we return NOERROR

      if (hRes == E_PENDING)
         hRes = NOERROR;
   }

   return hRes;
}

public void start()
{
   if (LoadCharacter(characterPath, m_MerlinID) != NOERROR)
   {
      stop();
      return;
   }

   // Other initialization code here

   .
   .
   .
}

Then get the IAgentCharacter interface that enables you to access its methods:

// Get the IAgentCharacter interface for the loaded
// character by passing its ID to the Agent server.

m_Agent.GetCharacter(m_MerlinID[0], m_Merlin);

// Show the character

m_Merlin[0].Show(FALSE, m_RequestID);

// And speak hello

m_Merlin[0].Speak("Hello World!", "", m_RequestID);

Similarly, to be notified of events, you must implement the IAgentNotifySink interface, creating and registering an object of that type:

…
// Declare an Agent Notify Sink so that we can get
// notification callbacks from the Agent server.

private AgentNotifySink m_Sink = null;
private int                m_SinkID[] = {-1};

public void start()
    {
    …
    // Create and register a notify sink

    m_Sink = new AgentNotifySink();

    m_Agent.Register(m_Sink, m_SinkID);
    …
    // Give our notify sink access to the character

    m_Sink.SetCharacter(m_Merlin[0]);
    …
    }

In order to access Microsoft Agent from a Java applet, you must generate Java classes that you then install with the applet. You can use the Visual J++ Java Type Library Wizard, for example, to generate these files. If you plan to host the applet on a Web page, you build a signed Java CAB that includes the generated class files and that downloads with the page. The class files are necessary to access the Microsoft Agent Server because it is a COM object that executes outside of the Java sandbox. To learn more about Trust-Based Security for Java, see http://www.microsoft.com/java/security/.