org.jbpm.logging.db.JDBCExceptionReporter Maven / Gradle / Ivy
The newest version!
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.jbpm.logging.db;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import org.hibernate.internal.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class JDBCExceptionReporter {
public static final Logger log = LoggerFactory.getLogger(JDBCExceptionReporter.class);
public static final String DEFAULT_EXCEPTION_MSG = "SQL Exception";
public static final String DEFAULT_WARNING_MSG = "SQL Warning";
private JDBCExceptionReporter() {}
/**
* Standard (legacy) behavior for logging warnings associated with a JDBC {@link Connection} and clearing them.
*
* Calls {@link #handleAndClearWarnings(Connection, WarningHandler)} using {@link #STANDARD_WARNING_HANDLER}
*
* @param connection The JDBC connection potentially containing warnings
*/
public static void logAndClearWarnings(Connection connection) {
handleAndClearWarnings( connection, STANDARD_WARNING_HANDLER );
}
/**
* General purpose handling of warnings associated with a JDBC {@link Connection}.
*
* @param connection The JDBC connection potentially containing warnings
* @param handler The handler for each individual warning in the stack.
*
* @see #walkWarnings
*/
@SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
public static void handleAndClearWarnings(Connection connection, WarningHandler handler) {
try {
walkWarnings( connection.getWarnings(), handler );
}
catch ( SQLException sqle ) {
//workaround for WebLogic
log.debug( "could not log warnings", sqle );
}
try {
//Sybase fail if we don't do that, sigh...
connection.clearWarnings();
}
catch ( SQLException sqle ) {
log.debug( "could not clear warnings", sqle );
}
}
/**
* General purpose handling of warnings associated with a JDBC {@link Statement}.
*
* @param statement The JDBC statement potentially containing warnings
* @param handler The handler for each individual warning in the stack.
*
* @see #walkWarnings
*/
@SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
public static void handleAndClearWarnings(Statement statement, WarningHandler handler) {
try {
walkWarnings( statement.getWarnings(), handler );
}
catch ( SQLException sqle ) {
//workaround for WebLogic
log.debug( "could not log warnings", sqle );
}
try {
//Sybase fail if we don't do that, sigh...
statement.clearWarnings();
}
catch ( SQLException sqle ) {
log.debug( "could not clear warnings", sqle );
}
}
/**
* Log the given warning and all of its nested warnings, preceded with the {@link #DEFAULT_WARNING_MSG default message}
*
* @param warning The warning to log
*
* @deprecated Use {@link #walkWarnings} instead
*/
@Deprecated()
@SuppressWarnings({ "UnusedDeclaration" })
public static void logWarnings(SQLWarning warning) {
walkWarnings( warning, STANDARD_WARNING_HANDLER );
}
/**
* Log the given warning and all of its nested warnings, preceded with the given message
*
* @param warning The warning to log
* @param message The prologue message
*
* @deprecated Use {@link #walkWarnings} instead
*/
@Deprecated()
@SuppressWarnings({ "UnusedDeclaration" })
public static void logWarnings(SQLWarning warning, String message) {
final WarningHandler handler = StringHelper.isNotEmpty(message)
? new StandardWarningHandler( message )
: STANDARD_WARNING_HANDLER;
walkWarnings( warning, handler );
}
/**
* Contract for handling {@link SQLWarning warnings}
*/
public static interface WarningHandler {
/**
* Should processing be done? Allows short-circuiting if not.
*
* @return True to process warnings, false otherwise.
*/
public boolean doProcess();
/**
* Prepare for processing of a {@link SQLWarning warning} stack.
*
* Note that the warning here is also the first passed to {@link #handleWarning}
*
* @param warning The first warning in the stack.
*/
public void prepare(SQLWarning warning);
/**
* Handle an individual warning in the stack.
*
* @param warning The warning to handle.
*/
public void handleWarning(SQLWarning warning);
}
/**
* Basic support for {@link WarningHandler} implementations which log
*/
public static abstract class WarningHandlerLoggingSupport implements WarningHandler {
public final void handleWarning(SQLWarning warning) {
StringBuffer buf = new StringBuffer(30)
.append( "SQL Warning Code: ").append( warning.getErrorCode() )
.append( ", SQLState: ").append( warning.getSQLState() );
logWarning( buf.toString(), warning.getMessage() );
}
/**
* Delegate to log common details of a {@link SQLWarning warning}
*
* @param description A description of the warning
* @param message The warning message
*/
protected abstract void logWarning(String description, String message);
}
public static class StandardWarningHandler extends WarningHandlerLoggingSupport implements Serializable {
private static final long serialVersionUID = 1L;
private final String introMessage;
public StandardWarningHandler(String introMessage) {
this.introMessage = introMessage;
}
public boolean doProcess() {
return log.isWarnEnabled();
}
public void prepare(SQLWarning warning) {
log.debug( introMessage, warning );
}
@Override
protected void logWarning(String description, String message) {
log.warn( description );
log.warn( message );
}
}
public static StandardWarningHandler STANDARD_WARNING_HANDLER = new StandardWarningHandler( DEFAULT_WARNING_MSG );
public static void walkWarnings(SQLWarning warning, WarningHandler handler) {
if ( warning == null || handler.doProcess() ) {
return;
}
handler.prepare( warning );
while ( warning != null ) {
handler.handleWarning( warning );
warning = warning.getNextWarning();
}
}
public static void logExceptions(Exception ex) {
logExceptions(ex, null);
}
public static void logExceptions(Exception ex, String message) {
if ( log.isErrorEnabled() ) {
if ( log.isDebugEnabled() ) {
message = StringHelper.isNotEmpty(message) ? message : DEFAULT_EXCEPTION_MSG;
log.debug( message, ex );
}
if (ex instanceof SQLException) {
SQLException sqlEx = ((SQLException)ex);
while (sqlEx != null) {
StringBuffer buf = new StringBuffer(30)
.append( "SQL Error: " )
.append( sqlEx.getErrorCode() )
.append( ", SQLState: " )
.append( sqlEx.getSQLState() );
log.warn( buf.toString() );
log.error( ex.getMessage() );
sqlEx = sqlEx.getNextException();
}
} else {
log.error( ex.getMessage() );
}
}
}
}