- An output level used to filter build events - Access to the ant output print stream - An emacs mode. Update DefaultLogger to the new interface. In its emacs mode, output is unadorned by the [taskname] tags Add -logger option to allow the logger class to be changed Add -emacs option to control the logger's emacsMode setting git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@267836 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -0,0 +1,92 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 1999 The Apache Software Foundation. All rights | |||
| * reserved. | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * 1. Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * 2. Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in | |||
| * the documentation and/or other materials provided with the | |||
| * distribution. | |||
| * | |||
| * 3. The end-user documentation included with the redistribution, if | |||
| * any, must include the following acknowlegement: | |||
| * "This product includes software developed by the | |||
| * Apache Software Foundation (http://www.apache.org/)." | |||
| * Alternately, this acknowlegement may appear in the software itself, | |||
| * if and wherever such third-party acknowlegements normally appear. | |||
| * | |||
| * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software | |||
| * Foundation" must not be used to endorse or promote products derived | |||
| * from this software without prior written permission. For written | |||
| * permission, please contact apache@apache.org. | |||
| * | |||
| * 5. Products derived from this software may not be called "Apache" | |||
| * nor may "Apache" appear in their names without prior written | |||
| * permission of the Apache Group. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| * SUCH DAMAGE. | |||
| * ==================================================================== | |||
| * | |||
| * This software consists of voluntary contributions made by many | |||
| * individuals on behalf of the Apache Software Foundation. For more | |||
| * information on the Apache Software Foundation, please see | |||
| * <http://www.apache.org/>. | |||
| */ | |||
| package org.apache.tools.ant; | |||
| import java.io.*; | |||
| /** | |||
| * Interface used by Ant to log the build output. | |||
| * | |||
| * A build logger is a build listener which has the 'right' to send output to the | |||
| * ant log, which is usually System.out unles redirected by the -logfile option. | |||
| * | |||
| * @author Conor MacNeill | |||
| */ | |||
| public interface BuildLogger extends BuildListener { | |||
| /** | |||
| * Set the msgOutputLevel this logger is to respond to. | |||
| * | |||
| * Only messages with a message level lower than or equal to the given level are | |||
| * output to the log. | |||
| * | |||
| * @param level the logging level for the logger. | |||
| */ | |||
| public void setMessageOutputLevel(int level); | |||
| /** | |||
| * Set the output stream to which this logger is to send its output. | |||
| * | |||
| * @param output the output stream for the logger. | |||
| */ | |||
| public void setOutputPrintStream(PrintStream output); | |||
| /** | |||
| * Set this logger to produce emacs (and other editor) friendly output. | |||
| * | |||
| * @param emacsMode true if output is to be unadorned so that emacs and other | |||
| * editors can parse files names, etc. | |||
| */ | |||
| public void setEmacsMode(boolean emacsMode); | |||
| } | |||
| @@ -61,24 +61,48 @@ import java.io.*; | |||
| * only writes which targets are being executed, and | |||
| * any messages that get logged. | |||
| */ | |||
| public class DefaultLogger implements BuildListener { | |||
| public class DefaultLogger implements BuildLogger { | |||
| private static int LEFT_COLUMN_SIZE = 12; | |||
| private PrintStream out; | |||
| private int msgOutputLevel; | |||
| private long startTime = System.currentTimeMillis(); | |||
| private boolean emacsMode = false; | |||
| /** | |||
| * Constructs a new logger which will write to the specified | |||
| * PrintStream. Messages with a priority lower (higher?) than | |||
| * msgOutputLevel will be ignored. | |||
| * Set the msgOutputLevel this logger is to respond to. | |||
| * | |||
| * Only messages with a message level lower than or equal to the given level are | |||
| * output to the log. | |||
| * | |||
| * @param level the logging level for the logger. | |||
| */ | |||
| public DefaultLogger(PrintStream out, int msgOutputLevel) { | |||
| this.out = out; | |||
| this.msgOutputLevel = msgOutputLevel; | |||
| public void setMessageOutputLevel(int level) { | |||
| this.msgOutputLevel = level; | |||
| } | |||
| /** | |||
| * Set the output stream to which this logger is to send its output. | |||
| * | |||
| * @param output the output stream for the logger. | |||
| */ | |||
| public void setOutputPrintStream(PrintStream output) { | |||
| this.out = output; | |||
| } | |||
| /** | |||
| * Set this logger to produce emacs (and other editor) friendly output. | |||
| * | |||
| * @param emacsMode true if output is to be unadorned so that emacs and other | |||
| * editors can parse files names, etc. | |||
| */ | |||
| public void setEmacsMode(boolean emacsMode) { | |||
| this.emacsMode = emacsMode; | |||
| } | |||
| public void buildStarted(BuildEvent event) { | |||
| startTime = System.currentTimeMillis(); | |||
| } | |||
| @@ -133,11 +157,13 @@ public class DefaultLogger implements BuildListener { | |||
| if (event.getTask() != null) { | |||
| String name = event.getTask().getTaskName(); | |||
| String msg = "[" + name + "] "; | |||
| for (int i = 0; i < (LEFT_COLUMN_SIZE - msg.length()); i++) { | |||
| out.print(" "); | |||
| if (!emacsMode) { | |||
| String msg = "[" + name + "] "; | |||
| for (int i = 0; i < (LEFT_COLUMN_SIZE - msg.length()); i++) { | |||
| out.print(" "); | |||
| } | |||
| out.print(msg); | |||
| } | |||
| out.print(msg); | |||
| } | |||
| // Print the message | |||
| @@ -90,6 +90,18 @@ public class Main { | |||
| /** Names of classes to add as listeners to project */ | |||
| private Vector listeners = new Vector(5); | |||
| /** | |||
| * The Ant logger class. There may be only one logger. It will have the | |||
| * right to use the 'out' PrintStream. The class must implements the BuildLogger | |||
| * interface | |||
| */ | |||
| private String loggerClassname = null; | |||
| /** | |||
| * Indicates whether output to the log is to be unadorned. | |||
| */ | |||
| private boolean emacsMode = false; | |||
| /** | |||
| * Indicates if this ant should be run. | |||
| */ | |||
| @@ -190,6 +202,14 @@ public class Main { | |||
| value = args[++i]; | |||
| definedProps.put(name, value); | |||
| } else if (arg.equals("-logger")) { | |||
| if (loggerClassname != null) { | |||
| System.out.println("Only one logger class may be specified."); | |||
| return; | |||
| } | |||
| loggerClassname = args[++i]; | |||
| } else if (arg.equals("-emacs")) { | |||
| emacsMode = true; | |||
| } else if (arg.startsWith("-")) { | |||
| // we don't have any more args to recognize! | |||
| String msg = "Unknown arg: " + arg; | |||
| @@ -224,7 +244,6 @@ public class Main { | |||
| /** | |||
| * Executes the build. | |||
| */ | |||
| private void runBuild() throws BuildException { | |||
| if (!readyToRun) { | |||
| @@ -294,7 +313,7 @@ public class Main { | |||
| protected void addBuildListeners(Project project) { | |||
| // Add the default listener | |||
| project.addBuildListener(createDefaultBuildListener()); | |||
| project.addBuildListener(createLogger()); | |||
| for (int i = 0; i < listeners.size(); i++) { | |||
| String className = (String) listeners.elementAt(i); | |||
| @@ -310,10 +329,34 @@ public class Main { | |||
| } | |||
| /** | |||
| * Creates the default build listener for displaying output to the screen. | |||
| * Creates the default build logger for sending build events to the ant log. | |||
| */ | |||
| private BuildListener createDefaultBuildListener() { | |||
| return new DefaultLogger(out, msgOutputLevel); | |||
| private BuildLogger createLogger() { | |||
| BuildLogger logger = null; | |||
| if (loggerClassname != null) { | |||
| try { | |||
| logger = (BuildLogger)(Class.forName(loggerClassname).newInstance()); | |||
| } | |||
| catch (ClassCastException e) { | |||
| System.err.println("The specified logger class " + loggerClassname + | |||
| " does not implement the BuildLogger interface"); | |||
| throw new RuntimeException(); | |||
| } | |||
| catch (Exception e) { | |||
| System.err.println("Unable to instantiate specified logger class " + | |||
| loggerClassname + " : " + e.getClass().getName()); | |||
| throw new RuntimeException(); | |||
| } | |||
| } | |||
| else { | |||
| logger = new DefaultLogger(); | |||
| } | |||
| logger.setMessageOutputLevel(msgOutputLevel); | |||
| logger.setOutputPrintStream(out); | |||
| logger.setEmacsMode(emacsMode); | |||
| return logger; | |||
| } | |||
| /** | |||
| @@ -328,7 +371,9 @@ public class Main { | |||
| msg.append(" -version print the version information and exit" + lSep); | |||
| msg.append(" -quiet be extra quiet" + lSep); | |||
| msg.append(" -verbose be extra verbose" + lSep); | |||
| msg.append(" -emacs produce logging information without adornments" + lSep); | |||
| msg.append(" -logfile <file> use given file for log" + lSep); | |||
| msg.append(" -logger <classname> the class which is to perform logging" + lSep); | |||
| msg.append(" -listener <classname> add an instance of class as a project listener" + lSep); | |||
| msg.append(" -buildfile <file> use given buildfile" + lSep); | |||
| msg.append(" -D<property>=<value> use value for given property" + lSep); | |||
| @@ -120,7 +120,10 @@ public class Ant extends Task { | |||
| if (output != null) { | |||
| try { | |||
| PrintStream out = new PrintStream(new FileOutputStream(output)); | |||
| p1.addBuildListener(new DefaultLogger(out, Project.MSG_INFO)); | |||
| DefaultLogger logger = new DefaultLogger(); | |||
| logger.setMessageOutputLevel(Project.MSG_INFO); | |||
| logger.setOutputPrintStream(out); | |||
| p1.addBuildListener(logger); | |||
| } | |||
| catch( IOException ex ) { | |||
| log( "Ant: Can't set output to " + output ); | |||