buildframework/helium/tools/common/java/src/com/nokia/ant/taskdefs/TextLogRecorderEntry.java
changeset 1 be27ed110b50
child 179 d8ac696cc51f
equal deleted inserted replaced
0:044383f39525 1:be27ed110b50
       
     1 /*
       
     2  *  Licensed to the Apache Software Foundation (ASF) under one or more
       
     3  *  contributor license agreements.  See the NOTICE file distributed with
       
     4  *  this work for additional information regarding copyright ownership.
       
     5  *  The ASF licenses this file to You under the Apache License, Version 2.0
       
     6  *  (the "License"); you may not use this file except in compliance with
       
     7  *  the License.  You may obtain a copy of the License at
       
     8  *
       
     9  *      http://www.apache.org/licenses/LICENSE-2.0
       
    10  *
       
    11  *  Unless required by applicable law or agreed to in writing, software
       
    12  *  distributed under the License is distributed on an "AS IS" BASIS,
       
    13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14  *  See the License for the specific language governing permissions and
       
    15  *  limitations under the License.
       
    16  *
       
    17  */
       
    18  
       
    19  /* * Portion Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.*/
       
    20  
       
    21 package com.nokia.ant.taskdefs;
       
    22 
       
    23 import java.io.FileOutputStream;
       
    24 import java.io.IOException;
       
    25 import java.io.PrintStream;
       
    26 import java.util.regex.Matcher;
       
    27 import java.util.regex.Pattern;
       
    28 
       
    29 import com.nokia.ant.types.LogFilterSet;
       
    30 
       
    31 import org.apache.tools.ant.BuildEvent;
       
    32 import org.apache.tools.ant.BuildException;
       
    33 import org.apache.tools.ant.DefaultLogger;
       
    34 import org.apache.tools.ant.Project;
       
    35 import org.apache.tools.ant.SubBuildListener;
       
    36 import org.apache.tools.ant.util.StringUtils;
       
    37 
       
    38 /**
       
    39  * This is a class that represents a recorder. This is the listener to the build
       
    40  * process.
       
    41  * 
       
    42  * @since Ant 1.4
       
    43  */
       
    44 public class TextLogRecorderEntry implements LogRecorderEntry, SubBuildListener
       
    45 {
       
    46 
       
    47     // ////////////////////////////////////////////////////////////////////
       
    48     // ATTRIBUTES
       
    49 
       
    50     /** The name of the file associated with this recorder entry. */
       
    51     private String filename;
       
    52 
       
    53     /** The state of the recorder (recorder on or off). */
       
    54     private boolean record = true;
       
    55 
       
    56     /** The current verbosity level to record at. */
       
    57     private int loglevel = Project.MSG_INFO;
       
    58 
       
    59     /** The output PrintStream to record to. */
       
    60     private PrintStream out;
       
    61 
       
    62     /** The start time of the last know target. */
       
    63     private long targetStartTime;
       
    64 
       
    65     /** Strip task banners if true. */
       
    66     private boolean emacsMode;
       
    67     
       
    68     private LogFilterSet filterset;
       
    69         
       
    70     private Pattern pattern;
       
    71 
       
    72     /** project instance the recorder is associated with */
       
    73     private Project project;
       
    74     
       
    75 
       
    76     // ////////////////////////////////////////////////////////////////////
       
    77     // CONSTRUCTORS / INITIALIZERS
       
    78 
       
    79     /**
       
    80      * @param name
       
    81      *            The name of this recorder (used as the filename).
       
    82      */
       
    83     protected TextLogRecorderEntry(String name)
       
    84     {
       
    85         targetStartTime = System.currentTimeMillis();
       
    86         filename = name;
       
    87     }
       
    88 
       
    89     // ////////////////////////////////////////////////////////////////////
       
    90     // ACCESSOR METHODS
       
    91 
       
    92     /**
       
    93      * @return the name of the file the output is sent to.
       
    94      */
       
    95     public String getFilename()
       
    96     {
       
    97         return filename;
       
    98     }
       
    99 
       
   100     /**
       
   101      * Turns off or on this recorder.
       
   102      * 
       
   103      * @param state
       
   104      *            true for on, false for off, null for no change.
       
   105      */
       
   106     public void setRecordState(boolean state)
       
   107     {
       
   108         flush();
       
   109         record = state;
       
   110     }
       
   111     
       
   112     public void setRegexp(String regexp)
       
   113     {        
       
   114         pattern = Pattern.compile(Pattern.quote(regexp));
       
   115     }
       
   116     
       
   117     public void setFilterSet(LogFilterSet o)
       
   118     {
       
   119         System.out.println("setFilterSet: " + o);
       
   120         filterset = o;
       
   121     }
       
   122 
       
   123     /**
       
   124      * @see org.apache.tools.ant.BuildListener#buildStarted(BuildEvent)
       
   125      */
       
   126     /** {@inheritDoc}. */
       
   127     public void buildStarted(BuildEvent event)
       
   128     {
       
   129         log("> BUILD STARTED", Project.MSG_DEBUG);
       
   130     }
       
   131 
       
   132     /**
       
   133      * @see org.apache.tools.ant.BuildListener#buildFinished(BuildEvent)
       
   134      */
       
   135     /** {@inheritDoc}. */
       
   136     public void buildFinished(BuildEvent event)
       
   137     {
       
   138         log("< BUILD FINISHED", Project.MSG_DEBUG);
       
   139 
       
   140         if (record && out != null)
       
   141         {
       
   142             Throwable error = event.getException();
       
   143 
       
   144             if (error == null)
       
   145             {
       
   146                 out.println(StringUtils.LINE_SEP + "BUILD SUCCESSFUL");
       
   147             }
       
   148             else
       
   149             {
       
   150                 out.println(StringUtils.LINE_SEP + "BUILD FAILED" + StringUtils.LINE_SEP);
       
   151                 error.printStackTrace(out);
       
   152             }
       
   153         }
       
   154         cleanup();
       
   155     }
       
   156 
       
   157     /**
       
   158      * Cleans up any resources held by this recorder entry at the end of a
       
   159      * subbuild if it has been created for the subbuild's project instance.
       
   160      * 
       
   161      * @param event
       
   162      *            the buildFinished event
       
   163      * 
       
   164      * @since Ant 1.6.2
       
   165      */
       
   166     public void subBuildFinished(BuildEvent event)
       
   167     {
       
   168         if (event.getProject() == project)
       
   169         {
       
   170             cleanup();
       
   171         }
       
   172     }
       
   173 
       
   174     /**
       
   175      * Empty implementation to satisfy the BuildListener interface.
       
   176      * 
       
   177      * @param event
       
   178      *            the buildStarted event
       
   179      * 
       
   180      * @since Ant 1.6.2
       
   181      */
       
   182     public void subBuildStarted(BuildEvent event)
       
   183     {
       
   184     }
       
   185 
       
   186     /**
       
   187      * @see org.apache.tools.ant.BuildListener#targetStarted(BuildEvent)
       
   188      */
       
   189     /** {@inheritDoc}. */
       
   190     public void targetStarted(BuildEvent event)
       
   191     {
       
   192         log(">> TARGET STARTED -- " + event.getTarget(), Project.MSG_DEBUG);
       
   193         log(StringUtils.LINE_SEP + event.getTarget().getName() + ":", Project.MSG_INFO);
       
   194         targetStartTime = System.currentTimeMillis();
       
   195     }
       
   196 
       
   197     /**
       
   198      * @see org.apache.tools.ant.BuildListener#targetFinished(BuildEvent)
       
   199      */
       
   200     /** {@inheritDoc}. */
       
   201     public void targetFinished(BuildEvent event)
       
   202     {
       
   203         log("<< TARGET FINISHED -- " + event.getTarget(), Project.MSG_DEBUG);
       
   204 
       
   205         String time = formatTime(System.currentTimeMillis() - targetStartTime);
       
   206 
       
   207         log(event.getTarget() + ":  duration " + time, Project.MSG_VERBOSE);
       
   208         flush();
       
   209     }
       
   210 
       
   211     /**
       
   212      * @see org.apache.tools.ant.BuildListener#taskStarted(BuildEvent)
       
   213      */
       
   214     /** {@inheritDoc}. */
       
   215     public void taskStarted(BuildEvent event)
       
   216     {
       
   217         log(">>> TASK STARTED -- " + event.getTask(), Project.MSG_DEBUG);
       
   218     }
       
   219 
       
   220     /**
       
   221      * @see org.apache.tools.ant.BuildListener#taskFinished(BuildEvent)
       
   222      */
       
   223     /** {@inheritDoc}. */
       
   224     public void taskFinished(BuildEvent event)
       
   225     {
       
   226         log("<<< TASK FINISHED -- " + event.getTask(), Project.MSG_DEBUG);
       
   227         flush();
       
   228     }
       
   229 
       
   230     /**
       
   231      * @see org.apache.tools.ant.BuildListener#messageLogged(BuildEvent)
       
   232      */
       
   233     /** {@inheritDoc}. */
       
   234     public void messageLogged(BuildEvent event)
       
   235     {
       
   236         log("--- MESSAGE LOGGED", Project.MSG_DEBUG);
       
   237 
       
   238         StringBuffer buf = new StringBuffer();
       
   239 
       
   240         if (event.getTask() != null)
       
   241         {
       
   242             String name = event.getTask().getTaskName();
       
   243 
       
   244             if (!emacsMode)
       
   245             {
       
   246                 String label = "[" + name + "] ";
       
   247                 int size = DefaultLogger.LEFT_COLUMN_SIZE - label.length();
       
   248 
       
   249                 for (int i = 0; i < size; i++)
       
   250                 {
       
   251                     buf.append(" ");
       
   252                 }
       
   253                 buf.append(label);
       
   254             }
       
   255         }
       
   256         String message = event.getMessage();
       
   257         String filteredMessage = filterMessage(message);
       
   258         buf.append(filteredMessage);
       
   259 
       
   260         log(buf.toString(), event.getPriority());
       
   261     }
       
   262     
       
   263     private String filterMessage(String message)
       
   264     {
       
   265         if (pattern != null)
       
   266         {
       
   267         Matcher match = pattern.matcher(message);
       
   268         message = match.replaceAll("********");
       
   269     }
       
   270         return message;
       
   271     }
       
   272 
       
   273     /**
       
   274      * The thing that actually sends the information to the output.
       
   275      * 
       
   276      * @param mesg
       
   277      *            The message to log.
       
   278      * @param level
       
   279      *            The verbosity level of the message.
       
   280      */
       
   281     private void log(String mesg, int level)
       
   282     {
       
   283         if (record && (level <= loglevel) && out != null)
       
   284         {
       
   285             out.println(mesg);
       
   286         }
       
   287     }
       
   288 
       
   289     private void flush()
       
   290     {
       
   291         if (record && out != null)
       
   292         {
       
   293             out.flush();
       
   294         }
       
   295     }
       
   296 
       
   297     /**
       
   298      * @see BuildLogger#setMessageOutputLevel(int)
       
   299      */
       
   300     /** {@inheritDoc}. */
       
   301     public void setMessageOutputLevel(int level)
       
   302     {
       
   303         if (level >= Project.MSG_ERR && level <= Project.MSG_DEBUG)
       
   304         {
       
   305             loglevel = level;
       
   306         }
       
   307     }
       
   308 
       
   309     /**
       
   310      * @see BuildLogger#setOutputPrintStream(PrintStream)
       
   311      */
       
   312     /**
       
   313      * 
       
   314      * @param output Output print stream
       
   315      * 
       
   316      */
       
   317     public void setOutputPrintStream(PrintStream output)
       
   318     {
       
   319         closeFile();
       
   320         out = output;
       
   321     }
       
   322 
       
   323     /**
       
   324      * @see BuildLogger#setEmacsMode(boolean)
       
   325      */
       
   326     /** {@inheritDoc}. */
       
   327     public void setEmacsMode(boolean emacsMode)
       
   328     {
       
   329         this.emacsMode = emacsMode;
       
   330     }
       
   331 
       
   332     /**
       
   333      * @see BuildLogger#setErrorPrintStream(PrintStream)
       
   334      */
       
   335     /**
       
   336      * 
       
   337      * @param err Error print stream
       
   338      * 
       
   339      */
       
   340     public void setErrorPrintStream(PrintStream err)
       
   341     {
       
   342         setOutputPrintStream(err);
       
   343     }
       
   344 
       
   345     private static String formatTime(long millis)
       
   346     {
       
   347         long seconds = millis / 1000;
       
   348         long minutes = seconds / 60;
       
   349 
       
   350         if (minutes > 0)
       
   351         {
       
   352             return Long.toString(minutes) + " minute" + (minutes == 1 ? " " : "s ")
       
   353                     + Long.toString(seconds % 60) + " second" + (seconds % 60 == 1 ? "" : "s");
       
   354         }
       
   355         else
       
   356         {
       
   357             return Long.toString(seconds) + " second" + (seconds % 60 == 1 ? "" : "s");
       
   358         }
       
   359 
       
   360     }
       
   361 
       
   362     /**
       
   363      * Set the project associated with this recorder entry.
       
   364      * 
       
   365      * @param project
       
   366      *            the project instance
       
   367      * 
       
   368      * @since 1.6.2
       
   369      */
       
   370     public void setProject(Project project)
       
   371     {
       
   372         this.project = project;
       
   373         if (project != null)
       
   374         {
       
   375             project.addBuildListener(this);
       
   376         }
       
   377     }
       
   378 
       
   379     /**
       
   380      * @since 1.6.2
       
   381      */
       
   382     public void cleanup()
       
   383     {
       
   384         closeFile();
       
   385         if (project != null)
       
   386         {
       
   387             project.removeBuildListener(this);
       
   388         }
       
   389         project = null;
       
   390     }
       
   391 
       
   392     /**
       
   393      * Initially opens the file associated with this recorder. Used by Recorder.
       
   394      * 
       
   395      * @param append
       
   396      *            Indicates if output must be appended to the logfile or that
       
   397      *            the logfile should be overwritten.
       
   398      * @throws BuildException
       
   399      * @since 1.6.3
       
   400      */
       
   401     public void openFile(boolean append)
       
   402     {
       
   403         openFileImpl(append);
       
   404     }
       
   405 
       
   406     /**
       
   407      * Closes the file associated with this recorder. Used by Recorder.
       
   408      * 
       
   409      * @since 1.6.3
       
   410      */
       
   411     public void closeFile()
       
   412     {
       
   413         if (out != null)
       
   414         {
       
   415             out.close();
       
   416             out = null;
       
   417         }
       
   418     }
       
   419 
       
   420     /**
       
   421      * Re-opens the file associated with this recorder. Used by Recorder.
       
   422      * 
       
   423      * @throws BuildException
       
   424      * @since 1.6.3
       
   425      */
       
   426     public void reopenFile()
       
   427     {
       
   428         openFileImpl(true);
       
   429     }
       
   430 
       
   431     private void openFileImpl(boolean append)
       
   432     {
       
   433         if (out == null)
       
   434         {
       
   435             try
       
   436             {
       
   437                 out = new PrintStream(new FileOutputStream(filename, append));
       
   438             }
       
   439             catch (IOException ioe)
       
   440             {
       
   441                 throw new BuildException("Problems opening file using a " + "recorder entry", ioe);
       
   442             }
       
   443         }
       
   444     }
       
   445 
       
   446 }