|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.tomcat5.ide; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.BufferedReader; import java.io.PrintWriter; import java.util.*; import org.openide.ErrorManager; import org.openide.filesystems.*; import org.openide.util.*; import org.openide.windows.IOProvider; import org.openide.windows.InputOutput; import org.openide.windows.OutputWriter; import org.netbeans.modules.tomcat5.util.LogSupport; import org.netbeans.api.java.classpath.GlobalPathRegistry; /** Connects the error and output streams of a process to the IDE output window. * * @author Ales Novak, Jaroslav Tulach, Petr Jiricka */ public class ProcessSupport { /** Connects a given process to the output window. Returns immediately, but threads are started that * copy streams of the process to/from the output window. * @param process process whose streams to connect to the output window * @param ioName name of the output window tab to use */ public static void connectProcessToOutputWindow(final Process process, final String ioName) { final InputOutput io = IOProvider.getDefault().getIO(ioName, false); try { io.getOut().reset(); } catch (IOException e) { // not a critical error, continue ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); } io.select(); final Thread serverLog = new ProcessSupport.ServerLog( io, new InputStreamReader(process.getInputStream()), new InputStreamReader(process.getErrorStream()), true, false); serverLog.start(); //PENDING: currently we copy only Tomcat std & err output. We should // also support copying to Tomcat std input. new Thread() { public void run() { try { int ret = process.waitFor(); Thread.sleep(2000); // time for server log } catch (InterruptedException e) { } finally { serverLog.interrupt(); } } }.start(); } /** * Tomcat server log reads from the Tomcat standard and error output and * writes to output window. */ private static class ServerLog extends Thread { private InputOutput io; private OutputWriter writer; private OutputWriter errorWriter; private BufferedReader inReader; private BufferedReader errReader; private final boolean autoFlush; private final boolean takeFocus; private volatile boolean done = false; private ServerLogSupport logSupport; /** * Tomcat server log reads from the Tomcat standard and error output and * writes to output window. * * @param io output window where logging should be done to * @param in Tomcat standard output reader * @param err Tomcat error output reader * @param autoFlush should we flush after a change? * @param takeFocus should be the output window made visible after each * changed? */ public ServerLog(InputOutput io, Reader in, Reader err, boolean autoFlush, boolean takeFocus) { super("Tomcat ServerLog - Thread"); // NOI18N setDaemon(true); inReader = new BufferedReader(in); errReader = new BufferedReader(err); this.autoFlush = autoFlush; this.takeFocus = takeFocus; writer = io.getOut(); errorWriter = io.getErr(); this.io = io; logSupport = new ServerLogSupport(); } private void processLine(String line) { ServerLogSupport.LineInfo lineInfo = logSupport.analyzeLine(line); if (lineInfo.isError()) { if (lineInfo.isAccessible()) { try { errorWriter.println(line, logSupport.getLink(lineInfo.message() , lineInfo.path(), lineInfo.line())); } catch (IOException ex) { ErrorManager.getDefault().notify(ex); } } else { errorWriter.println(line); } } else { writer.println(line); } } public void run() { try { while(!done) { boolean isInReaderReady = false; boolean isErrReaderReady = false; boolean updated = false; int count = 0; // take a nap after 1024 read cycles, this should ensure responsiveness // even if log file is growing fast while (((isInReaderReady = inReader.ready()) || (isErrReaderReady = errReader.ready())) && count++ < 1024) { if (done) return; updated = true; if (isInReaderReady) { String line = inReader.readLine(); // finish, if we have reached the end of the stream if (line == null) return; processLine(line); } if (isErrReaderReady) { String line = errReader.readLine(); // finish, if we have reached the end of the stream if (line == null) return; processLine(line); } } if (updated) { if (autoFlush) { writer.flush(); errorWriter.flush(); } if (takeFocus) { io.select(); } } sleep(100); // take a nap } } catch (IOException ex) { } catch (InterruptedException e) { } finally { logSupport.detachAnnotation(); } } public void interrupt() { super.interrupt(); done = true; } } /** * Support class for Tomcat server output log line analyzation and for * creating links in the output window. */ static class ServerLogSupport extends LogSupport { private String prevMessage; private GlobalPathRegistry globalPathRegistry = GlobalPathRegistry.getDefault(); public LineInfo analyzeLine(String logLine) { String path = null; int line = -1; String message = null; boolean error = false; boolean accessible = false; logLine = logLine.trim(); int lineLenght = logLine.length(); // look for unix file links (e.g. /foo/bar.java:51: 'error msg') if (logLine.startsWith("/")) { error = true; int colonIdx = logLine.indexOf(':'); if (colonIdx > -1) { path = logLine.substring(0, colonIdx); accessible = true; if (lineLenght > colonIdx) { int nextColonIdx = logLine.indexOf(':', colonIdx + 1); if (nextColonIdx > -1) { String lineNum = logLine.substring(colonIdx + 1, nextColonIdx); try { line = Integer.valueOf(lineNum).intValue(); } catch(NumberFormatException nfe) { // ignore it } if (lineLenght > nextColonIdx) { message = logLine.substring(nextColonIdx + 1, lineLenght); } } } } } // look for windows file links (e.g. c:\foo\bar.java:51: 'error msg') else if (lineLenght > 3 && Character.isLetter(logLine.charAt(0)) && (logLine.charAt(1) == ':') && (logLine.charAt(2) == '\\')) { error = true; int secondColonIdx = logLine.indexOf(':', 2); if (secondColonIdx > -1) { path = logLine.substring(0, secondColonIdx); accessible = true; if (lineLenght > secondColonIdx) { int thirdColonIdx = logLine.indexOf(':', secondColonIdx + 1); if (thirdColonIdx > -1) { String lineNum = logLine.substring(secondColonIdx + 1, thirdColonIdx); try { line = Integer.valueOf(lineNum).intValue(); } catch(NumberFormatException nfe) { // ignore it } if (lineLenght > thirdColonIdx) { message = logLine.substring(thirdColonIdx + 1, lineLenght); } } } } } // look for stacktrace links (e.g. at java.lang.Thread.run(Thread.java:595)) else if (logLine.startsWith("at ") && lineLenght > 3) { error = true; int parenthIdx = logLine.indexOf('('); if (parenthIdx > -1) { String classWithMethod = logLine.substring(3, parenthIdx); int lastDotIdx = classWithMethod.lastIndexOf('.'); if (lastDotIdx > -1) { int lastParenthIdx = logLine.lastIndexOf(')'); int lastColonIdx = logLine.lastIndexOf(':'); if (lastParenthIdx > -1 && lastColonIdx > -1) { String lineNum = logLine.substring(lastColonIdx + 1, lastParenthIdx); try { line = Integer.valueOf(lineNum).intValue(); } catch(NumberFormatException nfe) { // ignore it } message = prevMessage; } String className = classWithMethod.substring(0, lastDotIdx); path = className.replace('.','/') + ".java"; // NOI18N accessible = globalPathRegistry.findResource(path) != null; } } } // every other message treat as normal info message else { prevMessage = logLine; } return new LineInfo(path, line, message, error, accessible); } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.