FileDocCategorySizeDatePackage
JDBCLogger.javaAPI DocApache log4j 1.2.1513492Sat Aug 25 00:09:36 BST 2007com.klopotek.utils.log

JDBCLogger

public class JDBCLogger extends Object
This class encapsulate the logic which is necessary to log into a table. Used by JDBCAppender

Author : Thomas Fenner

since
1.0

Fields Summary
private ArrayList
logcols
private String
column_list
private int
num
private boolean
isconfigured
private boolean
ready
private String
errormsg
private Connection
con
private Statement
stmt
private ResultSet
rs
private String
table
private String
sql
private String
new_sql
private String
new_sql_part1
private String
new_sql_part2
private static final String
msg_wildcard
private int
msg_wildcard_pos
Constructors Summary
Methods Summary
public voidappend(java.lang.String _msg)
Writes a message into the database table. Throws an exception, if an database-error occurs !


		      	       	
	     
	
		if(!ready) if(!ready()) throw new Exception("JDBCLogger::append(), Not ready to append !");

      if(sql != null)
      {
      	appendSQL(_msg);
         return;
      }

		LogColumn logcol;

		rs.moveToInsertRow();

		for(int i=0; i<num; i++)
		{
        	logcol = (LogColumn)logcols.get(i);

			if(logcol.logtype == LogType.MSG)
			{
				rs.updateObject(logcol.name, _msg);
			}
			else if(logcol.logtype == LogType.ID)
			{
				rs.updateObject(logcol.name, logcol.idhandler.getID());
			}
			else if(logcol.logtype == LogType.STATIC)
			{
				rs.updateObject(logcol.name, logcol.value);
			}
			else if(logcol.logtype == LogType.TIMESTAMP)
			{
				rs.updateObject(logcol.name, new Timestamp((new java.util.Date()).getTime()));
			}
		}

		rs.insertRow();
	
public voidappendSQL(java.lang.String _msg)
Writes a message into the database using a given sql-statement. Throws an exception, if an database-error occurs !

		if(!ready) if(!ready()) throw new Exception("JDBCLogger::appendSQL(), Not ready to append !");

      if(sql == null) throw new Exception("JDBCLogger::appendSQL(), No SQL-Statement configured !");

      if(msg_wildcard_pos > 0)
      {
			new_sql = new_sql_part1 + _msg + new_sql_part2;
      }
		else new_sql = sql;

      try
      {
			stmt.executeUpdate(new_sql);
      }
      catch(Exception e)
      {
      	errormsg = new_sql;
         throw e;
		}
	
public voidconfigureSQL(java.lang.String _sql)
Configures this class, by storing and parsing the given sql-statement. Throws an exception, if somethings wrong !

   	if(isconfigured) return;

		if(!isConnected()) throw new Exception("JDBCLogger::configureSQL(), Not connected to database !");

		if(_sql == null || _sql.trim().equals("")) throw new Exception("JDBCLogger::configureSQL(), Invalid SQL-Statement !");

		sql = _sql.trim();

      stmt = con.createStatement();

		msg_wildcard_pos = sql.indexOf(msg_wildcard);

      if(msg_wildcard_pos > 0)
      {
			new_sql_part1 = sql.substring(0, msg_wildcard_pos-1) + "'";
         //between the message...
         new_sql_part2 = "'" + sql.substring(msg_wildcard_pos+msg_wildcard.length());
		}

		isconfigured = true;
	
public voidconfigureTable(java.lang.String _table)
Configures this class, by reading in the structure of the log-table Throws an exception, if an database-error occurs !

   	if(isconfigured) return;

		//Fill logcols with META-informations of the table-columns
		stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
		rs = stmt.executeQuery("SELECT * FROM " + _table + " WHERE 1 = 2");

		LogColumn logcol;

		ResultSetMetaData rsmd = rs.getMetaData();

		num = rsmd.getColumnCount();

		logcols = new ArrayList(num);

		for(int i=1; i<=num; i++)
		{
			logcol = new LogColumn();
			logcol.name = rsmd.getColumnName(i).toUpperCase();
			logcol.type = rsmd.getColumnTypeName(i);
			logcol.nullable = (rsmd.isNullable(i) == rsmd.columnNullable);
         logcol.isWritable = rsmd.isWritable(i);
         if(!logcol.isWritable) logcol.ignore = true;
         logcols.add(logcol);
		}

      table = _table;

		isconfigured = true;
	
public java.lang.StringgetErrorMsg()
Return the internal error message stored in instance variable msg.

String r = new String(errormsg); errormsg = null; return r;
public booleanisConfigured()
Return true, if this class is configured, else false.

 return isconfigured;
public booleanisConnected()
Return true, if this connection is open, else false.

   	try
      {
   		return (con != null && !con.isClosed());
      }
      catch(Exception e){return false;}
   
