Job Queue Introduction   -   Job Queue Architecture   -   IndyJUG Home

Summary Class Structure

 

Utilizes the Reflection Class to inspect the classes for certain data types. 

 

According to Javasoft Tutorial website, Reflection Class gives the ability to:

You can identify a class's fields by invoking the getFields method on a Class object. The getFields method returns an array of Field objects containing one object per accessible public field.

A public field is accessible if it is a member of either:

·         this class

·         a superclass of this class

·         an interface implemented by this class

·         an interface extended from an interface implemented by this class

The methods provided by the Field (in the API reference documentation)class allow you to retrieve the field's name, type, and set of modifiers. You can even get and set the value of a field, as described in the sections Getting Field Values and Setting Field Values.

The following program prints the names and types of fields belonging to the GridBagConstraints class. Note that the program first retrieves the Field objects for the class by calling getFields, and then invokes the getName and getType methods on each of these Field objects.

import java.lang.reflect.*;
import java.awt.*;
 
class SampleField {
   public static void main(String[] args) {
      GridBagConstraints g = new GridBagConstraints();
      printFieldNames(g);
   }
   static void printFieldNames(Object o) {
      Class c = o.getClass();
      Field[] publicFields = c.getFields();
      for (int i = 0; i < publicFields.length; i++) {
         String fieldName = publicFields[i].getName();
         Class typeClass = publicFields[i].getType();
         String fieldType = typeClass.getName();
         System.out.println("Name: " + fieldName + 
           ", Type: " + fieldType);
         }
      }
}
A truncated listing of the output generated by the preceding program follows: 
Name: RELATIVE, Type: int, Name: REMAINDER, Type: int, Name: NONE, Type: int, Name: BOTH, Type: int, Name: HORIZONTAL, Type: int, Name: VERTICAL, Type: int
 

How we use the Reflection class:

 

DBAttribute is an abstract base class that gets all other data types built from it.

 

DBVarchar, DBInt, etc all derive from DBAttribute so that inspection of the class can easily identify those variables which are of DBAttribute types.

 

SqlStmt class utilizes DBAttribute class types to define a class that matches the table layout that will allow the autogeneration of a SQL statement for generic types of table processing.

 

SqlStmt contains the SQL syntax for multi-database platforms as well as specialty processing.  When SqlStmt builds the SQL String, it looks for instanceof DBAttributes only.  This allows the fields and keys to be distinguished from other items like niceNames, table name, etc..

 

Each table like JobQueue has minimal database specific logic and is the final derivative used to manipulate the tables.

 

Advantages/Use:

Easier porting from database to database

Utilization of automatic SQL generation routines

Table classes with associated logic, more than just MetaData definitions

No third party tools involved for licensing or future conversion issues

Quick development times by reducing the need to generate typical SQL

Possible to dynamically create table manipulation programs

 

Base Abstract Class DBAttribute

 

package ebiz.db;
import java.io.Serializable;
import ebiz.util.*;
 
public abstract class DBAttribute implements Serializable
{
    public String niceName;
    public String searchOp = "=";  // Used by DBRow.startList() for constructing query
    public boolean isAKey = false;
    public boolean allowNull = false;
    public boolean isAListBoxValue = false;
    public String separator = ",";
    public boolean useDefaultOnNull = false;
    public String defaultValue = null;
 
    public abstract void set(String s);
    public abstract String getSQLType();
    public abstract String getSQLForm();
    public abstract String get();
    public void setKey() { isAKey = true; }
    public void notKey() { isAKey = false; }
    public void setAllowNull(boolean b) { allowNull = b; }
    public boolean getAllowNull() { return allowNull; }
    public void setDefaultValue(String s) { defaultValue = s; }
    
    public void defaultOnNull(boolean flag)
    {
        useDefaultOnNull = flag;
    }
 
    public void setSearchOp(String op) { searchOp = op; }
    public String getSearchOp() { return searchOp; } 
}

 

Derived class DBVarchar

 

package ebiz.db;
 
public class DBVarchar extends DBAttribute
{
  int size;
  String attrProperties;
  String value;
 
