/*
 * 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.
 */
/*
 * $Id$
 */

package org.apache.xalan.lib.sql;

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

import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMManager;

/**
 *
 * A base class that will convert an exception into an XML stream
 * that can be returned in place of the standard result. The XML
 * format returned is a follows.
 *
 * <ext-error>
 *  <message> The Message for a generic error </message>
 *  <sql-error>
 *    <message> SQL Message from the Exception thrown </message>
 *    <code> SQL Error Code </stack>
 *  </sql-error>
 * <ext-error>
 *
 */

/**
 * The SQL Document is the main controlling class the executesa SQL Query
 */
public class SQLErrorDocument extends DTMDocument
{
  /**
   */
  private static final String S_EXT_ERROR = "ext-error";
  /**
   */
  private static final String S_SQL_ERROR = "sql-error";
  /**
   */
  private static final String S_MESSAGE = "message";
  /**
   */
  private static final String S_CODE = "code";

  /**
   */
  private static final String S_STATE = "state";

  /**
   */
  private static final String S_SQL_WARNING = "sql-warning";

  /**
   */
  private int m_ErrorExt_TypeID = DTM.NULL;
  /**
   */
  private int m_Message_TypeID = DTM.NULL;
  /**
   */
  private int m_Code_TypeID = DTM.NULL;

  /**
   */
  private int m_State_TypeID = DTM.NULL;

  /**
   */
  private int m_SQLWarning_TypeID = DTM.NULL;

  /**
   */
  private int m_SQLError_TypeID = DTM.NULL;

  /**
   */
  private int m_rootID = DTM.NULL;
  /**
   */
  private int m_extErrorID = DTM.NULL;
  /**
   */
  private int m_MainMessageID = DTM.NULL;

  /**
   * Build up an SQLErrorDocument that includes the basic error information
   * along with the Extended SQL Error information.
   * @param mgr
   * @param ident
   * @param error
   */
  public SQLErrorDocument( DTMManager mgr, int ident, SQLException error )
  {
    super(mgr, ident);

    createExpandedNameTable();
    buildBasicStructure(error);

    int sqlError = addElement(2, m_SQLError_TypeID, m_extErrorID, m_MainMessageID);
    int element = DTM.NULL;

    element = addElementWithData(
      new Integer(error.getErrorCode()), 3,
      m_Code_TypeID, sqlError, element);

    element = addElementWithData(
      error.getLocalizedMessage(), 3,
      m_Message_TypeID, sqlError, element);

//    this.dumpDTM();
  }


  /**
   * Build up an Error Exception with just the Standard Error Information
   * @param mgr
   * @param ident
   * @param error
   */
  public SQLErrorDocument( DTMManager mgr, int ident, Exception error )
  {
    super(mgr, ident);
    createExpandedNameTable();
    buildBasicStructure(error);
  }

  /**
   * Build up an Error Exception with just the Standard Error Information
   * @param mgr
   * @param ident
   * @param error
   */
  public SQLErrorDocument(DTMManager mgr, int ident, Exception error, SQLWarning warning, boolean full)
  {
    super(mgr, ident);
    createExpandedNameTable();
    buildBasicStructure(error);

	SQLException se = null;
	int prev = m_MainMessageID;
	boolean inWarnings = false;

	if ( error != null && error instanceof SQLException )
		se = (SQLException)error;
	else if ( full && warning != null )
	{
		se = warning;
		inWarnings = true;
	}

	while ( se != null )
	{
	    int sqlError = addElement(2, inWarnings ? m_SQLWarning_TypeID : m_SQLError_TypeID, m_extErrorID, prev);
		prev = sqlError;
    	int element = DTM.NULL;

	    element = addElementWithData(
	      new Integer(se.getErrorCode()), 3,
	      m_Code_TypeID, sqlError, element);

	    element = addElementWithData(
	      se.getLocalizedMessage(), 3,
	      m_Message_TypeID, sqlError, element);

		if ( full )
		{
			String state = se.getSQLState();
			if ( state != null && state.length() > 0 )
			    element = addElementWithData(
			      state, 3,
			      m_State_TypeID, sqlError, element);

			if ( inWarnings )
				se = ((SQLWarning)se).getNextWarning();
			else
				se = se.getNextException();
		}
		else
			se = null;
	}
  }

  /**
   * Build up the basic structure that is common for each error.
   * @param e
   * @return
   */
  private void buildBasicStructure( Exception e )
  {
    m_rootID = addElement(0, m_Document_TypeID, DTM.NULL, DTM.NULL);
    m_extErrorID = addElement(1, m_ErrorExt_TypeID, m_rootID, DTM.NULL);
    m_MainMessageID = addElementWithData
      (e != null ? e.getLocalizedMessage() : "SQLWarning", 2, m_Message_TypeID, m_extErrorID, DTM.NULL);
  }

  /**
   * Populate the Expanded Name Table with the Node that we will use.
   * Keep a reference of each of the types for access speed.
   * @return
   */
  protected void createExpandedNameTable( )
  {

    super.createExpandedNameTable();

    m_ErrorExt_TypeID =
      m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_EXT_ERROR, DTM.ELEMENT_NODE);

    m_SQLError_TypeID =
      m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_SQL_ERROR, DTM.ELEMENT_NODE);

    m_Message_TypeID =
      m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_MESSAGE, DTM.ELEMENT_NODE);

    m_Code_TypeID =
      m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_CODE, DTM.ELEMENT_NODE);

    m_State_TypeID =
      m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_STATE, DTM.ELEMENT_NODE);

    m_SQLWarning_TypeID =
      m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_SQL_WARNING, DTM.ELEMENT_NODE);
  }

}
