buildframework/helium/tools/common/java/src/com/nokia/ant/taskdefs/LogRecorderTask.java
changeset 1 be27ed110b50
child 179 d8ac696cc51f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildframework/helium/tools/common/java/src/com/nokia/ant/taskdefs/LogRecorderTask.java	Wed Oct 28 14:39:48 2009 +0000
@@ -0,0 +1,429 @@
+/*
+* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+ 
+package com.nokia.ant.taskdefs;
+
+import java.util.Hashtable;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.SubBuildListener;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.LogLevel;
+
+import java.lang.reflect.Constructor;
+import java.io.File;
+
+/**
+ * Adds a listener to the current build process that records the output to a
+ * file.
+ * <p>
+ * Several recorders can exist at the same time. Each recorder is associated
+ * with a file. The filename is used as a unique identifier for the recorders.
+ * The first call to the recorder task with an unused filename will create a
+ * recorder (using the parameters provided) and add it to the listeners of the
+ * build. All subsequent calls to the recorder task using this filename will
+ * modify that recorders state (recording or not) or other properties (like
+ * logging level).
+ * </p>
+ * <p>
+ * Some technical issues: the file's print stream is flushed for
+ * &quot;finished&quot; events (buildFinished, targetFinished and taskFinished),
+ * and is closed on a buildFinished event.
+ * </p>
+ *
+ * @ant.task name="record" category="Utility" 
+ * @see LogRecorderEntry
+ * @version 0.5
+ * @since Ant 1.4
+ */
+public class LogRecorderTask extends Task implements SubBuildListener
+{
+
+    // ////////////////////////////////////////////////////////////////////
+    // ATTRIBUTES
+    
+    /** The list of recorder entries. */
+    private static Hashtable recorderEntries = new Hashtable();
+
+    /** The name of the file to record to. */
+    private String filename;
+
+    private String loggerclass = "nokia.ant.taskdefs.TextLogRecorderEntry";
+
+    private String filterset;
+
+    /**
+     * Whether or not to append. Need Boolean to record an unset state (null).
+     */
+    private boolean append;
+    
+    /**
+     * Whether or not to backup the old log (if exists). 
+     */
+    private boolean backup;
+
+    /**
+     * Whether to start or stop recording. Need Boolean to record an unset state
+     * (null).
+     */
+    private boolean start;
+    
+    private int loglevel = -1;
+    /** Strip task banners if true.  */
+    private boolean emacsMode;
+
+    private String regexp;
+
+    // ////////////////////////////////////////////////////////////////////
+    // CONSTRUCTORS / INITIALIZERS
+
+    /**
+     * Overridden so we can add the task as build listener.
+     * 
+     * @since Ant 1.7
+     */
+    public void init()
+    {
+        getProject().addBuildListener(this);
+    }
+
+    // ////////////////////////////////////////////////////////////////////
+    // ACCESSOR METHODS
+
+    /**
+     * Sets the name of the file to log to, and the name of the recorder entry.
+     * 
+     * @param fname
+     *            File name of logfile.
+     */
+    public void setName(String fname)
+    {
+        filename = fname;
+    }
+
+    public void setClass(String name)
+    {
+        loggerclass = name;
+    }
+
+    /**
+     * Sets the action for the associated recorder entry.
+     * 
+     * @param action
+     *            The action for the entry to take: start or stop.
+     */
+    public void setAction(ActionChoices action)
+    {
+        if (action.getValue().equalsIgnoreCase("start"))
+        {
+            start = true;
+        }
+        else
+        {
+            start = false;
+        }
+    }
+
+    /**
+     * Whether or not the logger should append to a previous file.
+     * 
+     * @param append
+     *            if true, append to a previous file.
+     */
+    public void setAppend(boolean append)
+    {
+        this.append = append;
+    }
+    
+    
+    
+    /**
+     * Whether or not the logger should backup the previous file.
+     * 
+     * @param backup
+     *            if true, backup the exising file.
+     */
+    public void setBackup(boolean backup)
+    {
+        this.backup = backup;
+    }
+    
+    
+    
+    /**
+     * Set emacs mode.
+     * @param emacsMode if true use emacs mode
+     */
+    public void setEmacsMode(boolean emacsMode) {
+        this.emacsMode = emacsMode;
+    }
+
+
+    /**
+     * Sets the level to which this recorder entry should log to.
+     * @param level the level to set.
+     * @see VerbosityLevelChoices
+     */
+    public void setLoglevel(VerbosityLevelChoices level) {
+        loglevel = level.getLevel();
+    }
+
+    /**
+     * Sets filterset
+     * 
+     * @param filterset
+     */
+    public void setFilterSet(String filterset)
+    {
+        this.filterset = filterset;
+    }
+
+    public void setRegexp(String regexp)
+    {
+        this.regexp = regexp;
+    }
+
+    // ////////////////////////////////////////////////////////////////////
+    // CORE / MAIN BODY
+
+    /**
+     * The main execution.
+     * 
+     * @throws BuildException
+     *             on error
+     */
+    public void execute()
+    {
+        if (filename == null)
+        {
+            throw new BuildException("No filename specified");
+        }
+        
+        //Backup the old log file        
+        if (backup)
+        {            
+            long timestamp = System.currentTimeMillis();                         
+            File oldFile = new File(filename); 
+            if (oldFile.exists()) {
+                oldFile.renameTo(new File(filename + "." + timestamp));
+                getProject().setProperty("backup.file.name", filename + "." + timestamp);
+            }    
+            
+        }
+        
+        
+        getProject().log("setting a recorder for name " + filename, Project.MSG_DEBUG);
+
+        // get the recorder entry
+        LogRecorderEntry recorder = getRecorder(filename, getProject());
+        recorder.setMessageOutputLevel(loglevel);
+        recorder.setEmacsMode(emacsMode);
+        if (regexp != null && regexp.trim().length() > 0)
+        {
+            recorder.setRegexp(regexp);
+        }
+        // if (filterset != null)
+        // {
+        // Object o = getProject().getReference(filterset);
+        // if (o != null && o instanceof LogFilterSet)
+        // {
+        // recorder.setFilterSet((LogFilterSet) o);
+        // }
+        // }
+
+        // set the values on the recorder
+        if (start)
+        {
+            recorder.reopenFile();
+            recorder.setRecordState(true);
+        }
+        else
+        {
+            recorder.setRecordState(false);
+            recorder.closeFile();
+        }
+    }
+
+    /**
+    * INNER CLASSES
+    */
+    public static class VerbosityLevelChoices extends LogLevel {
+    }
+
+    /**
+     * A list of possible values for the <code>setAction()</code> method.
+     * Possible values include: start and stop.
+     */
+    public static class ActionChoices extends EnumeratedAttribute
+    {
+        private static final String[] VALUES =
+        { "start", "stop" };
+
+        /**
+         * @see EnumeratedAttribute#getValues()
+         */
+        public String[] getValues()
+        {
+            return VALUES;
+        }
+    }
+
+    /**
+     * Gets the recorder that's associated with the passed in name. If the
+     * recorder doesn't exist, then a new one is created.
+     * 
+     * @param name
+     *            the name of the recoder
+     * @param proj
+     *            the current project
+     * @return a recorder
+     * @throws BuildException
+     *             on error
+     */
+    protected LogRecorderEntry getRecorder(String name, Project proj)
+    {
+        Object o = recorderEntries.get(name);
+        LogRecorderEntry entry;
+
+        if (o == null)
+        {
+            try
+            {
+                Class[] parameters = new Class[1];
+                parameters[0] = String.class;
+                Class centry = Class.forName(loggerclass);
+                Constructor c = centry.getConstructor(parameters);
+                Object[] params = new Object[1];
+                params[0] = filename;
+                entry = (LogRecorderEntry) c.newInstance(params);
+            }
+            catch (Exception e)
+            {
+                entry = new TextLogRecorderEntry(name);
+            }
+
+            entry.openFile(append);
+            entry.setProject(proj);
+            recorderEntries.put(name, entry);
+        }
+        else
+        {
+            entry = (LogRecorderEntry) o;
+        }
+        return entry;
+    }
+
+    /**
+     * Empty implementation required by SubBuildListener interface.
+     * 
+     * @since Ant 1.7
+     */
+    public void buildStarted(BuildEvent event)
+    {
+    }
+
+    /**
+     * Empty implementation required by SubBuildListener interface.
+     * 
+     * @since Ant 1.7
+     */
+    public void subBuildStarted(BuildEvent event)
+    {
+    }
+
+    /**
+     * Empty implementation required by SubBuildListener interface.
+     * 
+     * @since Ant 1.7
+     */
+    public void targetStarted(BuildEvent event)
+    {
+    }
+
+    /**
+     * Empty implementation required by SubBuildListener interface.
+     * 
+     * @since Ant 1.7
+     */
+    public void targetFinished(BuildEvent event)
+    {
+    }
+
+    /**
+     * Empty implementation required by SubBuildListener interface.
+     * 
+     * @since Ant 1.7
+     */
+    public void taskStarted(BuildEvent event)
+    {
+    }
+
+    /**
+     * Empty implementation required by SubBuildListener interface.
+     * 
+     * @since Ant 1.7
+     */
+    public void taskFinished(BuildEvent event)
+    {
+    }
+
+    /**
+     * Empty implementation required by SubBuildListener interface.
+     * 
+     * @since Ant 1.7
+     */
+    public void messageLogged(BuildEvent event)
+    {
+    }
+
+    /**
+     * Cleans recorder registry.
+     * 
+     * @since Ant 1.7
+     */
+    public void buildFinished(BuildEvent event)
+    {
+        cleanup();
+    }
+
+    /**
+     * Cleans recorder registry, if this is the subbuild the task has been
+     * created in.
+     * 
+     * @since Ant 1.7
+     */
+    public void subBuildFinished(BuildEvent event)
+    {
+        if (event.getProject() == getProject())
+        {
+            cleanup();
+        }
+    }
+
+    /**
+     * cleans recorder registry and removes itself from BuildListener list.
+     * 
+     * @since Ant 1.7
+     */
+    private void cleanup()
+    {
+        recorderEntries.clear();
+        getProject().removeBuildListener(this);
+    }
+}