public booleanready()
Return true, if this class is ready to append(), else false. When not ready, a reason-String is stored in the instance-variable msg.

   	if(ready) return true;

		if(!isconfigured){ errormsg = "Not ready to append ! Call configure() first !"; return false;}

      //No need to doing the whole rest...
      if(sql != null)
      {
      	ready = true;
         return true;
      }

		boolean msgcol_defined = false;

		LogColumn logcol;

		for(int i=0; i<num; i++)
		{
      	logcol = (LogColumn)logcols.get(i);

         if(logcol.ignore || !logcol.isWritable) continue;
			if(!logcol.nullable && logcol.logtype == LogType.EMPTY)
         {
         	errormsg = "Not ready to append ! Column " + logcol.name + " is not nullable, and must be specified by setLogType() !";
            return false;
         }
			if(logcol.logtype == LogType.ID && logcol.idhandler == null)
         {
         	errormsg = "Not ready to append ! Column " + logcol.name + " is specified as an ID-column, and a JDBCIDHandler has to be set !";
            return false;
         }
			else if(logcol.logtype == LogType.STATIC && logcol.value == null)
         {
         	errormsg = "Not ready to append ! Column " + logcol.name + " is specified as a static field, and a value has to be set !";
            return false;
         }
         else if(logcol.logtype == LogType.MSG) msgcol_defined = true;
		}

      if(!msgcol_defined) return false;

      //create the column_list
		for(int i=0; i<num; i++)
		{
      	logcol = (LogColumn)logcols.get(i);

			if(logcol.ignore || !logcol.isWritable) continue;

         if(logcol.logtype != LogType.EMPTY)
         {
				if(column_list == null)
            {
            	column_list = logcol.name;
            }
            else column_list += ", " + logcol.name;
         }
		}

      try
      {
			rs = stmt.executeQuery("SELECT " + column_list + " FROM " + table + " WHERE 1 = 2");
		}
      catch(Exception e)
      {
			errormsg = "Not ready to append ! Cannot select columns '" + column_list + "' of table " + table + " !";
      	return false;
      }

		ready = true;

		return true;
	
public voidsetConnection(java.sql.Connection _con)
Sets a connection. Throws an exception, if the connection is not open !

		con = _con;

		if(!isConnected()) throw new Exception("JDBCLogger::setConnection(), Given connection isnt connected to database !");
	
public voidsetLogType(java.lang.String _name, int _logtype, java.lang.Object _value)
Sets a columns logtype (LogTypes) and value, which depends on that logtype. Throws an exception, if the given arguments arent correct !

		if(!isconfigured) throw new Exception("JDBCLogger::setLogType(), Not configured !");

		//setLogType() makes only sense for further configuration of configureTable()
      if(sql != null) return;

      _name = _name.toUpperCase();

		if(_name == null || !(_name.trim().length() > 0)) throw new Exception("JDBCLogger::setLogType(), Missing argument name !");
		if(!LogType.isLogType(_logtype)) throw new Exception("JDBCLogger::setLogType(), Invalid logtype '" + _logtype + "' !");
		if((_logtype != LogType.MSG && _logtype != LogType.EMPTY) && _value == null) throw new Exception("JDBCLogger::setLogType(), Missing argument value !");

  		LogColumn logcol;

		for(int i=0; i<num; i++)
		{
        	logcol = (LogColumn)logcols.get(i);

			if(logcol.name.equals(_name))
			{
         	if(!logcol.isWritable) throw new Exception("JDBCLogger::setLogType(), Column " + _name + " is not writeable !");

				//Column gets the message
				if(_logtype == LogType.MSG)
            {
            	logcol.logtype = _logtype;
               return;
				}
				//Column will be provided by JDBCIDHandler::getID()
				else if(_logtype == LogType.ID)
				{
					logcol.logtype = _logtype;

               try
               {
               	//Try to cast directly Object to JDBCIDHandler
						logcol.idhandler = (JDBCIDHandler)_value;
               }
               catch(Exception e)
               {
               	try
                  {
                  	//Assuming _value is of class string which contains the classname of a JDBCIDHandler
							logcol.idhandler = (JDBCIDHandler)(Class.forName((String)_value).newInstance());
                  }
                  catch(Exception e2)
                  {
							throw new Exception("JDBCLogger::setLogType(), Cannot cast value of class " + _value.getClass() + " to class JDBCIDHandler !");
                  }
               }

               return;
				}

				//Column will be statically defined with Object _value
				else if(_logtype == LogType.STATIC)
				{
					logcol.logtype = _logtype;
					logcol.value = _value;
               return;
				}

				//Column will be provided with a actually timestamp
				else if(_logtype == LogType.TIMESTAMP)
				{
					logcol.logtype = _logtype;
               return;
				}

            //Column will be fully ignored during process.
            //If this column is not nullable, the column has to be filled by a database trigger,
            //else a database error occurs !
            //Columns which are not nullable, but should be not filled, must be explicit assigned with LogType.EMPTY,
            //else a value is required !
				else if(_logtype == LogType.EMPTY)
				{
					logcol.logtype = _logtype;
					logcol.ignore = true;
               return;
				}
			}
		}