This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

--Creating Lifecycle Objects

Documents for the development of and with JVx.

--Creating Lifecycle Objects

Postby Development@SIB » Thu Sep 16, 2010 11:20 am



This article is outdated - please use our new system at

https://doc.sibvisions.com




JVx's Lifecycle Objects are not only containers for objects and methods, they also allow the reuse of functionality through inheritance. Any POJO can potentially be used as a lifecycle object, although this would mean that we forego the advantage of reuse.

We recommend a special use and a predefined class hierarchy to exploit all the advantages without restrictions!


Configuration
Ideally, lifecycle objects are defined for the application and for the MasterSession.

The objects are defined in the application configuration:

Code: Select all
<application>
  ...
  ...

  <!-- predefined life-cycle object names -->
  <lifecycle>
    <application>com.sibvisions.apps.showcase.Application</application>
    <mastersession>com.sibvisions.apps.showcase.Session</mastersession>
  </lifecycle>

</application>

The class name for the MasterSession can also be defined during the creation of MasterConnection using setLifeCycleName.

Each MasterConnection (Client) requires a MasterSession (Server) to access the server.

The lifecycle object for the application is optional and is only required for tasks spanning multiple applications.


Class Hierarchy

We will explain the class hierarchy based on a showcase application.

The applications lifecycle object:

Code: Select all
package com.sibvisions.apps.showcase;

...
...

/**
 * Application object for Showcase application.
 */
public class Application extends GenericBean
{   
}   // Application

The class GenericBean handles the object administration, which is why we derive from it.

The MasterSession lifecycle object:

Code: Select all
package com.sibvisions.apps.showcase;

...
...

/**
 * Session object for Showcase application.
 */
public class Session extends Application
{
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // User-defined methods
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   
   /**
    * Returns access to the database.
    *
    * @return the access to the database
    * @throws Exception if the datasource can not be opened
    */
   public DBAccess getDBAccess() throws Exception
   {
      DBAccess dba = (DBAccess)get("dBAccess");
      
      if (dba == null)
      {
         IConfiguration cfgSession = SessionContext.getCurrentSessionConfig();
         
         dba = new HSQLDBAccess();
         
         //read the configuration from the config file
         dba.setConnection(cfgSession.getProperty(
                           "/application/securitymanager/database/url"));
         dba.setUser(cfgSession.getProperty(
                           "/application/securitymanager/database/username"));
         dba.setPassword(cfgSession.getProperty(
                           "/application/securitymanager/database/password"));
         dba.open();
               
         put("dBAccess", dba);
      }
      
      return dba;
   }   
   
   /**
    * Gets the source code access object.
    *
    * @return the source access object
    */
   public SourceCode getSourceCode()
   {
      SourceCode sc = (SourceCode)get("sourceCode");
      
      if (sc == null)
      {
         sc = new SourceCode();
         
         put("sourceCode", sc);
      }
      
      return sc;
   }
   
}   // Session

We derive from Application to receive full access to the methods and objects of the super class. The derivation of GenericBean ensures the availability of objects.

Each SubConnection (Client)), and therefore each WorkScreen, receives its own lifecycle object:

Code: Select all
package com.sibvisions.apps.showcase.frames;

...
...

/**
 * The <code>Educations</code> class is the life-cycle object for <code>EducationsFrame</code>.
 */
public class Educations extends Session
{
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // User-defined methods
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   
   /**
    * Returns the educations storage.
    *
    * @return the Educations storage
    * @throws Exception if the initialization throws an error
    */
   public DBStorage getEducations() throws Exception
   {
      DBStorage dbsEducations = (DBStorage)get("educations");
      
      if (dbsEducations == null)
      {
         dbsEducations = new DBStorage();
         dbsEducations.setDBAccess(getDBAccess());
         dbsEducations.setFromClause("V_EDUCATIONS");
         dbsEducations.setWritebackTable("EDUCATIONS");
         dbsEducations.open();
         
         put("educations", dbsEducations);
      }
      
      return dbsEducations;
   }
   
}   // Educations

The lifecycle object is derived from Session to also receive full access to all methods and objects of the super class.

By calling getDBAccess we can asee the advantage of this technique. We open the database connection at a central location and all derivations have access to the connection.

By using this procedure we perform changes at a central location; we can save time and solve dependencies.


GenericBean

The previous example shows that due to the derivations all methods are inherited, but that each instance would usually manage its own objects. We would therefore expect that each instance of Educations creates a new database connection through the call of getDBAccess!

This is the difference between POJO and GenericBean.

Because of the derivation of GenericBean, the server makes sure that all instances are reused. In our example the session Instance is set as the parent at the instantitation of Educations and the Application instance is set as parent of the Session instance. Because of this definition, the method getDBAccess always returns the same database connection.

Another feature of GenericBean is the access to managed objects by their names:

Code: Select all
DBStorage dbsEducations = (DBStorage)get("educations");

We can therefore call either getEducations() or get("educations") and in both cases the same instance is delivered. For this process to work the desired object has to be instatiated and put to the cache:

Code: Select all
dbsEducations = new DBStorage();
dbsEducations.setDBAccess(getDBAccess());
dbsEducations.setFromClause("V_EDUCATIONS");
dbsEducations.setWritebackTable("EDUCATIONS");
dbsEducations.open();
         
put("educations", dbsEducations);


A rather unusual, but economical, approach of the GenericBean is the initialization of objects without get methods. In this case objects are accessed via name only.

Our Educations lifecycle object would be implemented as follows:

Code: Select all
public class Educations extends Session
{
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   // User-defined methods
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   
   /**
    * Initializes the educations storage.
    *
    * @return the educations storage
    * @throws Exception if the initialization throws an error
    */
   @SuppressWarnings("unused")
   private DBStorage initEducations() throws Throwable
   {
       dbsEducations = new DBStorage();
       dbsEducations.setDBAccess(getDBAccess());
       dbsEducations.setFromClause("V_EDUCATIONS");
       dbsEducations.setWritebackTable("EDUCATIONS");
       dbsEducations.open();

       return dbsEducations;
   }         

}   // Educations

Initialization occurs automatically at first access using get("educations"). The name of the method has to be considered: "init" + "Educations" (depends on the object name).

A disadvantage of this method is that derived classes have no overview of the managed objects!
User avatar
Development@SIB
 
Posts: 325
Joined: Mon Sep 28, 2009 1:54 pm

Return to Documentation