KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > util > BuildLogMsgDoc


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.util;
25
26 import java.io.*;
27 import java.util.ArrayList JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 /**
31  * This class is a utility that takes as input a property file name and
32  * creates a file named <propertyFileName>.html which is an html document
33  * containing a table consisting of the following columns:
34  *
35  * MessageId, MessageSeverity, MessageText, Description
36  *
37  * The MessageId and MessageText are pulled directly from the given property
38  * file. The MessageSeverity is determined by searching through the source
39  * code heuristically for the message key in the property file and parsing
40  * the severity (FATAL, ALERT, SEVERE, WARNING, CONFIG, INFO, FINE, FINER,
41  * FINEST) from the source files containing the message key. For now the
42  * description holds the file and line number where the message key was found.
43  *
44  * The format of the property file is assumed to be as follows:
45  *
46  * Lines starting with # are considered comments and ignored
47  *
48  * Blank lines are ignored
49  *
50  * Other lines are considered to be of the format:
51  * <messageKey>=<messageId><delimiter><messageText>
52  * The messageId is typically a string of the form <subsystem><id> such
53  * as WEB0001. The delimiter is either the ':' character or a ' '
54  * (space). Message text can be anything.
55  *
56  * Notes:
57  * There are hardcoded values here about where to search for source
58  * and what file types to search.
59  *
60  * This has only been run / tested on Win2K against the
61  * LogStrings.property files found in com/sun/logging.
62  *
63  * The find utility is used to search for message key occurrences.
64  **/

65
66 /**
67  * The ThreadedReader is used to read stdout/stderr of the find command and
68  * return its results in an ArrayList buffer.
69  **/

