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
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
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; } }
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; } }
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()); };