Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 335   Methods: 15
NCLOC: 129   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DefaultLogger.java 68.2% 86.9% 100% 84.7%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 
 55   
 package org.apache.tools.ant;
 56   
 
 57   
 import java.io.BufferedReader;
 58   
 import java.io.IOException;
 59   
 import java.io.PrintStream;
 60   
 import java.io.StringReader;
 61   
 import org.apache.tools.ant.util.DateUtils;
 62   
 import org.apache.tools.ant.util.StringUtils;
 63   
 
 64   
 /**
 65   
  * Writes build events to a PrintStream. Currently, it
 66   
  * only writes which targets are being executed, and
 67   
  * any messages that get logged.
 68   
  *
 69   
  * @author Matt Foemmel
 70   
  */
 71   
 public class DefaultLogger implements BuildLogger {
 72   
     /** 
 73   
      * Size of left-hand column for right-justified task name.
 74   
      * @see #messageLogged(BuildEvent)
 75   
      */
 76   
     public static final int LEFT_COLUMN_SIZE = 12;
 77   
 
 78   
     /** PrintStream to write non-error messages to */
 79   
     protected PrintStream out;
 80   
     /** PrintStream to write error messages to */
 81   
     protected PrintStream err;
 82   
     /** Lowest level of message to write out */
 83   
     protected int msgOutputLevel = Project.MSG_ERR;
 84   
     /** Time of the start of the build */
 85   
     private long startTime = System.currentTimeMillis();
 86   
 
 87   
     /** Line separator */
 88   
     protected static final String lSep = StringUtils.LINE_SEP;
 89   
     
 90   
     /** Whether or not to use emacs-style output */
 91   
     protected boolean emacsMode = false;
 92   
 
 93   
     /**
 94   
      * Sole constructor.
 95   
      */
 96  5
     public DefaultLogger() {
 97   
     }
 98   
 
 99   
     /**
 100   
      * Sets the highest level of message this logger should respond to.
 101   
      *
 102   
      * Only messages with a message level lower than or equal to the 
 103   
      * given level should be written to the log.
 104   
      * <P>
 105   
      * Constants for the message levels are in the 
 106   
      * {@link Project Project} class. The order of the levels, from least 
 107   
      * to most verbose, is <code>MSG_ERR</code>, <code>MSG_WARN</code>, 
 108   
      * <code>MSG_INFO</code>, <code>MSG_VERBOSE</code>, 
 109   
      * <code>MSG_DEBUG</code>.
 110   
      * <P>
 111   
      * The default message level for DefaultLogger is Project.MSG_ERR.
 112   
      * 
 113   
      * @param level the logging level for the logger.
 114   
      */
 115  5
     public void setMessageOutputLevel(int level) {
 116  5
         this.msgOutputLevel = level;
 117   
     }
 118   
 
 119   
     /**
 120   
      * Sets the output stream to which this logger is to send its output.
 121   
      *
 122   
      * @param output The output stream for the logger.
 123   
      *               Must not be <code>null</code>.
 124   
      */
 125  5
     public void setOutputPrintStream(PrintStream output) {
 126  5
         this.out = new PrintStream(output, true);
 127   
     }
 128   
 
 129   
     /**
 130   
      * Sets the output stream to which this logger is to send error messages.
 131   
      *
 132   
      * @param err The error stream for the logger.
 133   
      *            Must not be <code>null</code>.
 134   
      */
 135  5
     public void setErrorPrintStream(PrintStream err) {
 136  5
         this.err = new PrintStream(err, true);
 137   
     }
 138   
 
 139   
     /**
 140   
      * Sets this logger to produce emacs (and other editor) friendly output.
 141   
      *
 142   
      * @param emacsMode <code>true</code> if output is to be unadorned so that
 143   
      *                  emacs and other editors can parse files names, etc.
 144   
      */
 145  1
     public void setEmacsMode(boolean emacsMode) {
 146  1
         this.emacsMode = emacsMode;
 147   
     }
 148   
 
 149   
     /**
 150   
      * Responds to a build being started by just remembering the current time.
 151   
      * 
 152   
      * @param event Ignored.
 153   
      */
 154  1
     public void buildStarted(BuildEvent event) {
 155  1
         startTime = System.currentTimeMillis();
 156   
     }
 157   
 
 158   
     /**
 159   
      * Prints whether the build succeeded or failed,
 160   
      * any errors the occured during the build, and
 161   
      * how long the build took.
 162   
      * 
 163   
      * @param event An event with any relevant extra information.
 164   
      *              Must not be <code>null</code>.
 165   
      */
 166  1
     public void buildFinished(BuildEvent event) {
 167  1
         Throwable error = event.getException();
 168  1
         StringBuffer message = new StringBuffer();
 169   
 
 170  1
         if (error == null) {
 171  0
             message.append(StringUtils.LINE_SEP);
 172  0
             message.append("BUILD SUCCESSFUL");
 173   
         } else {
 174  1
             message.append(StringUtils.LINE_SEP);
 175  1
             message.append("BUILD FAILED");
 176  1
             message.append(StringUtils.LINE_SEP);
 177   
 
 178  1
             if (Project.MSG_VERBOSE <= msgOutputLevel ||
 179   
                 !(error instanceof BuildException)) {
 180  0
                 message.append(StringUtils.getStackTrace(error));
 181   
             } else {
 182  1
                 if (error instanceof BuildException) {
 183  1
                     message.append(error.toString()).append(lSep);
 184   
                 } else {
 185  0
                     message.append(error.getMessage()).append(lSep);
 186   
                 }
 187   
             }
 188   
         }
 189  1
         message.append(StringUtils.LINE_SEP);
 190  1
         message.append("Total time: ");
 191  1
         message.append(formatTime(System.currentTimeMillis() - startTime));
 192   
 
 193  1
         String msg = message.toString();
 194  1
         if (error == null) {
 195  0
             printMessage(msg, out, Project.MSG_VERBOSE);
 196   
         } else {
 197  1
             printMessage(msg, err, Project.MSG_ERR);
 198   
         }
 199  1
         log(msg);
 200   
     }
 201   
 
 202   
     /**
 203   
      * Logs a message to say that the target has started if this
 204   
      * logger allows information-level messages.
 205   
      * 
 206   
      * @param event An event with any relevant extra information.
 207   
      *              Must not be <code>null</code>.
 208   
       */
 209  14
     public void targetStarted(BuildEvent event) {
 210  14
         if (Project.MSG_INFO <= msgOutputLevel
 211   
             && !event.getTarget().getName().equals("")) {
 212  14
             String msg = StringUtils.LINE_SEP 
 213   
                 + event.getTarget().getName() + ":";
 214  14
             printMessage(msg, out, event.getPriority());
 215  14
             log(msg);
 216   
         }
 217   
     }
 218   
 
 219   
     /**
 220   
      * No-op implementation.
 221   
      * 
 222   
      * @param event Ignored.
 223   
      */
 224  14
     public void targetFinished(BuildEvent event) {}
 225   
 
 226   
     /**
 227   
      * No-op implementation.
 228   
      * 
 229   
      * @param event Ignored.
 230   
      */
 231  171
     public void taskStarted(BuildEvent event) {}
 232   
 
 233   
     /**
 234   
      * No-op implementation.
 235   
      * 
 236   
      * @param event Ignored.
 237   
      */
 238  171
     public void taskFinished(BuildEvent event) {}
 239   
 
 240   
     /**
 241   
      * Logs a message, if the priority is suitable.
 242   
      * In non-emacs mode, task level messages are prefixed by the
 243   
      * task name which is right-justified.
 244   
      * 
 245   
      * @param event A BuildEvent containing message information.
 246   
      *              Must not be <code>null</code>.
 247   
      */
 248  13009
     public void messageLogged(BuildEvent event) {
 249  13009
         int priority = event.getPriority();
 250   
         // Filter out messages based on priority
 251  13009
         if (priority <= msgOutputLevel) {
 252   
 
 253  1121
             StringBuffer message = new StringBuffer();
 254  1121
             if (event.getTask() != null && !emacsMode) {
 255   
                 // Print out the name of the task if we're in one
 256  1121
                 String name = event.getTask().getTaskName();
 257  1121
                 String label = "[" + name + "] ";
 258  1121
                 int size = LEFT_COLUMN_SIZE - label.length();
 259  1121
                 StringBuffer tmp = new StringBuffer();
 260  1121
                 for (int i = 0; i < size; i++) {
 261  4487
                     tmp.append(" ");
 262   
                 }
 263  1121
                 tmp.append(label);
 264  1121
                 label = tmp.toString();
 265   
 
 266  1121
                 try {
 267  1121
                     BufferedReader r = 
 268   
                         new BufferedReader(
 269   
                             new StringReader(event.getMessage()));
 270  1121
                     String line = r.readLine();
 271  1121
                     boolean first = true;
 272  1121
                     while (line != null) {
 273  966
                         if (!first) {
 274  0
                             message.append(StringUtils.LINE_SEP);
 275   
                         }
 276  966
                         first = false;
 277  966
                         message.append(label).append(line);
 278  966
                         line = r.readLine();
 279   
                     }
 280   
                 } catch (IOException e) {
 281   
                     // shouldn't be possible
 282  0
                     message.append(label).append(event.getMessage());
 283   
                 }
 284   
             } else {
 285  0
                 message.append(event.getMessage());
 286   
             }
 287   
 
 288  1121
             String msg = message.toString();
 289  1121
             if (priority != Project.MSG_ERR) {
 290  1119
                 printMessage(msg, out, priority);
 291   
             } else {
 292  2
                 printMessage(msg, err, priority);
 293   
             }
 294  1121
             log(msg);
 295   
         }
 296   
     }
 297   
 
 298   
     /**
 299   
      * Convenience method to format a specified length of time.
 300   
      * 
 301   
      * @param millis Length of time to format, in milliseonds.
 302   
      * 
 303   
      * @return the time as a formatted string.
 304   
      *
 305   
      * @see DateUtils#formatElapsedTime(long)
 306   
      */
 307  1
     protected static String formatTime(final long millis) {
 308  1
         return DateUtils.formatElapsedTime(millis);
 309   
     }
 310   
 
 311   
     /**
 312   
      * Prints a message to a PrintStream.
 313   
      * 
 314   
      * @param message  The message to print. 
 315   
      *                 Should not be <code>null</code>.
 316   
      * @param stream   A PrintStream to print the message to. 
 317   
      *                 Must not be <code>null</code>.
 318   
      * @param priority The priority of the message. 
 319   
      *                 (Ignored in this implementation.)
 320   
      */
 321  1136
     protected void printMessage(final String message,
 322   
                                 final PrintStream stream,
 323   
                                 final int priority) {
 324  1136
         stream.println(message);
 325   
     }
 326   
 
 327   
     /**
 328   
      * Empty implementation which allows subclasses to receive the
 329   
      * same output that is generated here.
 330   
      * 
 331   
      * @param message Message being logged. Should not be <code>null</code>.
 332   
      */
 333  1136
     protected void log(String message) {}
 334   
 }
 335