Why Subclass?

Paragraph Data

The above steps outline a simplistic example of how to create your own class that would allow you to use all of the same methods as the LINCEnvironment object.

The real power of subclassing is in letting you define new behavior that becomes built into the object. The most obvious behavior is to get the object to connect itself to the host system when it is created, as shown in the following example,

com.unisys.jellybeans.freddy.java. The best name under which to save the file would be one that contained the system name and your company name, as long as the file name and class name match.

package com.unisys.jellybeans;

import com.unisys.util.ObjectRef;

class freddy extends LINCEnvironment
{
      public int loginFailure_ = 100; //set to our ’OK’ value.
      freddy()
      { //constructor. This should be the same name as the class.
            super(); //call LINCEnvironment constructor. You MUST do this.
            setName("freddy");
            setURL("x-ratl:<hostname>:2889");
            setConnectionMode(0);
            setViewName("view");
            setUsername("ddd");
            setPassword("dddddddddddd");
            // setStationName("<some ’unique’ identifier>");
            setPackagePrefix("com.unisys");
            setBundleName("all");
            setApplicationName("dwtest");
            ObjectRef loginAttrsRef = new ObjectRef();
            LINCStatus status = new LINCStatus();
            int ok = connect(getURL(), getViewName(), loginAttrsRef, status,
            getConnectionMode());
            if(ok == OK_LOGIN)
            {
                  do
                  {
                        LoginAttributeArray loginAttrs = (LoginAttributeArray) 
                                                            loginAttrsRef.getObject();
                        //I will assume that you will know the login attributes 
                        //being asked for.
                        loginAttrs.set("us", getUsername());
                        loginAttrs.set("pw", getPassword());

                        loginAttrsRef.setObject(null);

                        ok = login(loginAttrs, loginAttrsRef, status);
                  } while(ok == OK_MORE_LOGIN_INFO);
                  
                  if(ok != OK)
                  {
                        loginFailure_ =ok; //set this aside, so a client can
                                          //check on why, and report it.
                                          //More elaborate reporting, or even
                                          //re-attempts at connection are
                                          //possible. It is up to each site.
                        return;
                  }
            }
      hello();
      } //end of constructor.
}

When creating an instance of the object, using the above class would ensure it also connects itself automatically. For example,

Server.CreateObect("java:com.unisys.jellybeans.freddy") //create the object, 
and have it connect.

The above code is a simplistic example. While it enables the automatic connection it does not tell the user if a failure occurred or what the failure was. In this case you would be required to check the loginFailure_ property to find out the outcome of the connection. Alternatively, you could write a different method that returned an error/success code, and call that after the object was created. You can include the behavior that is required for your site.

Subclassing is very powerful as it allows you to add new methods without affecting the base class. However it can also be dangerous, as it allows you to overload an existing method or property which you own. It is recommended that you do not attempt to do this. It becomes impossible for Unisys support to determine what might be going wrong in a method if it is your version of the method that is being run, and not the one to which support has access.

Ensure that any methods you add have unique names. A good practice is to pre-append any methods with an abbreviation for your company. This makes them easily identifiable and avoids confusion over where the method comes from, and where the documentation of the method might reside. It is also a good practice to document your methods. You might not always be there to fix the code, and by documenting you give the next person the best chance to understand what is going on.

Apart from automatically connecting, you can automate almost any task. For instance, if your component is going to be used in server-side scripting, you might want to substitute any multiple spaces with &nbsp; to preserve the white space in a browser. You could perform additional checking on certain types of fields, inter field dependency checking, or any task that you want to perform often enough to justify writing it only once, rather than in every client.

The following example, rename.java, includes the addition of a checkConnect() method that automatically connects the object if is not already connected. The subclass in this file would be useful where object pooling is being used.

package com.unisys.jellybeans;

import com.unisys.util.ObjectRef;

class rename extends LINCEnvironment
{
      public int loginFailure_ = 100; //set to our ’OK’ value.
      rename()
      { //constructor. This should be the same name as the class.
            super(); //call LINCEnvironment constructor
            connectToSystem(); //connect on creation of object, so client
                              //does not have to.
      }

//This common function has all of the details to connect to the system.
//It is called as part of the construction of the object, and may
//be called when the client checks if the object is still Ok to use.

      private int connectToSystem()
      {
            setName("freddy");
            setURL("x-ratl:<hostname>:2889");
            setConnectionMode(0);
            setViewName("zz");
            setUsername("zz");
            setPassword("zz");
            // setStationName("<some ’unique’ identifier>");
            setPackagePrefix("com.unisys");
            setBundleName("all");
            setApplicationName("dwtest");
            ObjectRef loginAttrsRef = new ObjectRef();
            LINCStatus status = new LINCStatus();
            int ok = connect(getURL(), getViewName(), loginAttrsRef, status,
            getConnectionMode());
            if(ok == OK_LOGIN)
            {
                  do
                  {
                        LoginAttributeArray loginAttrs = (LoginAttributeArray)
                                                      loginAttrsRef.getObject();
                        //I will assume that you will know the login
                        //attributes being asked for.
                        loginAttrs.set("us", getUsername());
                        loginAttrs.set("pw", getPassword());

                        loginAttrsRef.setObject(null);
                        ok = login(loginAttrs, loginAttrsRef, status);
                  } while(ok == OK_MORE_LOGIN_INFO);

                  if(ok != OK)
                  {
                        loginFailure_ = ok; //set this asside, so a client 
                                          //can check on why, and report it.
                                          //more elaberate reporting, or even
                                          //re-attempts at connection are
                                          //up to each site.
                        return ok;
                  }
            }
            //At this point, the object is ’connected’ to the host,
            //but not to the system. In a ’stateful’ environment,
            //we need each ’user’ to do a hello() to the system, so that
            //it can correctly allocate glb.work etc, for the user.
            //In a stateless environment, you can share the same Linc user
            //as well, and there is no need for every user to do an
            //individual hello. In such a case, do the following as well.

      //uncomment the following line in a statefull environment,
      //or make sure the client does the hello()
      
      //hello();
      
      return ok;
}

//If the LINCEnvironement object has become disconnected for some
//reason (This may be that the host session closed, or that someone
//has closed all of the pooled objects to allow for host
//maintenance.) Then the call this checkConnect() method, will
//re-establish the connection prior to use.
//It will return 100 if things are OK, otherwise the usual error code.
public int checkConnect()
{
      if(!isConnected())
      {    
            return connectToSystem();
            return OK;
      }
}