001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: SQLErrorDocument.java 468638 2006-10-28 06:52:06Z minchau $
020 */
021
022 package org.apache.xalan.lib.sql;
023
024 import java.sql.SQLException;
025 import java.sql.SQLWarning;
026
027 import org.apache.xml.dtm.DTM;
028 import org.apache.xml.dtm.DTMManager;
029
030 /**
031 *
032 * A base class that will convert an exception into an XML stream
033 * that can be returned in place of the standard result. The XML
034 * format returned is a follows.
035 *
036 * <ext-error>
037 * <message> The Message for a generic error </message>
038 * <sql-error>
039 * <message> SQL Message from the Exception thrown </message>
040 * <code> SQL Error Code </stack>
041 * </sql-error>
042 * <ext-error>
043 *
044 */
045
046 /**
047 * The SQL Document is the main controlling class the executesa SQL Query
048 */
049 public class SQLErrorDocument extends DTMDocument
050 {
051 /**
052 */
053 private static final String S_EXT_ERROR = "ext-error";
054 /**
055 */
056 private static final String S_SQL_ERROR = "sql-error";
057 /**
058 */
059 private static final String S_MESSAGE = "message";
060 /**
061 */
062 private static final String S_CODE = "code";
063
064 /**
065 */
066 private static final String S_STATE = "state";
067
068 /**
069 */
070 private static final String S_SQL_WARNING = "sql-warning";
071
072 /**
073 */
074 private int m_ErrorExt_TypeID = DTM.NULL;
075 /**
076 */
077 private int m_Message_TypeID = DTM.NULL;
078 /**
079 */
080 private int m_Code_TypeID = DTM.NULL;
081
082 /**
083 */
084 private int m_State_TypeID = DTM.NULL;
085
086 /**
087 */
088 private int m_SQLWarning_TypeID = DTM.NULL;
089
090 /**
091 */
092 private int m_SQLError_TypeID = DTM.NULL;
093
094 /**
095 */
096 private int m_rootID = DTM.NULL;
097 /**
098 */
099 private int m_extErrorID = DTM.NULL;
100 /**
101 */
102 private int m_MainMessageID = DTM.NULL;
103
104 /**
105 * Build up an SQLErrorDocument that includes the basic error information
106 * along with the Extended SQL Error information.
107 * @param mgr
108 * @param ident
109 * @param error
110 */
111 public SQLErrorDocument( DTMManager mgr, int ident, SQLException error )
112 {
113 super(mgr, ident);
114
115 createExpandedNameTable();
116 buildBasicStructure(error);
117
118 int sqlError = addElement(2, m_SQLError_TypeID, m_extErrorID, m_MainMessageID);
119 int element = DTM.NULL;
120
121 element = addElementWithData(
122 new Integer(error.getErrorCode()), 3,
123 m_Code_TypeID, sqlError, element);
124
125 element = addElementWithData(
126 error.getLocalizedMessage(), 3,
127 m_Message_TypeID, sqlError, element);
128
129 // this.dumpDTM();
130 }
131
132
133 /**
134 * Build up an Error Exception with just the Standard Error Information
135 * @param mgr
136 * @param ident
137 * @param error
138 */
139 public SQLErrorDocument( DTMManager mgr, int ident, Exception error )
140 {
141 super(mgr, ident);
142 createExpandedNameTable();
143 buildBasicStructure(error);
144 }
145
146 /**
147 * Build up an Error Exception with just the Standard Error Information
148 * @param mgr
149 * @param ident
150 * @param error
151 */
152 public SQLErrorDocument(DTMManager mgr, int ident, Exception error, SQLWarning warning, boolean full)
153 {
154 super(mgr, ident);
155 createExpandedNameTable();
156 buildBasicStructure(error);
157
158 SQLException se = null;
159 int prev = m_MainMessageID;
160 boolean inWarnings = false;
161
162 if ( error != null && error instanceof SQLException )
163 se = (SQLException)error;
164 else if ( full && warning != null )
165 {
166 se = warning;
167 inWarnings = true;
168 }
169
170 while ( se != null )
171 {
172 int sqlError = addElement(2, inWarnings ? m_SQLWarning_TypeID : m_SQLError_TypeID, m_extErrorID, prev);
173 prev = sqlError;
174 int element = DTM.NULL;
175
176 element = addElementWithData(
177 new Integer(se.getErrorCode()), 3,
178 m_Code_TypeID, sqlError, element);
179
180 element = addElementWithData(
181 se.getLocalizedMessage(), 3,
182 m_Message_TypeID, sqlError, element);
183
184 if ( full )
185 {
186 String state = se.getSQLState();
187 if ( state != null && state.length() > 0 )
188 element = addElementWithData(
189 state, 3,
190 m_State_TypeID, sqlError, element);
191
192 if ( inWarnings )
193 se = ((SQLWarning)se).getNextWarning();
194 else
195 se = se.getNextException();
196 }
197 else
198 se = null;
199 }
200 }
201
202 /**
203 * Build up the basic structure that is common for each error.
204 * @param e
205 * @return
206 */
207 private void buildBasicStructure( Exception e )
208 {
209 m_rootID = addElement(0, m_Document_TypeID, DTM.NULL, DTM.NULL);
210 m_extErrorID = addElement(1, m_ErrorExt_TypeID, m_rootID, DTM.NULL);
211 m_MainMessageID = addElementWithData
212 (e != null ? e.getLocalizedMessage() : "SQLWarning", 2, m_Message_TypeID, m_extErrorID, DTM.NULL);
213 }
214
215 /**
216 * Populate the Expanded Name Table with the Node that we will use.
217 * Keep a reference of each of the types for access speed.
218 * @return
219 */
220 protected void createExpandedNameTable( )
221 {
222
223 super.createExpandedNameTable();
224
225 m_ErrorExt_TypeID =
226 m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_EXT_ERROR, DTM.ELEMENT_NODE);
227
228 m_SQLError_TypeID =
229 m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_SQL_ERROR, DTM.ELEMENT_NODE);
230
231 m_Message_TypeID =
232 m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_MESSAGE, DTM.ELEMENT_NODE);
233
234 m_Code_TypeID =
235 m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_CODE, DTM.ELEMENT_NODE);
236
237 m_State_TypeID =
238 m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_STATE, DTM.ELEMENT_NODE);
239
240 m_SQLWarning_TypeID =
241 m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_SQL_WARNING, DTM.ELEMENT_NODE);
242 }
243
244 }