buildframework/helium/sf/java/logging/src/com/nokia/helium/logger/ant/listener/RecorderEntry.java
changeset 628 7c4a911dc066
parent 588 c7c26511138f
child 645 b8d81fa19e7d
equal deleted inserted replaced
588:c7c26511138f 628:7c4a911dc066
     1 /*
     1 /*
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
     2  * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3  * All rights reserved.
     4 * This component and the accompanying materials are made available
     4  * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     5  * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6  * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     8  *
     9 * Initial Contributors:
     9  * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    10  * Nokia Corporation - initial contribution.
    11 *
    11  *
    12 * Contributors:
    12  * Contributors:
    13 *
    13  *
    14 * Description:  
    14  * Description:  
    15 *
    15  *
    16 */
    16  */
    17 package com.nokia.helium.logger.ant.listener;
    17 package com.nokia.helium.logger.ant.listener;
    18 
    18 
       
    19 import java.io.File;
       
    20 import java.io.FileOutputStream;
       
    21 import java.io.IOException;
    19 import java.io.PrintStream;
    22 import java.io.PrintStream;
       
    23 import java.util.Vector;
       
    24 import java.util.regex.Matcher;
       
    25 import java.util.regex.Pattern;
    20 
    26 
    21 import org.apache.log4j.Logger;
    27 import org.apache.log4j.Logger;
    22 import org.apache.tools.ant.BuildEvent;
    28 import org.apache.tools.ant.BuildEvent;
       
    29 import org.apache.tools.ant.BuildException;
    23 import org.apache.tools.ant.DefaultLogger;
    30 import org.apache.tools.ant.DefaultLogger;
    24 import org.apache.tools.ant.Project;
    31 import org.apache.tools.ant.Project;
    25 import org.apache.tools.ant.util.StringUtils;
    32 import org.apache.tools.ant.util.StringUtils;
    26 import org.apache.tools.ant.BuildException;
       
    27 
       
    28 import java.io.File;
       
    29 import java.io.FileOutputStream;
       
    30 import java.io.IOException;
       
    31 import java.util.Vector;
       
    32 import java.util.regex.Matcher;
       
    33 import java.util.regex.Pattern;
       
    34 
    33 
    35 /**
    34 /**
    36  * This is a class that represents a recorder. This is the listener to the
    35  * This is a class that represents a recorder. This is the listener to the build process.
    37  * build process.
    36  * 
    38  *
       
    39  * @since Ant 1.4
    37  * @since Ant 1.4
    40  */
    38  */
    41 public class RecorderEntry implements BuildEventHandler, TargetEventHandler, TaskEventHandler, MessageEventHandler {
    39 public class RecorderEntry implements BuildEventHandler, TargetEventHandler, TaskEventHandler,
    42 
    40     MessageEventHandler {
    43     //////////////////////////////////////////////////////////////////////
    41 
    44     // ATTRIBUTES
    42     /** The name of the file associated with this recorder entry. */
    45 
       
    46     /** The name of the file associated with this recorder entry.  */
       
    47     private File filename;
    43     private File filename;
    48     /** The state of the recorder (recorder on or off).  */
    44     /** The state of the recorder (recorder on or off). */
    49     private boolean record = true;
    45     private boolean record = true;
    50     /** The current verbosity level to record at.  */
    46     /** The current verbosity level to record at. */
    51     private int loglevel = Project.MSG_INFO;
    47     private int loglevel = Project.MSG_INFO;
    52     /** The output PrintStream to record to.  */
    48     /** The output PrintStream to record to. */
    53     private PrintStream out;
    49     private PrintStream out;
    54     /** The start time of the last know target.  */
    50     /** The start time of the last know target. */
    55     private long targetStartTime;
    51     private long targetStartTime;
    56     /** Strip task banners if true.  */
    52     /** Strip task banners if true. */
    57     private boolean emacsMode;
    53     private boolean emacsMode;
    58     
    54 
    59     private Pattern pattern;
    55     private Pattern pattern;
    60     
    56 
    61     private Vector<String> logRegExps = new Vector<String>();
    57     private Vector<String> logRegExps = new Vector<String>();
    62     private Logger log = Logger.getLogger(getClass());
    58     private Logger log = Logger.getLogger(getClass());
    63 
       
    64     
       
    65     //////////////////////////////////////////////////////////////////////
       
    66     // CONSTRUCTORS / INITIALIZERS
       
    67 
    59 
    68     /**
    60     /**
    69      * @param name The name of this recorder (used as the filename).
    61      * @param name The name of this recorder (used as the filename).
    70      */
    62      */
    71     public RecorderEntry(File name) {
    63     public RecorderEntry(File name) {
    72         targetStartTime = System.currentTimeMillis();
    64         targetStartTime = System.currentTimeMillis();
    73         filename = name;
    65         filename = name;
    74     }
    66     }
    75 
    67 
    76     //////////////////////////////////////////////////////////////////////
       
    77     // ACCESSOR METHODS
       
    78 
       
    79     /**
    68     /**
    80      * @return the name of the file the output is sent to.
    69      * @return the name of the file the output is sent to.
    81      */
    70      */
    82     public File getFilename() {
    71     public File getFilename() {
    83         return filename;
    72         return filename;
    84     }
    73     }
    85 
    74 
    86     /**
    75     /**
    87      * Turns off or on this recorder.
    76      * Turns off or on this recorder.
    88      *
    77      * 
    89      * @param state true for on, false for off, null for no change.
    78      * @param state true for on, false for off, null for no change.
    90      */
    79      */
    91     public void setRecordState(boolean state) {
    80     public void setRecordState(boolean state) {
    92          flush();
    81         flush();
    93          record = state;
    82         record = state;
    94     }
    83     }
    95 
    84 
    96     /**
    85     /**
    97      * Get the current state of the recorder
    86      * Get the current state of the recorder
       
    87      * 
    98      * @param state
    88      * @param state
    99      */
    89      */
   100     public boolean getRecordState() {
    90     public boolean getRecordState() {
   101         return record;
    91         return record;
   102     }
    92     }
   103     
    93 
   104     /**
    94     /**
   105      * To set the regexp to filter the logging.
    95      * To set the regexp to filter the logging.
       
    96      * 
   106      * @param regexp
    97      * @param regexp
   107      */
    98      */
   108     public void addRegexp(String regexp) {
    99     public void addRegexp(String regexp) {
   109         logRegExps.add(regexp);
   100         logRegExps.add(regexp);
   110     }
   101     }
   111     
   102 
   112     /**
   103     /**
   113      * To clear all regexp set.
   104      * To clear all regexp set.
   114      */
   105      */
   115     public void resetRegExp() { 
   106     public void resetRegExp() {
   116         logRegExps.clear();
   107         logRegExps.clear();
   117     }
   108     }
   118 
   109 
   119     /**
   110     /**
   120      * @see org.apache.tools.ant.BuildListener#buildStarted(BuildEvent)
   111      * @see org.apache.tools.ant.BuildListener#buildStarted(BuildEvent)
   134         if (record && out != null) {
   125         if (record && out != null) {
   135             Throwable error = event.getException();
   126             Throwable error = event.getException();
   136 
   127 
   137             if (error == null) {
   128             if (error == null) {
   138                 out.println(StringUtils.LINE_SEP + "BUILD SUCCESSFUL");
   129                 out.println(StringUtils.LINE_SEP + "BUILD SUCCESSFUL");
   139             } else {
   130             }
   140                 out.println(StringUtils.LINE_SEP + "BUILD FAILED"
   131             else {
   141                             + StringUtils.LINE_SEP);
   132                 out.println(StringUtils.LINE_SEP + "BUILD FAILED" + StringUtils.LINE_SEP);
   142                 error.printStackTrace(out);
   133                 error.printStackTrace(out);
   143             }
   134             }
   144         }
   135         }
   145         cleanup();
   136         cleanup();
   146     }
   137     }
   147 
   138 
   148     /**
   139     /**
   149      * Cleans up any resources held by this recorder entry at the end
   140      * Cleans up any resources held by this recorder entry at the end of a subbuild if it has been
   150      * of a subbuild if it has been created for the subbuild's project
   141      * created for the subbuild's project instance.
   151      * instance.
   142      * 
   152      *
       
   153      * @param event the buildFinished event
   143      * @param event the buildFinished event
   154      *
   144      * 
   155      * @since Ant 1.6.2
   145      * @since Ant 1.6.2
   156      */
   146      */
   157     public void handleSubBuildFinished(BuildEvent event) {
   147     public void handleSubBuildFinished(BuildEvent event) {
   158         log("< SUBBUILD FINISHED", Project.MSG_DEBUG);
   148         log("< SUBBUILD FINISHED", Project.MSG_DEBUG);
   159         // let's keep the logging ongoing, even if sub-build finishes.
   149         // let's keep the logging ongoing, even if sub-build finishes.
   160     }
   150     }
   161 
   151 
   162     /**
   152     /**
   163      * Empty implementation to satisfy the BuildListener interface.
   153      * Empty implementation to satisfy the BuildListener interface.
   164      *
   154      * 
   165      * @param event the buildStarted event
   155      * @param event the buildStarted event
   166      *
   156      * 
   167      * @since Ant 1.6.2
   157      * @since Ant 1.6.2
   168      */
   158      */
   169     public void handleSubBuildStarted(BuildEvent event) {
   159     public void handleSubBuildStarted(BuildEvent event) {
   170         log("< SUBBUILD STARTED", Project.MSG_DEBUG);
   160         log("< SUBBUILD STARTED", Project.MSG_DEBUG);
   171     }
   161     }
   173     /**
   163     /**
   174      * {@inheritDoc}
   164      * {@inheritDoc}
   175      */
   165      */
   176     public void handleTargetStarted(BuildEvent event) {
   166     public void handleTargetStarted(BuildEvent event) {
   177         log(">> TARGET STARTED -- " + event.getTarget(), Project.MSG_DEBUG);
   167         log(">> TARGET STARTED -- " + event.getTarget(), Project.MSG_DEBUG);
   178         log(StringUtils.LINE_SEP + event.getTarget().getName() + ":",
   168         log(StringUtils.LINE_SEP + event.getTarget().getName() + ":", Project.MSG_INFO);
   179             Project.MSG_INFO);
       
   180         targetStartTime = System.currentTimeMillis();
   169         targetStartTime = System.currentTimeMillis();
   181     }
   170     }
   182 
   171 
   183     /**
   172     /**
   184      * {@inheritDoc}
   173      * {@inheritDoc}
   233         }
   222         }
   234         String messgeToUpdate = filterMessage(event.getMessage());
   223         String messgeToUpdate = filterMessage(event.getMessage());
   235         buf.append(messgeToUpdate);
   224         buf.append(messgeToUpdate);
   236         log(buf.toString(), event.getPriority());
   225         log(buf.toString(), event.getPriority());
   237     }
   226     }
   238     
   227 
   239     
       
   240     /**
   228     /**
   241      * To replace regExp matching with ****.
   229      * To replace regExp matching with ****.
       
   230      * 
   242      * @param message
   231      * @param message
   243      * @return
   232      * @return
   244      */
   233      */
   245     private String filterMessage(String message) {
   234     private String filterMessage(String message) {
   246         for (String regExp : logRegExps) {
   235         for (String regExp : logRegExps) {
   251             }
   240             }
   252         }
   241         }
   253         return message;
   242         return message;
   254     }
   243     }
   255 
   244 
   256 
       
   257     /**
   245     /**
   258      * The thing that actually sends the information to the output.
   246      * The thing that actually sends the information to the output.
   259      *
   247      * 
   260      * @param mesg The message to log.
   248      * @param mesg The message to log.
   261      * @param level The verbosity level of the message.
   249      * @param level The verbosity level of the message.
   262      */
   250      */
   263     private void log(String msg, int level) {
   251     private void log(String msg, int level) {
   264         if (record && (level <= loglevel) && out != null) {
   252         if (record && (level <= loglevel) && out != null) {
   289     public void setOutputPrintStream(PrintStream output) {
   277     public void setOutputPrintStream(PrintStream output) {
   290         closeFile();
   278         closeFile();
   291         out = output;
   279         out = output;
   292     }
   280     }
   293 
   281 
   294 
       
   295     /**
   282     /**
   296      * @see BuildLogger#setEmacsMode(boolean)
   283      * @see BuildLogger#setEmacsMode(boolean)
   297      */
   284      */
   298     /** {@inheritDoc}. */
   285     /** {@inheritDoc}. */
   299     public void setEmacsMode(boolean emacsMode) {
   286     public void setEmacsMode(boolean emacsMode) {
   300         this.emacsMode = emacsMode;
   287         this.emacsMode = emacsMode;
   301     }
   288     }
   302 
   289 
   303 
       
   304     /**
   290     /**
   305      * @see BuildLogger#setErrorPrintStream(PrintStream)
   291      * @see BuildLogger#setErrorPrintStream(PrintStream)
   306      */
   292      */
   307     /** {@inheritDoc}. */
   293     /** {@inheritDoc}. */
   308     public void setErrorPrintStream(PrintStream err) {
   294     public void setErrorPrintStream(PrintStream err) {
   309         setOutputPrintStream(err);
   295         setOutputPrintStream(err);
   310     }
   296     }
   311 
       
   312 
   297 
   313     private static String formatTime(long millis) {
   298     private static String formatTime(long millis) {
   314         // CheckStyle:MagicNumber OFF
   299         // CheckStyle:MagicNumber OFF
   315         long seconds = millis / 1000;
   300         long seconds = millis / 1000;
   316         long minutes = seconds / 60;
   301         long minutes = seconds / 60;
   317 
   302 
   318 
       
   319         if (minutes > 0) {
   303         if (minutes > 0) {
   320             return Long.toString(minutes) + " minute"
   304             return Long.toString(minutes) + " minute" + (minutes == 1 ? " " : "s ")
   321                  + (minutes == 1 ? " " : "s ")
   305                 + Long.toString(seconds % 60) + " second" + (seconds % 60 == 1 ? "" : "s");
   322                  + Long.toString(seconds % 60) + " second"
   306         }
   323                  + (seconds % 60 == 1 ? "" : "s");
   307         else {
   324         } else {
   308             return Long.toString(seconds) + " second" + (seconds % 60 == 1 ? "" : "s");
   325             return Long.toString(seconds) + " second"
       
   326                  + (seconds % 60 == 1 ? "" : "s");
       
   327         }
   309         }
   328         // CheckStyle:MagicNumber ON
   310         // CheckStyle:MagicNumber ON
   329     }
   311     }
   330     
   312 
   331     
       
   332     /**
   313     /**
   333      * Registering ourselves to the StatusAndLogListener.
   314      * Registering ourselves to the StatusAndLogListener.
   334      */
   315      */
   335     public void register() {
   316     public void register() {
   336         StatusAndLogListener listener = StatusAndLogListener.getStatusAndLogListener();
   317         StatusAndLogListener listener = StatusAndLogListener.getStatusAndLogListener();
   337         if (listener != null) {
   318         if (listener != null) {
   338             this.log.debug("register");
   319             this.log.debug("register");
   339             synchronized (listener) {
   320             synchronized (listener) {
   340                 listener.register((BuildEventHandler)this);
   321                 listener.register((BuildEventHandler) this);
   341                 listener.register((TargetEventHandler)this);
   322                 listener.register((TargetEventHandler) this);
   342                 listener.register((TaskEventHandler)this);
   323                 listener.register((TaskEventHandler) this);
   343                 listener.register((MessageEventHandler)this);
   324                 listener.register((MessageEventHandler) this);
   344             }
   325             }
   345         }
   326         }
   346     }
   327     }
   347 
   328 
   348     /**
   329     /**
   351     public void unregister() {
   332     public void unregister() {
   352         StatusAndLogListener listener = StatusAndLogListener.getStatusAndLogListener();
   333         StatusAndLogListener listener = StatusAndLogListener.getStatusAndLogListener();
   353         if (listener != null) {
   334         if (listener != null) {
   354             this.log.debug("unregister");
   335             this.log.debug("unregister");
   355             synchronized (listener) {
   336             synchronized (listener) {
   356                 listener.remove((MessageEventHandler)this);
   337                 listener.remove((MessageEventHandler) this);
   357                 listener.remove((TaskEventHandler)this);
   338                 listener.remove((TaskEventHandler) this);
   358                 listener.remove((TargetEventHandler)this);
   339                 listener.remove((TargetEventHandler) this);
   359                 listener.remove((BuildEventHandler)this);
   340                 listener.remove((BuildEventHandler) this);
   360             }
   341             }
   361         }
   342         }
   362     }
   343     }
   363     
       
   364 
   344 
   365     /**
   345     /**
   366      * @since 1.6.2
   346      * @since 1.6.2
   367      */
   347      */
   368     public void cleanup() {
   348     public void cleanup() {
   369         closeFile();
   349         closeFile();
   370     }
   350     }
   371 
   351 
   372     /**
   352     /**
   373      * Closes the file associated with this recorder.
   353      * Closes the file associated with this recorder. Used by Recorder.
   374      * Used by Recorder.
   354      * 
   375      * @since 1.6.3
   355      * @since 1.6.3
   376      */
   356      */
   377     public void closeFile() {
   357     public void closeFile() {
   378         this.log.debug("closeFile.");                
   358         this.log.debug("closeFile.");
   379         if (out != null) {
   359         if (out != null) {
   380             out.close();
   360             out.close();
   381             out = null;
   361             out = null;
   382             unregister();
   362             unregister();
   383         }
   363         }
   384     }
   364     }
   385     
   365 
   386     /**
   366     /**
   387      * Initially opens the file associated with this recorder.
   367      * Initially opens the file associated with this recorder. Used by Recorder.
   388      * Used by Recorder.
   368      * 
   389      * @param append Indicates if output must be appended to the logfile or that
   369      * @param append Indicates if output must be appended to the logfile or that the logfile should
   390      * the logfile should be overwritten.
   370      *        be overwritten.
   391      * @throws BuildException
   371      * @throws BuildException
   392      * @since 1.6.3
   372      * @since 1.6.3
   393      */
   373      */
   394     public void openFile(boolean append) {
   374     public void openFile(boolean append) {
   395         openFileImpl(append);
   375         openFileImpl(append);
   396     }
   376     }
   397     
   377 
   398     /**
   378     /**
   399      * Re-opens the file associated with this recorder.
   379      * Re-opens the file associated with this recorder. Used by Recorder.
   400      * Used by Recorder.
   380      * 
   401      * @throws BuildException
   381      * @throws BuildException
   402      * @since 1.6.3
   382      * @since 1.6.3
   403      */
   383      */
   404     public void reopenFile() {
   384     public void reopenFile() {
   405         openFileImpl(true);
   385         openFileImpl(true);
   406     }
   386     }
   407     
   387 
   408     private void openFileImpl(boolean append) {
   388     private void openFileImpl(boolean append) {
   409         if (out == null) {
   389         if (out == null) {
   410             this.log.debug("openFileImpl: " + filename);
   390             this.log.debug("openFileImpl: " + filename);
   411             try {
   391             try {
   412                 out = new PrintStream(new FileOutputStream(filename, append));
   392                 out = new PrintStream(new FileOutputStream(filename, append));
   413                 register();
   393                 register();
   414             } catch (IOException ioe) {
   394             }
   415                 throw new BuildException("Problems opening file using a "
   395             catch (IOException ioe) {
   416                                          + "recorder entry: " + ioe.getMessage(), ioe);
   396                 throw new BuildException("Problems opening file using a " + "recorder entry: "
   417             }
   397                     + ioe.getMessage(), ioe);
   418         }
   398             }
   419     }
   399         }
   420     
   400     }
       
   401 
   421     /**
   402     /**
   422      * To add user message into log file.
   403      * To add user message into log file.
       
   404      * 
   423      * @param message
   405      * @param message
   424      */
   406      */
   425     public void addLogMessage(String message) {
   407     public void addLogMessage(String message) {
   426         out.println(StringUtils.LINE_SEP + message);
   408         out.println(StringUtils.LINE_SEP + message);
   427         
   409 
   428     }
   410     }
   429     
   411 
   430     
       
   431     
       
   432 }
   412 }