D:\DEV\PROJECTS\Harbor_Tests\src\harbor\test\testContructors.java
/*
 * testContructors.java
 */

package harbor.test;
import harbor.interfaces.*;
import kewlstuff.harbor.client.Vessel;

/**
 *
 * @author Johnny Kewl
 * Testing GETTING and LOADING a class that needs constructor arguments...
 * TEST 8
 */
public class testContructors {
    private Vessel vessel = null;      
    
    /** Creates a new instance of testContructors */
    public testContructors() {
        String harborUrl = "http://localhost:8080/harbor/service"; //location of container harbor
        vessel = new Vessel(harborUrl); //get a vessel from the harbor  
        vessel.verboseVessel(true);// watch the class loading process in system.out, for debugging        
    }
    
    public void runTest(){

        ///////////////////
        // Local Object
        // Inject the primitive types into a local running object
        Class constructors = vessel.getRemoteClass("harbor.classContainer.Constructors");//get a class from the harbor    
        Class[] contructorTypes = new Class[] {String.class, long.class};
        Object[] contructorArgs = new Object[] {"Me Contructor String", (long)123456789};
        //Create new instance
        I_Constructors i_Constructors = (I_Constructors)vessel.newInst(constructors,contructorArgs,contructorTypes);//can have many instances of a single class (its just like new)
        //Display them
        System.out.print("LOCAL:: " + i_Constructors.getTheContructorParams() + "\n");
        
        ///////////////////
        // Remote Object
        // Inject the primitive types into a remote object
        I_Constructors i_ConstructorsRemote = (I_Constructors)vessel.loadRemoteClassInst(I_Constructors.class,"harbor.classContainer.Constructors",contructorArgs,contructorTypes);
        System.out.print("REMOTE:: " + i_ConstructorsRemote.getTheContructorParams() + "\n");
        vessel.releaseRemoteClassInst(i_ConstructorsRemote);
        
        ///////////////////
        // Singletom Test
        // Inject the primitive types into a singleton
        I_Constructors i_ConstructorsSingleton = (I_Constructors)vessel.loadRemoteSingleton(I_Constructors.class,"harbor.classContainer.Constructors",contructorArgs,contructorTypes,"CONSTRUCTOR");
        System.out.print("SINGLETON:: " + i_ConstructorsSingleton.getTheContructorParams() + "\n");
        vessel.releaseRemoteClassInst(i_ConstructorsSingleton);
        //We released the singleton because we dont want it around and just for fun... because this is unusual
        //we log the message, which the remote Admin person will see when they look at the logs in the browser
        //using the uri /harbor/admin
        vessel.setRemoteAdminLogMessage(0,"INFO: SINGLETON RELEASED BY CLIENT contructor test " + i_ConstructorsSingleton.toString());
        

        ///////////////////
        // Remote Object Injection test
        // Load up an object on the remote server and Inject it through a constructor
        I_MsgTest i_MsgTest = (I_MsgTest)vessel.loadRemoteClassInst(I_MsgTest.class,"harbor.classContainer.MsgTest");//load a class instance ON the harbor        
        //init the constructor arguments
        Class[] contructorObjectTypes = new Class[] {I_MsgTest.class};
        Object[] contructorObjectArgs = new Object[] {i_MsgTest};
        //Now load up the constructor class initialized by this object
        I_Constructors i_ConstructorsObject = (I_Constructors)vessel.loadRemoteClassInst(I_Constructors.class,"harbor.classContainer.Constructors",contructorObjectArgs,contructorObjectTypes);
        //Call the method to see if it works
        System.out.print("OBJECT:: " + i_ConstructorsObject.getObjectContructorParams() + "\n");
        vessel.releaseRemoteClassInst(i_ConstructorsObject);
        vessel.releaseRemoteClassInst(i_MsgTest);  
        
     
        ///////////////////
        // Serialize test
        // Test constructor with serialized data
        Class c_serialObject = vessel.getRemoteClass("harbor.classContainer.serialObject");
        I_serialObject i_serialObject = (I_serialObject)vessel.newInst(c_serialObject);
        i_serialObject.addMessageToBox("Constructor test for local class serialized to constructor");        
        
        Class[] contructorSerialTypes = new Class[] {I_serialObject.class};
        Object[] contructorSerialArgs = new Object[] {i_serialObject};
        //Now load up the constructor class initialized by this object
        I_Constructors i_ConstructorsSerial = (I_Constructors)vessel.loadRemoteClassInst(I_Constructors.class,"harbor.classContainer.Constructors",contructorSerialArgs,contructorSerialTypes);
        //Call the method to see if it works
        System.out.print("SERIAL:: " + i_ConstructorsSerial.getSerialContructorParams() + "\n");
        vessel.releaseRemoteClassInst(i_ConstructorsSerial);
      
    }
   
}

/*
 * As you can see, working with classes that use contructors requires a little more
 * effort from the programmer, compared to setter methods.
 * Nevertheless, because harbor is not EJB restrictive, its possible.
 *
 * As you can see from the sample code, its possible to inject objects, whether
 * they are remote or local into constructors.
 *
 * From a technical perspective, the underlying code for constructor initialization
 * is a little more complex than setter methods, however its biggest draw back is
 * really just that one has to explicitly describe the types... eg
 *  Class[] contructorTypes = new Class[] {String.class, long.class};
 * and the form does not follow that of the constructor method. 
 * This is because the class does not exist yet and there is no implicit help
 * from an existing class.
 * Interesting only from the point of view that having developed the code, one gets
 * some insight into why typical application servers define EJB, which besides
 * a setter and getter convention, is really just classes with no constructors.
 *
 * What this all means is simply that, if one designs with a remote application
 * in mind, the tendency will be to use setter methods for injection.
 * From a design pattern perspective, sometimes designers will feel constructors
 * are the only way to go, or you may be using a third party library and have no
 * choice... the above example is how you do it.
 */