KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derbyBuild > ErrorMessageGenerator


1 /*
2
3    Derby - Class org.apache.derbyBuild.ErrorMessageGenerator
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derbyBuild;
23
24 import java.io.PrintWriter JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.util.Hashtable JavaDoc;
27 import java.lang.Math JavaDoc;
28 import java.sql.Connection JavaDoc;
29 import java.sql.DriverManager JavaDoc;
30 import java.sql.Statement JavaDoc;
31 import java.sql.ResultSet JavaDoc;
32
33
34 /**
35  *
36  * This tool is used to generate the DITA file that lists all the SQL states
37  * and their error messages.
38  */

39 public class ErrorMessageGenerator
40 {
41     /** Driver name */
42     private static final String JavaDoc DERBY_EMBEDDED_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
43
44     /** Output file name */
45     private static final String JavaDoc DITA_FILE_NAME = "rrefexcept71493.dita";
46
47     /** Location of output file in documentation client. The root of the
48         documentation client is the directory just above src.
49      */

50     private static final String JavaDoc OUTPUT_FILE_STUB = "src/ref/" + DITA_FILE_NAME;
51
52
53     /** Usage string */
54     private static final String JavaDoc USAGE_STRING =
55         "Usage:\n" +
56         "\n" +
57         " java org.apache.derbyBuild.ErrorMessageGenerator DOC_ROOT\n" +
58         "\n" +
59         " where DOC_ROOT = Root of documentation client (the directory just\n" +
60         " above src). E.g., /home/myname/derby/docs/trunk\n"
61         ;
62
63
64     /** Success exit */
65     private static final int SUCCESS = 0;
66     /** Failure exit */
67     private static final int FAILURE = 1;
68
69
70     /** Root of the documentation client */
71     private String JavaDoc docClientRoot;
72
73     /** The name of the DITA file */
74     private String JavaDoc ditaFileName = DITA_FILE_NAME;
75     
76     /** The connection URL */
77     private String JavaDoc url = "jdbc:derby:wombat;create=true";
78     
79     /** Used to write to the DITA file */
80     private PrintWriter JavaDoc ditaWriter;
81     
82     /** Table of SQL State codes and their meaning */
83     private static Hashtable JavaDoc codes = new Hashtable JavaDoc();
84
85     /** short-hand for a double-quote */
86     char dq = '"';
87     
88     /** Indicates whether we are on the first table */
89     boolean firstTable = true;
90     
91     /** Stores the code for the current row */
92     String JavaDoc currentCode;
93     
94     /** Stores the class comment for the current row */
95     String JavaDoc currentComment;
96     
97     static
98     {
99         codes.put("0A", "Feature not supported");
100         codes.put("01", "Warning");
101         codes.put("04", "Database authentication");
102         codes.put("07", "Dynamic SQL Error");
103         codes.put("08", "Connection Exception");
104         codes.put("21", "Cardinality Violation");
105         codes.put("22", "Data Exception");
106         codes.put("23", "Constraint Violation ");
107         codes.put("24", "Invalid Cursor State");
108         codes.put("25", "Invalid Transaction State");
109         codes.put("28", "Invalid Authorization Specification");
110         codes.put("2D", "Invalid Transaction Termination");
111         codes.put("38", "External Function Exception");
112         codes.put("39", "External Routine Invocation Exception");
113         codes.put("3B", "Invalid SAVEPOINT");
114         codes.put("40", "Transaction Rollback");
115         codes.put("42", "Syntax Error or Access Rule Violation");
116         codes.put("57", "DRDA Network Protocol: Execution Failure");
117         codes.put("58", "DRDA Network Protocol: Protocol Error");
118         codes.put("X0", "Execution exceptions");
119         codes.put("XBCA", "CacheService");
120         codes.put("XBCM", "ClassManager");
121         codes.put("XBCX", "Cryptography");
122         codes.put("XBM", "Monitor");
123         codes.put("XCL", "Execution exceptions");
124         codes.put("XCW", "Upgrade unsupported");
125         codes.put("XCX", "Internal Utility Errors");
126         codes.put("XCY", "Derby Property Exceptions");
127         codes.put("XCZ", "org.apache.derby.database.UserUtility");
128         codes.put("XD00", "Dependency Manager");
129         codes.put("XIE", "Import/Export Exceptions");
130         codes.put("XJ", "Connectivity Errors");
131         codes.put("XN", "Network Client Exceptions");
132         codes.put("XSAI", "Store - access.protocol.interface");
133         codes.put("XSAM", "Store - AccessManager");
134         codes.put("XSAS", "Store - Sort");
135         codes.put("XSAX", "Store - access.protocol.XA statement");
136         codes.put("XSCB", "Store - BTree");
137         codes.put("XSCG0", "Conglomerate");
138         codes.put("XSCH", "Heap");
139         codes.put("XSDA", "RawStore - Data.Generic statement");
140         codes.put("XSDB", "RawStore - Data.Generic transaction");
141         codes.put("XSDF", "RawStore - Data.Filesystem statement");
142         codes.put("XSDG", "RawStore - Data.Filesystem database");
143         codes.put("XSLA", "RawStore - Log.Generic database exceptions");
144         codes.put("XSLB", "RawStore - Log.Generic statement exceptions");
145         codes.put("XSRS", "RawStore - protocol.Interface statement");
146         codes.put("XSTA2", "XACT_TRANSACTION_ACTIVE");
147         codes.put("XSTB", "RawStore - Transactions.Basic system");
148         codes.put("XXXXX", "No SQLSTATE");
149     }
150     
151     /**
152      * <p>
153      * Generate the dita file of SQLStates for inclusion in
154      * Derby's Reference Guide.
155      * </p>
156      *
157      * <ul>
158      * <li>args[ 0 ] = Root of docs client. E.g. "/home/myname/derby/docs/trunk"</li>
159      * </ul>
160      */

161     public static void main(String JavaDoc[] args)
162     {
163         ErrorMessageGenerator generator = new ErrorMessageGenerator();
164         
165         if ( !generator.parseArgs( args ) )
166         {
167             generator.printUsage();
168
169             System.exit( FAILURE );
170         }
171
172         generator.setDitaFileName( generator.docClientRoot + '/' + OUTPUT_FILE_STUB );
173         
174         try
175         {
176             generator.execute();
177         }
178         catch ( Throwable JavaDoc t )
179         {
180             t.printStackTrace();
181             System.exit( FAILURE );
182         }
183         System.exit( SUCCESS );
184     }
185     
186     /**
187      * <p>
188      * Parse the arguments. Returns false if the arguments are malformed.
189      * </p>
190      *
191      * <ul>
192      * <li>args[ 0 ] = Root of docs client. E.g. "/home/myname/derby/docs"</li>
193      * </ul>
194      */

195     private boolean parseArgs( String JavaDoc args[] )
196     {
197         int idx = 0;
198         
199         if ( args == null ) { return false; }
200         if ( args.length != 1 ) { return false; }
201
202         docClientRoot = args[ idx++ ];
203
204         return true;
205     }
206
207     /**
208      * <p>
209      * Print instructions on how to run this program.
210      * </p>
211      */

212     private void printUsage()
213     {
214         System.out.println( USAGE_STRING );
215     }
216
217     /**
218      * Set the name of the DITA file
219      */

220     public void setDitaFileName(String JavaDoc ditaFileName)
221     {
222         this.ditaFileName = ditaFileName;
223     }
224     
225     /**
226      * Set the database URL
227      */

228     public void setDatabaseUrl(String JavaDoc url)
229     {
230         this.url = url;
231     }
232     
233     /**
234      * Execute the program
235      */

236     public void execute() throws Exception JavaDoc
237     {
238         try
239         {
240             // Open the DITA file
241
ditaWriter = openDitaFile();
242
243             // Generate the header of the DITA file
244
generateDitaHeader();
245
246             // Generate the error messages for the DITA file
247
generateMessages();
248
249             // Generate the footer of the DITA file
250
generateDitaFooter();
251
252             ditaWriter.close();
253         }
254         catch ( Exception JavaDoc e )
255         {
256             throw e;
257         }
258         finally
259         {
260             if ( ditaWriter != null )
261             {
262                 ditaWriter.close();
263             }
264         }
265     }
266     
267     /**
268      * Open the DITA file for writing
269      *
270      * @return a PrintWriter for the DITA file
271      */

272     protected PrintWriter JavaDoc openDitaFile() throws Exception JavaDoc
273     {
274         return new PrintWriter JavaDoc(new FileOutputStream JavaDoc(ditaFileName));
275     }
276     
277     /**
278      * Generate the header for the DITA file
279      */

280     protected void generateDitaHeader() throws Exception JavaDoc
281     {
282         PrintWriter JavaDoc dw = this.ditaWriter;
283                 
284         ditaWriter.println("<?xml version=" + dq + "1.0" + dq +
285             " encoding=" + dq + "utf-8" + dq + "?>");
286         ditaWriter.println("<!DOCTYPE reference PUBLIC " + dq +
287             "-//OASIS//DTD DITA Reference//EN" + dq);
288         ditaWriter.println(dq + "../dtd/reference.dtd" + dq + ">");
289         ditaWriter.println("<reference id=" + dq + "rrefexcept71493" + dq +
290             " xml:lang=" + dq + "en-us" + dq + ">");
291         ditaWriter.println("<!-- ");
292         ditaWriter.println("Licensed to the Apache Software Foundation (ASF) under one or more");
293         ditaWriter.println("contributor license agreements. See the NOTICE file distributed with");
294         ditaWriter.println("this work for additional information regarding copyright ownership.");
295         ditaWriter.println("The ASF licenses this file to You under the Apache License, Version 2.0");
296         ditaWriter.println("(the \"License\"); you may not use this file except in compliance with");
297         ditaWriter.println("the License. You may obtain a copy of the License at ");
298         ditaWriter.println("");
299         ditaWriter.println("http://www.apache.org/licenses/LICENSE-2.0 ");
300         ditaWriter.println("");
301         ditaWriter.println("Unless required by applicable law or agreed to in writing, software ");
302         ditaWriter.println("distributed under the License is distributed on an \"AS IS\" BASIS, ");
303         ditaWriter.println("WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ");
304         ditaWriter.println("See the License for the specific language governing permissions and ");
305         ditaWriter.println("limitations under the License.");
306         ditaWriter.println("-->");
307         ditaWriter.println("<!-- ");
308         ditaWriter.println("NOTE: this file is generated by running org.apache.derbyBuild.ErrorMessageGenerator ");
309         ditaWriter.println("This utility reads all the error messages from the database and ");
310         ditaWriter.println("generates this file. Please do not feel obligated to update it manually ");
311         ditaWriter.println("-->");
312         ditaWriter.println("<title>SQL error messages and exceptions</title>");
313         ditaWriter.println("<refbody>");
314         ditaWriter.println("<section><p>The following tables list " +
315             "<i>SQLStates</i> for exceptions. Exceptions ");
316         ditaWriter.println("that begin with an <i>X</i> are specific to " +
317             "<ph conref=" + dq + "refconrefs.dita#prod/productshortname" +
318             dq + "></ph>.");
319         ditaWriter.println("In the messages below each {n} tag, where n is a number, represents a\n" +
320                            "value that the Derby engine fills in at runtime. Examples of values\n" +
321                            "include database names, database object names, property names, user\n" +
322                            "names, and parameters passed to a function or procedure:\n" );
323         ditaWriter.println("</p></section>");
324         ditaWriter.println("<section>");
325     }
326     
327     /**
328      * Generate the footer for the DITA file
329      */

330     protected void generateDitaFooter() throws Exception JavaDoc
331     {
332         ditaWriter.println("</section>");
333         ditaWriter.println("</refbody>");
334         ditaWriter.println("</reference>");
335     }
336                 
337
338     /**
339      * Generate the actual error messages
340      */

341     protected void generateMessages() throws Exception JavaDoc
342     {
343         // Get the list of messages from the database
344
ResultSet JavaDoc rs = getMessages();
345         
346         String JavaDoc prevSqlState = null;
347         while ( rs.next() )
348         {
349             String JavaDoc sqlState = rs.getString(1);
350             String JavaDoc message = replaceSpecialChars(rs.getString(2));
351             String JavaDoc severity = rs.getString(3);
352             
353             // See if it's a new SQL State category, and if so,
354
// start a new table in the DITA file
355
testForNewCategory(sqlState, prevSqlState);
356             
357             generateTableEntry(sqlState, message, severity);
358             prevSqlState = sqlState;
359         }
360
361         // Tidy up the last table.
362
generateTableFooter();
363     }
364     
365     /**
366      * Replace a substring with some equivalent. For example, we would
367      * like to replace "<" with "&lt;" in the error messages.
368      * Add any substrings you would like to replace in the code below.
369      * Be aware that the first paramter to the replaceAll() method is
370      * interpreted as a regular expression.
371      *
372      * @param input
373      * A String that may contain substrings that we want to replace
374      * @return
375      * Output String where substrings selected for replacement have been
376      * replaced.
377      * @see java.util.regex.Pattern
378      */

379     private static String JavaDoc replaceSpecialChars(java.lang.String JavaDoc input) {
380         String JavaDoc output = input.replaceAll("<", "&lt;");
381         output = output.replaceAll(">", "&gt;");
382         
383         return output;
384     }
385     
386     /**
387      * Test to see if we have a new SQL State category, and if so,
388      * end the old table and start a new table in the DITA file.
389      *
390      * @param sqlState
391      * The SQL State for the current row
392      *
393      * @param oldSqlState
394      * The SQL State for the previous row
395      */

396     protected void testForNewCategory(String JavaDoc sqlState, String JavaDoc prevSqlState)
397         throws Exception JavaDoc
398     {
399         String JavaDoc prevCode = currentCode;
400         currentCode = getCode(sqlState);
401         
402         if ( currentCode == null )
403         {
404             ditaWriter.println("Unable to determine code for SQL State " +
405                 sqlState);
406             System.out.println("Unable to determine code for SQL State " +
407                 sqlState);
408             return;
409         }
410         
411         if ( currentCode.equals(prevCode))
412         {
413             return;
414         }
415
416         // If we got here, it's a new prefix, let's end the old table
417
// and generate a header for a new table
418
generateTableHeader();
419     }
420     
421     /**
422      * Get the class for the current SQL State.
423      * SIDE EFFECT: sets this.currentComment
424      */

425     protected String JavaDoc getCode(String JavaDoc sqlState) throws Exception JavaDoc
426     {
427         String JavaDoc comment = null;
428         String JavaDoc code = null;
429         
430         if ( sqlState == null )
431         {
432             return null;
433         }
434         
435         int codeLen = sqlState.length();
436         
437         while ( codeLen >= 2 )
438         {
439             code = sqlState.substring(0,codeLen);
440             comment = (String JavaDoc)codes.get(code);
441             if ( comment != null )
442             {
443                 this.currentComment = comment;
444                 return code;
445             }
446             codeLen--;
447         }
448         
449         if ( comment == null )
450         {
451             return null;
452         }
453         
454         return code;
455     }
456             
457     /**
458      * Generate the table header for a given prefix
459      */

460     protected void generateTableHeader()
461         throws Exception JavaDoc
462     {
463         // Generate the end of the previous table
464
if ( ! firstTable )
465         {
466             generateTableFooter();
467         }
468         else
469         {
470             firstTable = false;
471         }
472                
473         // Generate the header for this table
474
ditaWriter.println("<table><title>Class " + currentCode + ": " +
475             currentComment + "</title>");
476         ditaWriter.println("<tgroup cols=" + dq + "2" + dq +
477             "><colspec colname=" + dq + "col1" + dq + " colwidth=" + dq +
478             "1*" + dq + "/><colspec colname=" + dq + "col2" + dq);
479         ditaWriter.println("colwidth=" + dq + "7.5*" + dq +
480             "/>");
481         ditaWriter.println("<thead>");
482         ditaWriter.println("<row valign=" + dq + "bottom" + dq + ">");
483         ditaWriter.println("<entry colname=" + dq + "col1" + dq +
484             ">SQLSTATE</entry>");
485         ditaWriter.println("<entry colname=" + dq + "col2" + dq +
486             ">Message Text</entry>");
487         ditaWriter.println("</row>");
488         ditaWriter.println("</thead>");
489         ditaWriter.println("<tbody>");
490     }
491     
492     /**
493      * Generate the table footer for a given prefix
494      */

495     protected void generateTableFooter()
496         throws Exception JavaDoc
497     {
498         ditaWriter.println("</tbody>");
499         ditaWriter.println("</tgroup>");
500         ditaWriter.println("</table>");
501     }
502     
503     /**
504      * Generate a table entry for the current row
505      */

506     protected void generateTableEntry(String JavaDoc sqlState, String JavaDoc message,
507         String JavaDoc severity) throws Exception JavaDoc
508     {
509         ditaWriter.println("<row>");
510         ditaWriter.println("<entry colname =" + dq + "col1" + dq + ">" +
511             sqlState + "</entry>");
512         ditaWriter.println("<entry colname =" + dq + "col2" + dq + ">" +
513             message + "</entry>");
514         ditaWriter.println("</row>");
515     }
516     
517     /**
518      * Get the messages from the database
519      */

520     protected ResultSet JavaDoc getMessages() throws Exception JavaDoc
521     {
522         Class.forName( DERBY_EMBEDDED_DRIVER );
523         
524         Connection JavaDoc conn = DriverManager.getConnection( url );
525         
526         if ( conn == null )
527         {
528             throw new Exception JavaDoc("Unable to connect to " + url);
529         }
530         
531         Statement JavaDoc stmt = conn.createStatement();
532         
533         ResultSet JavaDoc rs = stmt.executeQuery("SELECT SQL_STATE, MESSAGE, SEVERITY FROM " +
534             "new org.apache.derby.diag.ErrorMessages() AS vti "
535             + "ORDER BY SQL_STATE");
536         
537         return rs;
538     }
539 }
540
Popular Tags