70 class ThreadedReader extends Thread JavaDoc
71 {
72     BufferedReader _reader = null;
73     String JavaDoc _messageKey = null;
74     ArrayList JavaDoc _result = null;
75
76     public ThreadedReader(InputStream is, ArrayList JavaDoc result, String JavaDoc messageKey) {
77         _reader = new BufferedReader(new InputStreamReader(is));
78         _result = result;
79         _messageKey = messageKey;
80     }
81
82     public void run() {
83         try {
84             String JavaDoc line = null;
85             while (true) {
86                 line = _reader.readLine();
87                 if (line == null) {
88                     break;
89                 }
90                 _result.add(line);
91             }
92         } catch (Exception JavaDoc ex) {
93             System.err.println("ThreadedReader " + _messageKey + " exception");
94             ex.printStackTrace();
95         }
96     }
97 }
98
99
100 public class BuildLogMsgDoc {
101
102     public static void main(String JavaDoc[] args) {
103         if (args.length != 1) {
104             System.err.println("usage: BuildLogMsgDoc <resource-file-name>");
105             System.exit(1);
106         }
107         String JavaDoc inFile = args[0];
108         String JavaDoc outFile = args[0] + ".html";
109         try {
110             createHtml(inFile, outFile);
111         } catch (Exception JavaDoc ex) {
112             ex.printStackTrace();
113         }
114      }
115
116     protected static void createHtml(String JavaDoc in, String JavaDoc out)
117         throws FileNotFoundException, IOException
118     {
119         BufferedReader reader = new BufferedReader(new FileReader(in));
120         BufferedWriter writer = new BufferedWriter(new FileWriter(out, false));
121         try {
122             // output html table header
123
writer.write(tableHeader(in));
124             writer.newLine();
125             writer.write(tableRow("Message Id", "Severity", "Message Text", "Description"));
126             writer.newLine();
127             String JavaDoc line = null;
128             String JavaDoc newLine = null;
129             while (true) {
130                 line = reader.readLine();
131                 if (line == null) {
132                     break;
133                 }
134                 parsePropertyEntry(writer, line);
135             }
136         } finally {
137             // output html table footer
138
writer.write(tableFooter());
139             try {
140                 reader.close();
141             } catch (Exception JavaDoc ex) {}
142             try {
143                 writer.close();
144             } catch (Exception JavaDoc ex) {}
145         }
146     }
147
148     protected static void parsePropertyEntry(BufferedWriter writer, String JavaDoc line)
149     {
150         String JavaDoc result = line.trim();
151         //skip empty lines
152
if (result.length() == 0) {
153             return;
154         }
155         //skip comments
156
if (result.startsWith("#")) {
157             return;
158         }
159         //parse the message key
160
String JavaDoc key = null;
161         String JavaDoc messageId = null;
162         String JavaDoc message = null;
163         int pos = -2;
164         int pos2 = -2;
165         int pos3 = -2;
166         pos = result.indexOf("=");
167         if (pos > 0) {
168             // Attempt to parse a message of the form
169
// <messageId>:<messageText> or
170
// <messageId> <messageText>
171
// delegate to formatLine on success
172
key = result.substring(0, pos);
173             result = result.substring(pos + 1);
174             pos2 = result.indexOf(" ");
175             pos3 = result.indexOf(":");
176             if ((pos3 < 0 || pos2 < pos3) && pos2 > 0) {
177                 messageId = result.substring(0, pos2);
178                 message = result.substring(pos2 + 1).trim();
179                 formatLine(writer, key, messageId, message);
180                 return;
181
182             } else if (pos3 > 0) {
183                 messageId = result.substring(0, pos3);
184                 message = result.substring(pos3 + 1).trim();
185                 formatLine(writer, key, messageId, message);
186                 return;
187             }
188         }
189         // Malformed line in the property file
190
System.err.println("Failed to parse: " + line + " pos=" + pos +
191                 " pos2=" + pos2 + " pos3=" + pos3);
192     }
193
194     protected static void formatLine(BufferedWriter writer, String JavaDoc key,
195             String JavaDoc messageId, String JavaDoc message)
196     {
197         // find occurrences of message key in the source
198
ArrayList JavaDoc files = findSourceFiles (key);
199         if (files == null) {
200             // there are no occurrences of the message key found.
201
try {
202                 System.err.println("message " + key + "is not found in any files");
203                 writer.write(tableRow(messageId, "UNKNOWN", message,
204                     "key=" + key + " found in NO FILES"));
205                 writer.newLine();
206             } catch (Exception JavaDoc ex) {
207                 System.err.println("formatLine id " +
208                     key + " exception ");
209                 ex.printStackTrace();
210             }
211         } else {
212             // for each source file in which the message key is found, we
213
// find the location of the message key in the source file
214
// to determine its severity
215
for (int i = 0; i < files.size(); i++) {
216                 //System.out.println("Searching file " + files.get(i) + " for " + key);
217
findSourceOccurrence(writer, key, messageId, message,
218                     (String JavaDoc)files.get(i));
219             }
220         }
221     }
222
223     // Looks for a severity in a single line of source, by looking for very
224
// specific keywords
225
protected static String JavaDoc findLevel (String JavaDoc line) {
226         String JavaDoc[] keywords = {"INFO", "WARNING", "SEVERE", "CONFIG", "ALERT", "FATAL",
227             "FINE", "FINER", "FINEST"};
228         line = line.toUpperCase();
229         for (int i = 0; i < keywords.length; i++) {
230             int pos = line.indexOf(keywords[i]);
231             if (pos >= 0) {
232                 return (keywords[i]);
233             }
234         }
235         return null;
236     }
237
238     // Looks for an occurrence of the given messageKey in the file and
239
// determines its severity. Upon success a row is written to the
240
// html table
241
protected static void findSourceOccurrence(BufferedWriter writer,
242             String JavaDoc messageKey, String JavaDoc messageId, String JavaDoc message,
243             String JavaDoc in)
244     {
245         BufferedReader reader = null;
246         try {
247             reader = new BufferedReader(new FileReader(in));
248             int lineno = 1;
249             int foundOn = -1;
250             String JavaDoc line = null;
251             // process each line of the source file sequentially looking for
252
// the message key followed (somewhere) by its level
253
while (true) {
254                 line = reader.readLine();
255                 if (line == null) {
256                     // end of file, check to see if we have found the message
257
// key, but no level
258
if (foundOn > 0) {
259                         System.err.println("found " + messageKey + " but no level in " +
260                                 in);
261                         writer.write(tableRow(messageId, "UNKNOWN", message,
262                             "key=" + messageKey + " found in " + in +
263                             " line " + foundOn));
264                         writer.newLine();
265                     }
266                     break;
267                 }
268                 int pos = line.indexOf(messageKey);
269                 if (pos >= 0) {
270                     // we have found an occurrence of the message key in the
271
// file.
272
if (foundOn > 0) {
273                         // we have not yet found the level for the previous
274
// occurrence of the message key
275
System.err.println("found next " + messageKey +
276                                 " before finding previous level in " + in);
277                         writer.write(tableRow(messageId, "UNKNOWN", message,
278                             "key=" + messageKey + " found in " + in +
279                             " line " + foundOn));
280                         writer.newLine();
281                     }
282                     foundOn = lineno;
283                     //System.out.println("Found " + messageKey + " on line " + foundOn +
284
// " in " + in);
285
}
286                 if (foundOn >= lineno) {
287                     // start looking for a level only after the message key
288
// has been found (i.e. foundOn > lineno)
289
String JavaDoc level = findLevel(line);
290                     if (level != null) {
291                         // we have successfully found the level. If the level
292
// was found within 5 lines of the key, then this is
293
// considered "normal"; otherwise, we output ** next
294
// to the level as a marker indicating that the level
295
// may not be accurate
296
//System.out.println(messageKey + " in " + in + " has level " + level);
297
if (foundOn < lineno + 5) {
298                             writer.write(tableRow(messageId, level, message,
299                                 "key=" + messageKey + " found in " + in +
300                                 " line " + foundOn + " logged in line " + lineno));
301                         } else {
302                             writer.write(tableRow(messageId, "**" + level, message,
303                                 "key=" + messageKey + " found in " + in +
304                                 " line " + foundOn + " logged in line " + lineno));
305                         }
306                         writer.newLine();
307                         foundOn = -1;
308                     }
309                 }
310                 lineno++;
311             }
312         } catch (Exception JavaDoc ex) {
313             System.err.println("findSourceOccurrence id " +
314                 messageKey + " in " + in + " exception");
315             ex.printStackTrace();
316         } finally {
317             try {
318                 if (reader != null) {
319                     reader.close();
320                 }
321             } catch (Exception JavaDoc ex) {}
322         }
323     }
324
325     protected static ArrayList JavaDoc findSourceFiles (String JavaDoc messageKey)
326     {
327         try {
328             ArrayList JavaDoc stdoutList = new ArrayList JavaDoc();
329             ArrayList JavaDoc stderrList = new ArrayList JavaDoc();
330             // exec a find ... -exeec grep -l to search for the source files
331
// containing the message key. Each match (source file) is returned
332
// as one String entry in the resulting ArrayList
333
Process JavaDoc p = Runtime.getRuntime().exec("/bin/find /ias/tip/iplanet/ias/server/src/java -name \"*.java\" -exec grep -l " + messageKey + " {} ;");
334             ThreadedReader inReader = new ThreadedReader(p.getInputStream(), stdoutList, messageKey);
335             ThreadedReader errReader = new ThreadedReader(p.getErrorStream(), stderrList, messageKey);
336             inReader.start();
337             errReader.start();
338             inReader.join();
339             errReader.join();
340             p.waitFor();
341             p.exitValue();
342             if (!stderrList.isEmpty()) {
343                 System.err.println("findSourceFiles " + messageKey + " stderr");
344                 for (int i = 0; i < stderrList.size(); i++) {
345                     System.err.println(" " + (String JavaDoc)stderrList.get(i));
346                 }
347             }
348             if (!stdoutList.isEmpty()) {
349                 return stdoutList;
350             }
351             return null;
352         } catch (Exception JavaDoc ex) {
353             System.err.println("findSourceFiles " + messageKey + " exception");
354             ex.printStackTrace();
355             return null;
356         }
357     }
358    
359     // Output the table header
360
protected static String JavaDoc tableHeader(String JavaDoc inFile) {
361         String JavaDoc r = "<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">";
362         r += "\n" + "<html>";
363         r += "\n" + "<head>";
364         r += "\n" + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">";
365         r += "\n" + "<meta name=\"Author\" content=\"Ken Ebbs\">";
366         r += "\n" + "<meta name=\"GENERATOR\" content=\"Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]\">";
367         r += "\n" + "<title>Logging Message Reference</title>";
368         r += "\n" + "</head>";
369         r += "\n" + "<body>";
370         r += "\n" + "&nbsp;";
371         r += "\n" + "<table BORDER WIDTH=\"100%\" >";
372         r += "\n" + "<caption>Log Messages For " + inFile + "</caption>";
373         return r;
374     }
375
376     // Output the table footer
377
protected static String JavaDoc tableFooter() {
378         String JavaDoc r = "</table>";
379         r += "\n" + "</body>";
380         r += "\n" + "</html>";
381         return r;
382     }
383
384     // Output a single row in the table
385
protected static String JavaDoc tableRow(String JavaDoc messageId, String JavaDoc severity, String JavaDoc messageText, String JavaDoc description) {
386         String JavaDoc r = "<tr>";
387         r += "\n" + "<td>" + messageId + "</td>";
388         r += "\n" + "<td>" + severity + "</td>";
389         r += "\n" + "<td>" + messageText + "</td>";
390         r += "\n" + "<td>" + description + "</td>";
391         r += "\n" + "</tr>";
392         return r;
393     }
394 }
395
Popular Tags