org.apache.ojb.broker.util.ExceptionHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ojb.broker.util.ExceptionHelper.java

Source

package org.apache.ojb.broker.util;

/* Copyright 2002-2005 The Apache Software Foundation
 *
 * Licensed 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.
 */

import java.sql.SQLException;
import java.sql.BatchUpdateException;
import java.sql.SQLWarning;

import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.ojb.broker.KeyConstraintViolatedException;
import org.apache.ojb.broker.PersistenceBrokerSQLException;
import org.apache.ojb.broker.core.ValueContainer;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.FieldDescriptor;
import org.apache.ojb.broker.metadata.JdbcTypesHelper;
import org.apache.ojb.broker.util.logging.Logger;

/**
 * A helper class which endorse dealing with exceptions.
 *
 * @version $Id: ExceptionHelper.java,v 1.2.2.3 2005/12/21 22:27:47 tomdz Exp $
 */
abstract public class ExceptionHelper {
    /**
     * Method which support the conversion of {@link java.sql.SQLException} to
     * OJB's runtime exception (with additional message details).
     *
     * @param message The error message to use, if <em>null</em> a standard message is used.
     * @param ex The exception to convert (mandatory).
     * @param sql The used sql-statement or <em>null</em>.
     * @param logger The {@link org.apache.ojb.broker.util.logging.Logger} to log an detailed message
     * to the specified {@link org.apache.ojb.broker.util.logging.Logger} or <em>null</em> to skip logging message.
     * @return A new created {@link org.apache.ojb.broker.PersistenceBrokerSQLException} based on the specified
     *         arguments.
     */
    public static PersistenceBrokerSQLException generateException(String message, SQLException ex, String sql,
            Logger logger) {
        return generateException(message, ex, sql, null, null, logger, null);
    }

    /**
     * Method which support the conversion of {@link java.sql.SQLException} to
     * OJB's runtime exception (with additional message details).
     *
     * @param ex The exception to convert (mandatory).
     * @param sql The used sql-statement or <em>null</em>.
     * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the target object or <em>null</em>.
     * @param logger The {@link org.apache.ojb.broker.util.logging.Logger} to log an detailed message
     * to the specified {@link org.apache.ojb.broker.util.logging.Logger} or <em>null</em> to skip logging message.
     * @param obj The target object or <em>null</em>.
     * @return A new created {@link org.apache.ojb.broker.PersistenceBrokerSQLException} based on the specified
     *         arguments.
     */
    public static PersistenceBrokerSQLException generateException(SQLException ex, String sql, ClassDescriptor cld,
            Logger logger, Object obj) {
        return generateException(ex, sql, cld, null, logger, obj);
    }

    /**
     * Method which support the conversion of {@link java.sql.SQLException} to
     * OJB's runtime exception (with additional message details).
     *
     * @param ex The exception to convert (mandatory).
     * @param sql The used sql-statement or <em>null</em>.
     * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the target object or <em>null</em>.
     * @param values The values set in prepared statement or <em>null</em>.
     * @param logger The {@link org.apache.ojb.broker.util.logging.Logger} to log an detailed message
     * to the specified {@link org.apache.ojb.broker.util.logging.Logger} or <em>null</em> to skip logging message.
     * @param obj The target object or <em>null</em>.
     * @return A new created {@link org.apache.ojb.broker.PersistenceBrokerSQLException} based on the specified
     *         arguments.
     */
    public static PersistenceBrokerSQLException generateException(SQLException ex, String sql, ClassDescriptor cld,
            ValueContainer[] values, Logger logger, Object obj) {
        return generateException(null, ex, sql, cld, values, logger, obj);
    }

