1 | /* |
2 | |
3 | Derby - Class org.apache.derby.iapi.error.StandardException |
4 | |
5 | Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.iapi.error; |
22 | |
23 | import org.apache.derby.iapi.reference.SQLState; |
24 | |
25 | import org.apache.derby.impl.jdbc.EmbedSQLException; |
26 | import org.apache.derby.iapi.error.ExceptionSeverity; |
27 | import org.apache.derby.iapi.services.i18n.MessageService; |
28 | import org.apache.derby.iapi.services.sanity.SanityManager; |
29 | |
30 | import java.sql.SQLException; |
31 | import java.sql.SQLWarning; |
32 | |
33 | /** |
34 | StandardException is the root of all exceptions that are handled |
35 | in a standard fashion by the database code, mainly in the language code. |
36 | <P> |
37 | This class is abstract to ensure that an implementation only throws |
38 | a specific exception (e.g. TransactionException) which is a sub-class |
39 | <P> |
40 | A method in an iterface in a protocol under com.ibm.db2j.protocol.Database must |
41 | only throw a StandardException (if it needs to throw an exception). |
42 | This indicates that the method can throw an exception and therefore its |
43 | caller must ensure that any resources it allocates will be cleaned up |
44 | in the event of an exception in the StandardException hierarchy. |
45 | <P> |
46 | Implementations of methods that throw StandardException can have throws |
47 | clause that are more specific than StandardException. |
48 | */ |
49 | |
50 | public class StandardException extends Exception |
51 | { |
52 | public static final int REPORT_DEFAULT = 0; |
53 | public static final int REPORT_NEVER = 1; |
54 | public static final int REPORT_ALWAYS = 2; |
55 | |
56 | /* |
57 | * Exception State |
58 | */ |
59 | private Throwable nestedException; |
60 | private transient Object[] arguments; |
61 | private int severity; |
62 | private String textMessage; |
63 | private String sqlState; |
64 | private transient int report; |
65 | |
66 | /* |
67 | ** End of constructors |
68 | */ |
69 | |
70 | protected StandardException(String messageID) |
71 | { |
72 | this(messageID, (Throwable) null, (Object[]) null); |
73 | |
74 | } |
75 | |
76 | protected StandardException(String messageID, Object[] args) |
77 | { |
78 | this(messageID, (Throwable) null, args); |
79 | } |
80 | |
81 | protected StandardException(String messageID, Throwable t, Object[] args) |
82 | { |
83 | super(messageID); |
84 | |
85 | this.severity = getSeverityFromIdentifier(messageID); |
86 | this.sqlState = getSQLStateFromIdentifier(messageID); |
87 | this.nestedException = t; |
88 | this.arguments = args; |
89 | |
90 | if (SanityManager.DEBUG) |
91 | { |
92 | SanityManager.ASSERT(messageID != null, |
93 | "StandardException with no messageID"); |
94 | } |
95 | } |
96 | |
97 | /** |
98 | * This constructor is used when we already have the |
99 | * message text. |
100 | * |
101 | * @param sqlState the sql state of the message |
102 | * @param text the text of the message |
103 | */ |
104 | private StandardException(String sqlState, String text) |
105 | { |
106 | this(sqlState); |
107 | textMessage = text; |
108 | } |
109 | |
110 | /* |
111 | ** End of constructors |
112 | */ |
113 | /** |
114 | * Sets the arguments for this exception. |
115 | */ |
116 | private final void setArguments(Object[] arguments) |
117 | { |
118 | this.arguments = arguments; |
119 | } |
120 | |
121 | /** |
122 | * Returns the arguments for this exception, |
123 | * if there are any. |
124 | */ |
125 | public final Object[] getArguments() |
126 | { |
127 | return arguments; |
128 | } |
129 | |
130 | /** |
131 | * Sets the nested exception for this exception. |
132 | */ |
133 | public final void setNestedException(Throwable nestedException) |
134 | { |
135 | this.nestedException = nestedException; |
136 | } |
137 | |
138 | /** |
139 | * Returns the nested exception for this exception, |
140 | * if there is one. |
141 | */ |
142 | public final Throwable getNestedException() |
143 | { |
144 | return nestedException; |
145 | } |
146 | |
147 | /** |
148 | Yes, report me. Errors that need this method to return |
149 | false are in the minority. |
150 | */ |
151 | public final int report() { |
152 | return report; |
153 | } |
154 | |
155 | /** |
156 | Set my report type. |
157 | */ |
158 | public final void setReport(int report) { |
159 | this.report = report; |
160 | } |
161 | |
162 | public final void setSeverity(int severity) { |
163 | this.severity = severity; |
164 | } |
165 | |
166 | |
167 | public final int getSeverity() { |
168 | return severity; |
169 | } |
170 | |
171 | public final int getErrorCode() { |
172 | return severity; |
173 | } |
174 | |
175 | /** |
176 | Return the 5 character SQL State. |
177 | If you need teh identifier that was used to create the |
178 | message, then use getMessageId(). getMessageId() will return the |
179 | string that corresponds to the field in org.apache.derby.iapi.reference.SQLState. |
180 | */ |
181 | public final String getSQLState() |
182 | { |
183 | return sqlState; |
184 | } |
185 | |
186 | /** |
187 | Convert a message identifer from org.apache.derby.iapi.reference.SQLState to |
188 | a SQLState five character string. |
189 | * @param messageID - the sql state id of the message from cloudscape |
190 | * @return String - the 5 character code of the SQLState ID to returned to the user |
191 | */ |
192 | public static String getSQLStateFromIdentifier(String messageID) { |
193 | |
194 | if (messageID.length() == 5) |
195 | return messageID; |
196 | return messageID.substring(0, 5); |
197 | } |
198 | |
199 | /** |
200 | Get the severity given a message identifier from org.apache.derby.iapi.reference.SQLState. |
201 | */ |
202 | public static int getSeverityFromIdentifier(String messageID) { |
203 | |
204 | int lseverity = ExceptionSeverity.NO_APPLICABLE_SEVERITY; |
205 | |
206 | switch (messageID.length()) { |
207 | case 5: |
208 | switch (messageID.charAt(0)) { |
209 | case '0': |
210 | switch (messageID.charAt(1)) { |
211 | case '1': |
212 | lseverity = ExceptionSeverity.WARNING_SEVERITY; |
213 | break; |
214 | case 'A': |
215 | case '7': |
216 | lseverity = ExceptionSeverity.STATEMENT_SEVERITY; |
217 | break; |
218 | case '8': |
219 | lseverity = ExceptionSeverity.SESSION_SEVERITY; |
220 | break; |
221 | } |
222 | break; |
223 | case '2': |
224 | case '3': |
225 | lseverity = ExceptionSeverity.STATEMENT_SEVERITY; |
226 | break; |
227 | case '4': |
228 | switch (messageID.charAt(1)) { |
229 | case '0': |
230 | lseverity = ExceptionSeverity.TRANSACTION_SEVERITY; |
231 | break; |
232 | case '2': |
233 | lseverity = ExceptionSeverity.STATEMENT_SEVERITY; |
234 | break; |
235 | } |
236 | break; |
237 | } |
238 | break; |
239 | |
240 | default: |
241 | switch (messageID.charAt(6)) { |
242 | case 'M': |
243 | lseverity = ExceptionSeverity.SYSTEM_SEVERITY; |
244 | break; |
245 | case 'D': |
246 | lseverity = ExceptionSeverity.DATABASE_SEVERITY; |
247 | break; |
248 | case 'C': |
249 | lseverity = ExceptionSeverity.SESSION_SEVERITY; |
250 | break; |
251 | case 'T': |
252 | lseverity = ExceptionSeverity.TRANSACTION_SEVERITY; |
253 | break; |
254 | case 'S': |
255 | lseverity = ExceptionSeverity.STATEMENT_SEVERITY; |
256 | break; |
257 | case 'U': |
258 | lseverity = ExceptionSeverity.NO_APPLICABLE_SEVERITY; |
259 | break; |
260 | } |
261 | break; |
262 | } |
263 | |
264 | return lseverity; |
265 | } |
266 | |
267 | /* |
268 | ** Set of static methods to obtain exceptions. |
269 | ** |
270 | ** Possible parameters: |
271 | ** String sqlState - SQL State |
272 | ** int severity - Severity of message |
273 | ** Throwable t - exception to wrap |
274 | ** Object aN - argument to error message |
275 | ** |
276 | ** Calls that can be made after the exception has been created. |
277 | ** |
278 | ** setExceptionCategory() |
279 | ** setReport() |
280 | */ |
281 | |
282 | /* specific exceptions */ |
283 | |
284 | public static StandardException normalClose() |
285 | { |
286 | StandardException se = newException( SQLState.NORMAL_CLOSE ); |
287 | se.report = REPORT_NEVER; |
288 | return se; |
289 | } |
290 | |
291 | /* 0 arguments */ |
292 | |
293 | public static StandardException newException(String messageID) { |
294 | return new StandardException(messageID); |
295 | } |
296 | public static StandardException newException(String messageID, Throwable t) { |
297 | return new StandardException(messageID, t, (Object[]) null); |
298 | } |
299 | |
300 | /* 1 argument */ |
301 | |
302 | public static StandardException newException(String messageID, Object a1) { |
303 | Object[] oa = new Object[] {a1}; |
304 | return new StandardException(messageID, oa); |
305 | } |
306 | public static StandardException newException(String messageID, Throwable t, Object a1) { |
307 | Object[] oa = new Object[] {a1}; |
308 | return new StandardException(messageID, t, oa); |
309 | } |
310 | |
311 | /* 2 arguments */ |
312 | |
313 | public static StandardException newException(String messageID, Object a1, Object a2) { |
314 | Object[] oa = new Object[] {a1, a2}; |
315 | return new StandardException(messageID, oa); |
316 | } |
317 | |
318 | /** |
319 | * Dummy exception to catch incorrect use of |
320 | * StandardException.newException(), at compile-time. If you get a |
321 | * compilation error because this exception isn't caught, it means |
322 | * that you are using StandardException.newException(...) |
323 | * incorrectly. The nested exception should always be the second |
324 | * argument. |
325 | * @see StandardException#newException(String, Object, Throwable) |
326 | * @see StandardException#newException(String, Object, Object, Throwable) |
327 | */ |
328 | public static class BadMessageArgumentException extends Throwable {} |
329 | |
330 | /** |
331 | * Dummy overload which should never be called. Only used to |
332 | * detect incorrect usage, at compile time. |
333 | * @param messageID - the sql state id of the message |
334 | * @param a1 - Message arg |
335 | * @param t - Incorrectly placed exception to be nested |
336 | * @return nothing - always throws |
337 | * @throws BadMessageArgumentException - always (dummy) |
338 | */ |
339 | public static StandardException newException(String messageID, |
340 | Object a1, |
341 | Throwable t) |
342 | throws BadMessageArgumentException { |
343 | throw new BadMessageArgumentException(); |
344 | } |
345 | |
346 | public static StandardException newException(String messageID, Throwable t, Object a1, Object a2) { |
347 | Object[] oa = new Object[] {a1, a2}; |
348 | return new StandardException(messageID, t, oa); |
349 | } |
350 | |
351 | /* 3 arguments */ |
352 | |
353 | public static StandardException newException(String messageID, Object a1, Object a2, Object a3) { |
354 | Object[] oa = new Object[] {a1, a2, a3}; |
355 | return new StandardException(messageID, oa); |
356 | } |
357 | |
358 | /** |
359 | * Dummy overload which should never be called. Only used to |
360 | * detect incorrect usage, at compile time. |
361 | * @param messageID - the sql state id of the message |
362 | * @param a1 - First message arg |
363 | * @param a2 - Second message arg |
364 | * @param t - Incorrectly placed exception to be nested |
365 | * @return nothing - always throws |
366 | * @throws BadMessageArgumentException - always (dummy) |
367 | */ |
368 | public static StandardException newException(String messageID, |
369 | Object a1, |
370 | Object a2, |
371 | Throwable t) |
372 | throws BadMessageArgumentException { |
373 | throw new BadMessageArgumentException(); |
374 | } |
375 | |
376 | public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3) { |
377 | Object[] oa = new Object[] {a1, a2, a3}; |
378 | return new StandardException(messageID, t, oa); |
379 | } |
380 | |
381 | /* 4 arguments */ |
382 | |
383 | public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4) { |
384 | Object[] oa = new Object[] {a1, a2, a3, a4}; |
385 | return new StandardException(messageID, oa); |
386 | } |
387 | public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4) { |
388 | Object[] oa = new Object[] {a1, a2, a3, a4}; |
389 | return new StandardException(messageID, t, oa); |
390 | } |
391 | |
392 | /* 5 arguments */ |
393 | public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4, Object a5) { |
394 | Object[] oa = new Object[] {a1, a2, a3, a4, a5}; |
395 | return new StandardException(messageID, oa); |
396 | } |
397 | public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4, Object a5) { |
398 | Object[] oa = new Object[] {a1, a2, a3, a4, a5}; |
399 | return new StandardException(messageID, t, oa); |
400 | } |
401 | |
402 | /* 6 arguments */ |
403 | public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { |
404 | Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6}; |
405 | return new StandardException(messageID, oa); |
406 | } |
407 | public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { |
408 | Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6}; |
409 | return new StandardException(messageID, t, oa); |
410 | } |
411 | |
412 | /* 7 arguments */ |
413 | public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { |
414 | Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6, a7}; |
415 | return new StandardException(messageID, oa); |
416 | } |
417 | public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { |
418 | Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6, a7}; |
419 | return new StandardException(messageID, t, oa); |
420 | } |
421 | |
422 | /* 8 arguments */ |
423 | public static StandardException newException(String messageID, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { |
424 | Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6, a7, a8}; |
425 | return new StandardException(messageID, oa); |
426 | } |
427 | public static StandardException newException(String messageID, Throwable t, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) { |
428 | Object[] oa = new Object[] {a1, a2, a3, a4, a5, a6, a7, a8}; |
429 | return new StandardException(messageID, t, oa); |
430 | } |
431 | |
432 | /** |
433 | * Creates a new StandardException using message text that has already been localized. |
434 | * |
435 | * @param MessageID The SQLState and severity are derived from the ID. However the text message is not. |
436 | * @param t The Throwable that caused this exception, null if this exception was not caused by another Throwable. |
437 | * @param localizedMessage The message associated with this exception. |
438 | * <b>It is the caller's responsibility to ensure that this message is properly localized.</b> |
439 | * |
440 | * See org.apache.derby.iapi.tools.i18n.LocalizedResource |
441 | */ |
442 | public static StandardException newPreLocalizedException( String MessageID, |
443 | Throwable t, |
444 | String localizedMessage) |
445 | { |
446 | StandardException se = new StandardException( MessageID, localizedMessage); |
447 | if( t != null) |
448 | se.nestedException = t; |
449 | return se; |
450 | } |
451 | |
452 | public static StandardException unexpectedUserException(Throwable t) |
453 | { |
454 | /* |
455 | ** If we have a SQLException that isn't a Util |
456 | ** (i.e. it didn't come from cloudscape), then we check |
457 | ** to see if it is a valid user defined exception range |
458 | ** (38001-38XXX). If so, then we convert it into a |
459 | ** StandardException without further ado. |
460 | */ |
461 | if ((t instanceof SQLException) && |
462 | !(t instanceof EmbedSQLException)) |
463 | { |
464 | SQLException sqlex = (SQLException)t; |
465 | String state = sqlex.getSQLState(); |
466 | if ((state != null) && |
467 | (state.length() == 5) && |
468 | state.startsWith("38") && |
469 | !state.equals("38000")) |
470 | { |
471 | StandardException se = new StandardException(state, sqlex.getMessage()); |
472 | if (sqlex.getNextException() != null) |
473 | { |
474 | se.setNestedException(sqlex.getNextException()); |
475 | } |
476 | return se; |
477 | } |
478 | } |
479 | |
480 | // Look for simple wrappers for 3.0.1 - will be cleaned up in main |
481 | if (t instanceof EmbedSQLException) { |
482 | EmbedSQLException csqle = (EmbedSQLException) t; |
483 | if (csqle.isSimpleWrapper()) { |
484 | Throwable wrapped = csqle.getJavaException(); |
485 | if (wrapped instanceof StandardException) |
486 | return (StandardException) wrapped; |
487 | } |
488 | } |
489 | |
490 | |
491 | // no need to wrap a StandardException |
492 | if (t instanceof StandardException) |
493 | { |
494 | return (StandardException) t; |
495 | } |
496 | else |
497 | { |
498 | /* |
499 | ** |
500 | ** The exception at this point could be a: |
501 | ** |
502 | ** standard java exception, e.g. NullPointerException |
503 | ** SQL Exception - from some server-side JDBC |
504 | ** 3rd party exception - from some application |
505 | ** some cloudscape exception that is not a standard exception. |
506 | ** |
507 | ** |
508 | ** We don't want to call t.toString() here, because the JVM is |
509 | ** inconsistent about whether it includes a detail message |
510 | ** with some exceptions (esp. NullPointerException). In those |
511 | ** cases where there is a detail message, t.toString() puts in |
512 | ** a colon character, even when the detail message is blank. |
513 | ** So, we do our own string formatting here, including the colon |
514 | ** only when there is a non-blank message. |
515 | ** |
516 | ** The above is because our test canons contain the text of |
517 | ** error messages. |
518 | ** |
519 | ** In addition we don't want to place the class name in an |
520 | ** exception when the class is from cloudscape because |
521 | ** the class name changes in obfuscated builds. Thus for |
522 | ** exceptions that are in a package below com.ibm.db2j |
523 | ** we use toString(). If this returns an empty or null |
524 | ** then we use the class name to make tracking the problem |
525 | ** down easier, though the lack of a message should be seen |
526 | ** as a bug. |
527 | */ |
528 | String detailMessage; |
529 | boolean cloudscapeException = false; |
530 | |
531 | if (t instanceof EmbedSQLException) { |
532 | detailMessage = ((EmbedSQLException) t).toString(); |
533 | cloudscapeException = true; |
534 | } |
535 | else { |
536 | detailMessage = t.getMessage(); |
537 | } |
538 | |
539 | if (detailMessage == null) |
540 | { |
541 | detailMessage = ""; |
542 | } else { |
543 | detailMessage = detailMessage.trim(); |
544 | } |
545 | |
546 | // if no message, use the class name |
547 | if (detailMessage.length() == 0) { |
548 | detailMessage = t.getClass().getName(); |
549 | } |
550 | else { |
551 | |
552 | if (!cloudscapeException) { |
553 | detailMessage = t.getClass().getName() + ": " + detailMessage; |
554 | } |
555 | } |
556 | |
557 | StandardException se = |
558 | newException(SQLState.LANG_UNEXPECTED_USER_EXCEPTION, t, detailMessage); |
559 | return se; |
560 | } |
561 | } |
562 | |
563 | /** |
564 | Similar to unexpectedUserException but makes no assumtion about |
565 | when the execption is being called. The error is wrapped as simply |
566 | as possible. |
567 | */ |
568 | |
569 | public static StandardException plainWrapException(Throwable t) { |
570 | |
571 | if (t instanceof StandardException) |
572 | return (StandardException) t; |
573 | |
574 | if (t instanceof SQLException) { |
575 | |
576 | SQLException sqle = (SQLException) t; |
577 | |
578 | String sqlState = sqle.getSQLState(); |
579 | if (sqlState != null) { |
580 | |
581 | StandardException se = new StandardException(sqlState, "(" + sqle.getErrorCode() + ") " + sqle.getMessage()); |
582 | sqle = sqle.getNextException(); |
583 | if (sqle != null) |
584 | se.setNestedException(plainWrapException(sqle)); |
585 | return se; |
586 | } |
587 | } |
588 | |
589 | String detailMessage = t.getMessage(); |
590 | |
591 | if (detailMessage == null) |
592 | { |
593 | detailMessage = ""; |
594 | } else { |
595 | detailMessage = detailMessage.trim(); |
596 | } |
597 | |
598 | StandardException se = |
599 | newException(SQLState.JAVA_EXCEPTION, t, detailMessage, t.getClass().getName()); |
600 | return se; |
601 | } |
602 | |
603 | /** |
604 | ** A special exception to close a session. |
605 | */ |
606 | public static StandardException closeException() { |
607 | StandardException se = newException(SQLState.CLOSE_REQUEST); |
608 | se.setReport(REPORT_NEVER); |
609 | return se; |
610 | } |
611 | /* |
612 | ** Message handling |
613 | */ |
614 | |
615 | /** |
616 | The message stored in the super class Throwable must be set |
617 | up object creation. At this time we cannot get any information |
618 | about the object itself (ie. this) in order to determine the |
619 | natural language message. Ie. we need to class of the objec in |
620 | order to look up its message, but we can't get the class of the |
621 | exception before calling the super class message. |
622 | <P> |
623 | Thus the message stored by Throwable and obtained by the |
624 | getMessage() of Throwable (ie. super.getMessage() in this |
625 | class) is the message identifier. The actual text message |
626 | is stored in this class at the first request. |
627 | |
628 | */ |
629 | |
630 | public String getMessage() { |
631 | if (textMessage == null) |
632 | textMessage = MessageService.getCompleteMessage(getMessageId(), getArguments()); |
633 | |
634 | return textMessage; |
635 | } |
636 | |
637 | /** |
638 | Return the message identifier that is used to look up the |
639 | error message text in the messages.properties file. |
640 | */ |
641 | public final String getMessageId() { |
642 | return super.getMessage(); |
643 | } |
644 | |
645 | |
646 | /** |
647 | Get the error code for an error given a type. The value of |
648 | the property messageId.type will be returned, e.g. |
649 | deadlock.sqlstate. |
650 | */ |
651 | public String getErrorProperty(String type) { |
652 | return getErrorProperty(getMessageId(), type); |
653 | } |
654 | |
655 | /** |
656 | Don't print the class name in the toString() method. |
657 | */ |
658 | public String toString() { |
659 | String msg = getMessage(); |
660 | |
661 | return "ERROR " + getSQLState() + ": " + msg; |
662 | } |
663 | |
664 | /* |
665 | ** Static methods |
666 | */ |
667 | |
668 | private static String getErrorProperty(String messageId, String type) { |
669 | return MessageService.getProperty(messageId, type); |
670 | } |
671 | |
672 | public static StandardException interrupt(InterruptedException ie) { |
673 | StandardException se = StandardException.newException(SQLState.CONN_INTERRUPT, ie); |
674 | return se; |
675 | } |
676 | /* |
677 | ** SQL warnings |
678 | */ |
679 | |
680 | public static SQLWarning newWarning(String messageId) { |
681 | |
682 | return newWarningCommon( messageId, (Object[]) null ); |
683 | |
684 | } |
685 | |
686 | public static SQLWarning newWarning(String messageId, Object a1) { |
687 | |
688 | Object[] oa = new Object[] {a1}; |
689 | |
690 | return newWarningCommon( messageId, oa ); |
691 | } |
692 | |
693 | public static SQLWarning newWarning(String messageId, Object a1, Object a2) { |
694 | |
695 | Object[] oa = new Object[] {a1, a2}; |
696 | |
697 | return newWarningCommon( messageId, oa ); |
698 | } |
699 | |
700 | private static SQLWarning newWarningCommon( String messageId, Object[] oa ) |
701 | { |
702 | String message = MessageService.getCompleteMessage(messageId, oa); |
703 | String state = StandardException.getSQLStateFromIdentifier(messageId); |
704 | SQLWarning sqlw = new SQLWarning(message, state, ExceptionSeverity.WARNING_SEVERITY); |
705 | |
706 | return sqlw; |
707 | } |
708 | } |