/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.klopotek.utils.log;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import org.apache.log4j.helpers.*;
import org.apache.log4j.spi.*;
/**
This class encapsulate the logic which is necessary to log into a table.
Used by JDBCAppender
Author : Thomas Fenner
@since 1.0
*/
public class JDBCLogger
{
//All columns of the log-table
private ArrayList logcols = null;
//Only columns which will be provided by logging
private String column_list = null;
//Number of all columns
private int num = 0;
//Status for successful execution of method configure()
private boolean isconfigured = false;
//Status for ready to do logging with method append()
private boolean ready = false;
//This message will be filled with a error-string when method ready() failes, and can be got by calling getMsg()
private String errormsg = "";
private Connection con = null;
private Statement stmt = null;
private ResultSet rs = null;
private String table = null;
//Variables for static SQL-statement logging
private String sql = null;
private String new_sql = null;
private String new_sql_part1 = null;
private String new_sql_part2 = null;
private static final String msg_wildcard = "@MSG@";
private int msg_wildcard_pos = 0;
/**
Writes a message into the database table.
Throws an exception, if an database-error occurs !
*/
public void append(String _msg) throws Exception
{
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 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;
}
}
/**
Configures this class, by reading in the structure of the log-table
Throws an exception, if an database-error occurs !
*/
public void configureTable(String _table) throws Exception
{
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;
}
/**
Configures this class, by storing and parsing the given sql-statement.
Throws an exception, if somethings wrong !
*/
public void configureSQL(String _sql) throws Exception
{
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;
}
/**
Sets a connection. Throws an exception, if the connection is not open !
*/
public void setConnection(Connection _con) throws Exception
{
con = _con;
if(!isConnected()) throw new Exception("JDBCLogger::setConnection(), Given connection isnt connected to database !");
}
/**
Sets a columns logtype (LogTypes) and value, which depends on that logtype.
Throws an exception, if the given arguments arent correct !
*/
public void setLogType(String _name, int _logtype, Object _value) throws Exception
{
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