  public DBVarchar(int size)
  {
    this.size = size;
  }
 
  public DBVarchar(int size, String attrProperties)
  { 
    this.size = size;
    this.attrProperties = attrProperties;
  }
 
  public String getSQLType()
  {
    return new String("varchar("+size+")" + 
                      (attrProperties == null ? "" : " "+attrProperties));
  }
 
  public String get()
  {
    return value == null ? null : new String(value);
  }
 
  public String getSQLForm()
  {
    int index, sub = 0;
 
    if ((value != null) && (index = value.indexOf("'")) != -1){
        String temp = new String("'");
        do {
            if (index == -1)
                break;
            temp += value.substring(sub, index+1) + "'";
            sub = index + 1;
        } while ((value != null) && (index = value.indexOf("'", sub)) != -1);
        return temp + value.substring(sub) + "'";
    }
    return value == null ? "null" : "'"+value+"'";
  }
 
  public void set(String s)
  {
    if (s == null) { value = null; return; }
    if (s.length() > size) {
      value = s.substring(0,size);
    } else {
      value = s;
    }
  }
 
  public String toString() {
    return get();
  }
 
  public int getSize() 
  {
    return size;
  }
 
  public void validate() throws FormFormatException {};
}
 
SqlStmt Class which uses DBAttribute derived types
 
package ebiz.db;
import java.lang.reflect.Field;
import java.io.Serializable;
import java.lang.Math;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
 
import ebiz.util.Log;
import ebiz.com.*;
 
public abstract class SqlStmt implements Serializable
{       
    private boolean isDBAttribute(Field f)
    {
        //Log.println("isDBAttribute "+f.getName()+"?");
        Class c = f.getType();        
        while (c != null) {
            //Log.println("  Check class "+c.toString());
            try {
                if (c.equals(Class.forName("ebiz.db.DBAttribute"))) return true;
                c = c.getSuperclass();
            } catch (ClassNotFoundException e) {
                //e.printStackTrace();
                return false;
            }
        }
        return false;
    }
 
   public String getInsertStatement() throws Exception
    {
        Field[] f = this.getClass().getFields();
        String prefix = getPrefix();
        String values = null;
        String list = null;
        for (int i=0; i<f.length; i++) {
            Object o = f[i].get(this);
            if (o != null && o instanceof DBAttribute &&
                !(o instanceof DBAutoInt) && !(o instanceof DBAutoShort)) {
                DBAttribute a = (DBAttribute)o;                
                String aval = a.getSQLForm();
                if ( !(aval.equals("null") && a.useDefaultOnNull) ) {
                    list = (list == null ? "" : list+", ")+prefix+f[i].getName();
                    values = (values == null ? "" : values+", ")+"  "+aval;
                }
            }
        }
        return "insert into " + getTableName() +  
            " (" + list + ") values (" + values + ") ";
    }
    
    public String getTableName() { 
        try {
            String tablename=this.getClass().getField("tableName").get(null).toString();
            return tablename;
        } catch (Exception e) {
            return null;
        }
        //      String tableName = this.getClass().getName();
        // May need to modify this string if class is a Com extension of table class,
        // e.g., the Usr class is extended by UsrCom, but still want just Usr.
        //        return tableName;
    }
   
    /** Get the update and pass in a custom where statement */
    public String getUpdateStatement(String wc, boolean disallowNulls) throws Exception {
        Field[] f = this.getClass().getFields();
        String prefix = getPrefix();
        String list = null; 
    for (int i=0; i<f.length; i++) 
    {
        Object o = f[i].get(this);
        if (o != null && o instanceof DBAttribute && !(o instanceof DBAutoInt)) 
        {
            DBAttribute a = (DBAttribute)o;
            if (!a.isKey())
            {
                String val = a.getSQLForm();
                if (!(val.equals("null") && disallowNulls))
                {
                    if (a instanceof DBTime && val.equals("null") && a.useDefaultOnNull)
                        val = "sysdate";
                    list=(list==null ? "" : list+",")+"  "+prefix+f[i].getName()+"="+val;
                }
            }
        }
    }
        return "update " + getTableName() + " set" + list + wc;
    }
    
 
    public void populate(Hashtable t) throws Exception {
        Field[] f = this.getClass().getFields();
        for (int i = 0; i < f.length; ++i) {
            Object o = f[i].get(this);
            if (o != null && o instanceof DBAttribute) {
                DBAttribute a = (DBAttribute) o;
                String s = (String) t.get(f[i].getName());
                //Log.println("Field: " + f[i].getName() + ", Value=[" + s + "]");
                if (s != null && s.length() > 0) a.set(s);
            }
        }
    }
 
