KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tomcat5 > util > ServerLog


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 /*
21  * ServerLog.java
22  *
23  * Created on September 13, 2004, 7:13 PM
24  */

25
26 package org.netbeans.modules.tomcat5.util;
27
28 import java.io.File JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.Reader JavaDoc;
31 import java.io.BufferedReader JavaDoc;
32 import org.netbeans.modules.tomcat5.TomcatManager;
33 import org.openide.ErrorManager;
34 import org.openide.modules.InstalledFileLocator;
35 import org.openide.util.NbBundle;
36 import org.openide.windows.InputOutput;
37 import org.openide.windows.OutputWriter;
38 import org.netbeans.api.java.classpath.GlobalPathRegistry;
39 import org.netbeans.modules.j2ee.deployment.plugins.api.UISupport;
40 import org.netbeans.modules.tomcat5.util.LogSupport.LineInfo;
41
42 /**
43  * Tomcat server log reads from the Tomcat standard and error output and
44  * writes to output window.
45  */

46 class ServerLog extends Thread JavaDoc {
47     private InputOutput io;
48     private OutputWriter writer;
49     private OutputWriter errorWriter;
50     private BufferedReader JavaDoc inReader;
51     private BufferedReader JavaDoc errReader;
52     private final boolean autoFlush;
53     private final boolean takeFocus;
54     private volatile boolean done = false;
55     private ServerLogSupport logSupport;
56
57     /**
58      * Tomcat server log reads from the Tomcat standard and error output and
59      * writes to output window.
60      *
61      * @param displayName output window display name.
62      * @param in Tomcat standard output reader.
63      * @param err Tomcat error output reader.
64      * @param autoFlush should we flush after a change?
65      * @param takeFocus should be the output window made visible after each
66      * changed?
67      */

68     public ServerLog(String JavaDoc url, String JavaDoc displayName, Reader JavaDoc in, Reader JavaDoc err, boolean autoFlush,
69             boolean takeFocus) {
70         super(displayName + " ServerLog - Thread"); // NOI18N
71
setDaemon(true);
72         inReader = new BufferedReader JavaDoc(in);
73         errReader = new BufferedReader JavaDoc(err);
74         this.autoFlush = autoFlush;
75         this.takeFocus = takeFocus;
76         io = UISupport.getServerIO(url);
77         try {
78             io.getOut().reset();
79         }
80         catch (IOException JavaDoc e) {
81             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
82         }
83         writer = io.getOut();
84         errorWriter = io.getErr();
85         io.select();
86         logSupport = new ServerLogSupport();
87     }
88
89     private void processLine(String JavaDoc line) {
90         ServerLogSupport.LineInfo lineInfo = logSupport.analyzeLine(line);
91         if (lineInfo.isError()) {
92             if (lineInfo.isAccessible()) {
93                 try {
94                     errorWriter.println(line, logSupport.getLink(lineInfo.message() , lineInfo.path(), lineInfo.line()));
95                 } catch (IOException JavaDoc ex) {
96                     ErrorManager.getDefault().notify(ex);
97                 }
98             } else {
99                 errorWriter.println(line);
100             }
101         } else {
102             writer.println(line);
103             if (line.startsWith("SEVERE: WSSERVLET11: failed to parse runtime descriptor: java.lang.LinkageError:")) { // NOI18N
104
File JavaDoc file = InstalledFileLocator.getDefault().locate("modules/ext/jaxws21/api/jaxws-api.jar", null, false); // NOI18N
105
if (file != null) {
106                     writer.println(NbBundle.getMessage(ServerLog.class, "MSG_WSSERVLET11", file.getParent()));
107                 } else {
108                     writer.println(NbBundle.getMessage(ServerLog.class, "MSG_WSSERVLET11_NOJAR"));
109                 }
110             }
111         }
112     }
113
114     public void run() {
115         try {
116             while(!done) {
117                 boolean isInReaderReady = false;
118                 boolean isErrReaderReady = false;
119                 boolean updated = false;
120                 int count = 0;
121                 // take a nap after 1024 read cycles, this should ensure responsiveness
122
// even if log file is growing fast
123
while (((isInReaderReady = inReader.ready()) || (isErrReaderReady = errReader.ready()))
124                         && count++ < 1024) {
125                     if (done) {
126                         return;
127                     }
128                     updated = true;
129                     if (isInReaderReady) {
130                         String JavaDoc line = inReader.readLine();
131                         // finish, if we have reached the end of the stream
132
if (line == null) {
133                             return;
134                         }
135                         processLine(line);
136                     }
137                     if (isErrReaderReady) {
138                         String JavaDoc line = errReader.readLine();
139                         // finish, if we have reached the end of the stream
140
if (line == null) {
141                             return;
142                         }
143                         processLine(line);
144                     }
145                 }
146                 if (updated) {
147                     if (autoFlush) {
148                         writer.flush();
149                         errorWriter.flush();
150                     }
151                     if (takeFocus) {
152                         io.select();
153                     }
154                 }
155                 sleep(100); // take a nap
156
}
157         } catch (IOException JavaDoc ex) {
158             TomcatManager.ERR.notify(ErrorManager.INFORMATIONAL, ex);
159         } catch (InterruptedException JavaDoc e) {
160             // no op - the thread was interrupted
161
} finally {
162             logSupport.detachAnnotation();
163         }
164     }
165     
166     /**
167      * Test whether ServerLog thread is still running.
168      *
169      * @return <code>true</code> if the thread is still running, <code>false</code>
170      * otherwise.
171      */

172     public boolean isRunning() {
173         return !(done);
174     }
175     
176     /**
177      * Make the log tab visible.
178      */

179     public void takeFocus() {
180         io.select();
181     }
182
183     public void interrupt() {
184         super.interrupt();
185         done = true;
186     }
187     
188     /**
189      * Support class for Tomcat server output log line analyzation and for
190      * creating links in the output window.
191      */

192     static class ServerLogSupport extends LogSupport {
193         private String JavaDoc prevMessage;
194         private GlobalPathRegistry globalPathRegistry = GlobalPathRegistry.getDefault();
195         
196         public LineInfo analyzeLine(String JavaDoc logLine) {
197             String JavaDoc path = null;
198             int line = -1;
199             String JavaDoc message = null;
200             boolean error = false;
201             boolean accessible = false;
202
203             logLine = logLine.trim();
204             int lineLenght = logLine.length();
205
206             // look for unix file links (e.g. /foo/bar.java:51: 'error msg')
207
if (logLine.startsWith("/")) {
208                 error = true;
209                 int colonIdx = logLine.indexOf(':');
210                 if (colonIdx > -1) {
211                     path = logLine.substring(0, colonIdx);
212                     accessible = true;
213                     if (lineLenght > colonIdx) {
214                         int nextColonIdx = logLine.indexOf(':', colonIdx + 1);
215                         if (nextColonIdx > -1) {
216                             String JavaDoc lineNum = logLine.substring(colonIdx + 1, nextColonIdx);
217                             try {
218                                 line = Integer.valueOf(lineNum).intValue();
219                             } catch(NumberFormatException JavaDoc nfe) {
220                                 // ignore it
221
TomcatManager.ERR.notify(ErrorManager.INFORMATIONAL, nfe);
222                             }
223                             if (lineLenght > nextColonIdx) {
224                                 message = logLine.substring(nextColonIdx + 1, lineLenght);
225                             }
226                         }
227                     }
228                 }
229             }
230             // look for windows file links (e.g. c:\foo\bar.java:51: 'error msg')
231
else if (lineLenght > 3 && Character.isLetter(logLine.charAt(0))
232                         && (logLine.charAt(1) == ':') && (logLine.charAt(2) == '\\')) {
233                 error = true;
234                 int secondColonIdx = logLine.indexOf(':', 2);
235                 if (secondColonIdx > -1) {
236                     path = logLine.substring(0, secondColonIdx);
237                     accessible = true;
238                     if (lineLenght > secondColonIdx) {
239                         int thirdColonIdx = logLine.indexOf(':', secondColonIdx + 1);
240                         if (thirdColonIdx > -1) {
241                             String JavaDoc lineNum = logLine.substring(secondColonIdx + 1, thirdColonIdx);
242                             try {
243                                 line = Integer.valueOf(lineNum).intValue();
244                             } catch(NumberFormatException JavaDoc nfe) {
245                                 // ignore it
246
TomcatManager.ERR.notify(ErrorManager.INFORMATIONAL, nfe);
247                             }
248                             if (lineLenght > thirdColonIdx) {
249                                 message = logLine.substring(thirdColonIdx + 1, lineLenght);
250                             }
251                         }
252                     }
253                 }
254             }
255             // look for stacktrace links (e.g. at java.lang.Thread.run(Thread.java:595)
256
// at t.HyperlinkTest$1.run(HyperlinkTest.java:24))
257
else if (logLine.startsWith("at ") && lineLenght > 3) {
258                 error = true;
259                 int parenthIdx = logLine.indexOf('(');
260                 if (parenthIdx > -1) {
261                     String JavaDoc classWithMethod = logLine.substring(3, parenthIdx);
262                     int lastDotIdx = classWithMethod.lastIndexOf('.');
263                     if (lastDotIdx > -1) {
264                         int lastParenthIdx = logLine.lastIndexOf(')');
265                         int lastColonIdx = logLine.lastIndexOf(':');
266                         if (lastParenthIdx > -1 && lastColonIdx > -1) {
267                             String JavaDoc lineNum = logLine.substring(lastColonIdx + 1, lastParenthIdx);
268                             try {
269                                 line = Integer.valueOf(lineNum).intValue();
270                             } catch(NumberFormatException JavaDoc nfe) {
271                                 // ignore it
272
TomcatManager.ERR.notify(ErrorManager.INFORMATIONAL, nfe);
273                             }
274                             message = prevMessage;
275                         }
276                         int firstDolarIdx = classWithMethod.indexOf('$'); // > -1 for inner classes
277
String JavaDoc className = classWithMethod.substring(0, firstDolarIdx > -1 ? firstDolarIdx : lastDotIdx);
278                         path = className.replace('.','/') + ".java"; // NOI18N
279
accessible = globalPathRegistry.findResource(path) != null;
280                     }
281                 }
282             }
283             // every other message treat as normal info message
284
else {
285                 prevMessage = logLine;
286             }
287             return new LineInfo(path, line, message, error, accessible);
288         }
289     }
290 }
Popular Tags