    /**
     * Method which support the conversion of {@link java.sql.SQLException} to
     * OJB's runtime exception (with additional message details).
     *
     * @param message The error message to use, if <em>null</em> a standard message is used.
     * @param ex The exception to convert (mandatory).
     * @param sql The used sql-statement or <em>null</em>.
     * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the target object or <em>null</em>.
     * @param values The values set in prepared statement or <em>null</em>.
     * @param logger The {@link org.apache.ojb.broker.util.logging.Logger} to log an detailed message
     * to the specified {@link org.apache.ojb.broker.util.logging.Logger} or <em>null</em> to skip logging message.
     * @param obj The target object or <em>null</em>.
     * @return A new created {@link org.apache.ojb.broker.PersistenceBrokerSQLException} based on the specified
     *         arguments.
     */
    public static PersistenceBrokerSQLException generateException(String message, SQLException ex, String sql,
            ClassDescriptor cld, ValueContainer[] values, Logger logger, Object obj) {
        /*
        X/OPEN codes within class 23:
        23000   INTEGRITY CONSTRAINT VIOLATION
        23001   RESTRICT VIOLATION
        23502   NOT NULL VIOLATION
        23503   FOREIGN KEY VIOLATION
        23505   UNIQUE VIOLATION
        23514   CHECK VIOLATION
        */
        String eol = SystemUtils.LINE_SEPARATOR;
        StringBuffer msg = new StringBuffer(eol);
        eol += "* ";

        if (ex instanceof BatchUpdateException) {
            BatchUpdateException tmp = (BatchUpdateException) ex;
            if (message != null) {
                msg.append("* ").append(message);
            } else {
                msg.append("* BatchUpdateException during execution of sql-statement:");
            }
            msg.append(eol).append("Batch update count is '").append(tmp.getUpdateCounts()).append("'");
        } else if (ex instanceof SQLWarning) {
            if (message != null) {
                msg.append("* ").append(message);
            } else {
                msg.append("* SQLWarning during execution of sql-statement:");
            }
        } else {
            if (message != null) {
                msg.append("* ").append(message);
            } else {
                msg.append("* SQLException during execution of sql-statement:");
            }
        }

        if (sql != null) {
            msg.append(eol).append("sql statement was '").append(sql).append("'");
        }
        String stateCode = null;
        if (ex != null) {
            msg.append(eol).append("Exception message is [").append(ex.getMessage()).append("]");
            msg.append(eol).append("Vendor error code [").append(ex.getErrorCode()).append("]");
            msg.append(eol).append("SQL state code [");

            stateCode = ex.getSQLState();
            if ("23000".equalsIgnoreCase(stateCode))
                msg.append(stateCode).append("=INTEGRITY CONSTRAINT VIOLATION");
            else if ("23001".equalsIgnoreCase(stateCode))
                msg.append(stateCode).append("=RESTRICT VIOLATION");
            else if ("23502".equalsIgnoreCase(stateCode))
                msg.append(stateCode).append("=NOT NULL VIOLATION");
            else if ("23503".equalsIgnoreCase(stateCode))
                msg.append(stateCode).append("=FOREIGN KEY VIOLATION");
            else if ("23505".equalsIgnoreCase(stateCode))
                msg.append(stateCode).append("=UNIQUE VIOLATION");
            else if ("23514".equalsIgnoreCase(stateCode))
                msg.append(stateCode).append("=CHECK VIOLATION");
            else
                msg.append(stateCode);
            msg.append("]");
        }

        if (cld != null) {
            msg.append(eol).append("Target class is '").append(cld.getClassNameOfObject()).append("'");
            FieldDescriptor[] fields = cld.getPkFields();
            msg.append(eol).append("PK of the target object is [");
            for (int i = 0; i < fields.length; i++) {
                try {
                    if (i > 0)
                        msg.append(", ");
                    msg.append(fields[i].getPersistentField().getName());
                    if (obj != null) {
                        msg.append("=");
                        msg.append(fields[i].getPersistentField().get(obj));
                    }
                } catch (Exception ignore) {
                    msg.append(" PK field build FAILED! ");
                }
            }
            msg.append("]");
        }
        if (values != null) {
            msg.append(eol).append(values.length).append(" values performed in statement: ").append(eol);
            for (int i = 0; i < values.length; i++) {
                ValueContainer value = values[i];
                msg.append("[");
                msg.append("jdbcType=").append(JdbcTypesHelper.getSqlTypeAsString(value.getJdbcType().getType()));
                msg.append(", value=").append(value.getValue());
                msg.append("]");
            }
        }
        if (obj != null) {
            msg.append(eol).append("Source object: ");
            try {
                msg.append(obj.toString());
            } catch (Exception e) {
                msg.append(obj.getClass());
            }
        }

        // message string for PB exception
        String shortMsg = msg.toString();

        if (ex != null) {
            // add causing stack trace
            Throwable rootCause = ExceptionUtils.getRootCause(ex);
            if (rootCause == null)
                rootCause = ex;
            msg.append(eol).append("The root stack trace is --> ");
            String rootStack = ExceptionUtils.getStackTrace(rootCause);
            msg.append(eol).append(rootStack);
        }
        msg.append(SystemUtils.LINE_SEPARATOR).append("**");

        // log error message
        if (logger != null)
            logger.error(msg.toString());

        // throw a specific type of runtime exception for a key constraint.
        if ("23000".equals(stateCode) || "23505".equals(stateCode)) {
            throw new KeyConstraintViolatedException(shortMsg, ex);
        } else {
            throw new PersistenceBrokerSQLException(shortMsg, ex);
        }
    }
}