        public String getWhereClause(boolean keysOnly) throws Exception {
        String stmt = null;
        Field[] f = this.getClass().getFields();
        String prefix = getPrefix();
        for (int i=0; i<f.length; i++) {
            Object o = f[i].get(this);
            if (o != null && o instanceof DBAttribute) {
                DBAttribute a = (DBAttribute)o;
                if (keysOnly) {
                    if (a.isKey() && !a.getSQLForm().equals("null")) {
                        stmt = (stmt == null ? " where " : stmt+" and ") +
                            prefix+f[i].getName()+" = "+a.getSQLForm();
                    }
                }
                else {
                    if (!a.getSQLForm().equals("null")) {
                        stmt = (stmt == null ? " where " : stmt+" and ") +
                            prefix+f[i].getName()+" = "+a.getSQLForm();
                    }
                }
            }
        }
        if (stmt == null) stmt = "";
        return stmt;
    }
       
 
}

 

 

JobQueue derived from SqlStmt

 

package mottables;
import java.lang.reflect.Field;
import java.io.*;
import ebiz.db.*;
 
public class JobQueue extends SqlStmt
{       
    public DBInt        JobQueueId          = new DBInt();
    public DBVarchar    JobName             = new DBVarchar(50);
    public DBInt        UserId              = new DBInt();
    public DBShort      JobQueueStatusId    = new DBShort();
    public DBVarchar    ProgramName         = new DBVarchar(50);
    public DBTime       EntryDate           = new DBTime();
    public DBTime       StartDate           = new DBTime();
    public DBTime       EndDate             = new DBTime();
    public DBVarchar    Parameters          = new DBVarchar(2048);
    public DBVarchar    Message             = new DBVarchar(80);
    public DBShort      JobQueuePriorityId  = new DBShort();
    public DBTime       UpdateTmstmp        = new DBTime();
    public DBInt        LastUpdater         = new DBInt();
    public DBInt        ExecMethod          = new DBInt();
    public DBVarchar    CompletionStatus    = new DBVarchar(80);
        
    public static final String tableName = "JobQueue";
 
    public JobQueue() {
            JobQueueId.setKey();
            JobQueueId.niceName = "Job Queue Id";
            JobName.niceName = "Job Name";
            UserId.niceName = "User Id";
            JobQueueStatusId.niceName = "Job Queue Status Id";
            ProgramName.niceName = "Job's Program Name";
            EntryDate.niceName = "Job's Entry Date";
            StartDate.niceName = "Job's Start Processing Date";
            EndDate.niceName = "Job's End Processing Date";
            Parameters.niceName = "Program's Parameters";
            Message.niceName = "User Message";
            JobQueuePriorityId.niceName = "Job Queue Priority Id";
            UpdateTmstmp.niceName = "Update Timestamp";
            LastUpdater.niceName = "Last Updater ";
            ExecMethod.niceName = "Method to Invoke the Job ";
            CompletionStatus.niceName = "Results of the Job ";
    } 
    
} // End of Program
 
Code snippet of use of JobQueue Class
 
           JobQueue jq = new JobQueue();
            jq.UserId.set(userid);
            jq.JobQueueStatusId.set(status);
            …
            jq.ExecMethod.set(execmethod);
 
            MessageCenter mc = new MessageCenter(codebase,true);
            try {
                if (!mc.insertRecord(jq)) {
                    return(mc.getDbResponse());
                }
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
                return(ex.getMessage());
            };