How callback's are implemented in the NetApp Wrappers construct.

9/8/98
The central idea is to implement the callback with NetApp wrapper classes that communicate using an auxillary socket connection associated with the original client server communication link. On the client side, a server (SI) implementation of the client program is loaded and set running. On the server side, a client (CI) implementation of the client class is created and is associated with the server class's callback reference. The mechanism for creating these objects is by overloading the setClient(...) methods of the client (CI) implementation and the server (SI) implementation of the sever class.

Consider two classes Aclass and Bclass, Aclass acting as a client, and Bclass acting as a server with callbacks. Aclass invokes the setClient(...) method of Bclass to set the callback reference. This is done by using a command such as B.setClient((Object) this).

Then

B.setClient(Object ob) does the following

The code that does this is the following

//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//     Client Implementation of Source Class Methods  
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
public void setClient(java.lang.Object Arg_1) throws java.lang.Exception
{
    Class theClass = Arg_1.getClass();
    String cName   = theClass.getName();
    Object theObject = null;
    
    try
    {
    theClass   = Class.forName(cName + "SI");
    theObject  = theClass.newInstance();
    }
    catch(Exception ex)
    {throw new Exception("Server Class " + cName + "SI Not Found : ");};
    
    ((SIinterface)theObject).setSIobject(Arg_1);
    
    Socket [] auxSocket = new Socket[1];
    auxSocket[0]        = netConnect.getAuxSocket(1);
    NetworkConnection  auxConnection = new NetworkConnection(auxSocket);
    ((SetNetworkConnection)theObject).setNetworkConnection(auxConnection);
    
    Thread SIrun = new Thread((Runnable)theObject);
    SIrun.start();
    
    Vector methodData = new Vector(2);
    methodData.addElement(new Integer(0));
    methodData.addElement(new String(cName + "CI"));
 
    try{Os.writeObject(methodData);}
    catch(Exception e){System.out.println(e);};
 
    Vector MethodRet = new Vector();
    try{MethodRet = (Vector)Is.readObject();}
    catch(Exception e){System.out.println(e);};
 
    int retValue = ((Integer)MethodRet.elementAt(0)).intValue();
    if(retValue != 0)
    {
      switch(retValue-1) 
      {
      case 0 : 
      throw (java.lang.Exception)MethodRet.elementAt(1);
      }
    }
    return;
 
}

On the server side, in BclassSI, the method case associated with the setClient(...) member function


Here is the code taken from Sample3 of the NetApp documentation.

     case 0 :   // setClient(...)
        String cName = (String)methodData.elementAt(1);
        try
        {
        Class theClass;
        Object theObject = null;
    
        theClass   = Class.forName(cName);
        theObject  = theClass.newInstance();
        Socket auxSocket =  netConnect.getAuxSocket(1);
        ((CIinterface)theObject).setObjectStreams(auxSocket.getInputStream(),auxSocket.getOutputStream());
        
        cObj.setClient(theObject);
        methodRet.addElement(new Integer(0));
        }
        catch(Exception e)
        {
        if(e instanceof java.lang.Exception){methodRet.addElement(new Integer(1));
        methodRet.addElement(e);}
        }
      break;