Merge pull request #601 from knocte/sock_improvements
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / BuildTask.cs
index c7a10113a251d1995a5b5c5cf62ff965246a2a77..d0048815a18d690db6de37c8f4c9cb578c394355 100644 (file)
@@ -25,8 +25,6 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-#if NET_2_0
-
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -37,13 +35,13 @@ using Microsoft.Build.Framework;
 using Microsoft.Build.Utilities;
 
 namespace Microsoft.Build.BuildEngine {
-       public class BuildTask {
+       public class BuildTask : IBuildTask {
        
                ITaskHost               hostObject;
                Target                  parentTarget;
                XmlElement              taskElement;
+               TaskLoggingHelper       task_logger;
        
-               // FIXME: implement
                internal BuildTask (XmlElement taskElement, Target parentTarget)
                {
                        if (taskElement == null)
@@ -59,113 +57,169 @@ namespace Microsoft.Build.BuildEngine {
                public void AddOutputItem (string taskParameter,
                                           string itemName)
                {
+                       XmlElement element = parentTarget.Project.XmlDocument.CreateElement ("Output", Project.XmlNamespace);
+                       taskElement.AppendChild (element);
+                       
+                       if (taskParameter != null)
+                               element.SetAttribute ("TaskParameter", taskParameter);
+                       if (itemName != null)
+                               element.SetAttribute ("ItemName", itemName);
                }
                
                [MonoTODO]
                public void AddOutputProperty (string taskParameter,
                                               string propertyName)
                {
+                       XmlElement element = parentTarget.Project.XmlDocument.CreateElement ("Output", Project.XmlNamespace);
+                       taskElement.AppendChild (element);
+                       
+                       if (taskParameter != null)
+                               element.SetAttribute ("TaskParameter", taskParameter);
+                       if (propertyName != null)
+                               element.SetAttribute ("PropertyName", propertyName);
                }
                
                [MonoTODO]
                public bool Execute ()
                {
-                       bool            result;
+                       bool            result = false;
                        TaskEngine      taskEngine;
 
                        LogTaskStarted ();
-                       
-                       taskEngine = new TaskEngine (parentTarget.Project);
-                       
-                       taskEngine.Prepare (InitializeTask (), this.taskElement, GetParameters (), this.Type);
-                       
-                       result = taskEngine.Execute ();
-                       
-                       taskEngine.PublishOutput ();
-                       
-                       LogTaskFinished (result);
-               
+                       ITask task = null;
+
+                       try {
+                               try {
+                                       task = InitializeTask ();
+                               } catch (Exception e) {
+                                       LogError ("Error initializing task {0}: {1}", taskElement.LocalName, e.Message);
+                                       LogMessage (MessageImportance.Low, "Error initializing task {0}: {1}",
+                                                       taskElement.LocalName, e.ToString ());
+                                       return false;
+                               }
+
+                               try {
+                                       taskEngine = new TaskEngine (parentTarget.Project);
+                                       taskEngine.Prepare (task, this.taskElement, GetParameters (), this.Type);
+                                       result = taskEngine.Execute ();
+                                       if (result)
+                                               taskEngine.PublishOutput ();
+                               } catch (Exception e) {
+                                       task_logger.LogError ("Error executing task {0}: {1}", taskElement.LocalName, e.Message);
+                                       task_logger.LogMessage (MessageImportance.Low,
+                                                       "Error executing task {0}: {1}", taskElement.LocalName, e.ToString ());
+                                       result = false;
+                               }
+                       } finally {
+                               LogTaskFinished (result);
+                       }
+
                        return result;
                }
 
 
-               [MonoTODO]
                public string[] GetParameterNames ()
                {
                        List <string> tempNames = new List <string> ();
                        
                        foreach (XmlAttribute xmlAttribute in taskElement.Attributes) {
-                               if (xmlAttribute.Name == "Condition")
-                                       continue;
-                               if (xmlAttribute.Name == "ContinueOnError")
+                               if (xmlAttribute.Name == "Condition" || xmlAttribute.Name == "ContinueOnError")
                                        continue;
                                tempNames.Add (xmlAttribute.Name);
                        }
-                       
+
                        return tempNames.ToArray ();
                }
                
-               [MonoTODO]
                public string GetParameterValue (string attributeName)
                {
+                       if (attributeName == "Condition")
+                               throw new ArgumentException ("Condition attribute cannot be accessed using this method.");
+                       if (attributeName == "ContinueOnError")
+                               throw new ArgumentException ("ContinueOnError attribute cannot be accessed using this method.");
+
                        return taskElement.GetAttribute (attributeName);
                }
                
-               [MonoTODO]
                public void SetParameterValue (string parameterName,
                                               string parameterValue)
                {
                        SetParameterValue (parameterName, parameterValue, false);
                }
                
-               [MonoTODO]
                public void SetParameterValue (string parameterName,
                                               string parameterValue,
                                               bool treatParameterValueAsLiteral)
                {
-                       // FIXME: use expression for parameterValue
-                       taskElement.SetAttribute (parameterName, parameterValue);
+                       if (treatParameterValueAsLiteral)
+                               taskElement.SetAttribute (parameterName, Utilities.Escape (parameterValue));
+                       else
+                               taskElement.SetAttribute (parameterName, parameterValue);
                }
-               
-               private void LogTaskStarted ()
+
+               void LogTaskStarted ()
                {
-                       TaskStartedEventArgs tsea = new TaskStartedEventArgs ("Task started.", null, parentTarget.Project.FullFileName,
-                               parentTarget.Project.FullFileName, taskElement.Name);
+                       TaskStartedEventArgs tsea = new TaskStartedEventArgs ("Task started.", null,
+                                       parentTarget.Project.FullFileName,
+                                       parentTarget.TargetFile, taskElement.Name);
                        parentTarget.Project.ParentEngine.EventSource.FireTaskStarted (this, tsea);
                }
                
-               private void LogTaskFinished (bool succeeded)
+               void LogTaskFinished (bool succeeded)
                {
-                       TaskFinishedEventArgs tfea = new TaskFinishedEventArgs ("Task finished.", null, parentTarget.Project.FullFileName,
-                               parentTarget.Project.FullFileName, taskElement.Name, succeeded);
+                       TaskFinishedEventArgs tfea = new TaskFinishedEventArgs ("Task finished.", null,
+                                       parentTarget.Project.FullFileName,
+                                       parentTarget.TargetFile, taskElement.Name, succeeded);
                        parentTarget.Project.ParentEngine.EventSource.FireTaskFinished (this, tfea);
                }
+
+               void LogError (string message,
+                                    params object[] messageArgs)
+               {
+                       parentTarget.Project.ParentEngine.LogError (message, messageArgs);
+               }
                
-               private ITask InitializeTask ()
+               void LogMessage (MessageImportance importance,
+                                       string message,
+                                       params object[] messageArgs)
+               {
+                       parentTarget.Project.ParentEngine.LogMessage (importance, message, messageArgs);
+               }
+
+               ITask InitializeTask ()
                {
                        ITask task;
                        
-                       task = (ITask)Activator.CreateInstance (this.Type);
-                       task.BuildEngine = new BuildEngine (parentTarget.Project.ParentEngine, 0, 0, ContinueOnError,
-                               parentTarget.Project.FullFileName);
+                       try {
+                               task = (ITask)Activator.CreateInstance (this.Type);
+                       } catch (InvalidCastException) {
+                               LogMessage (MessageImportance.Low, "InvalidCastException, ITask: {0} Task type: {1}",
+                                               typeof (ITask).AssemblyQualifiedName, this.Type.AssemblyQualifiedName);
+                               throw;
+                       }
+                       parentTarget.Project.ParentEngine.LogMessage (
+                                       MessageImportance.Low,
+                                       "Using task {0} from {1}", Name, this.Type.AssemblyQualifiedName);
+
+                       task.BuildEngine = new BuildEngine (parentTarget.Project.ParentEngine, parentTarget.Project,
+                                               parentTarget.TargetFile, 0, 0, ContinueOnError);
+                       task_logger = new TaskLoggingHelper (task);
                        
                        return task;
                }
                
-               private IDictionary <string, string> GetParameters ()
+               IDictionary <string, string> GetParameters ()
                {
                        Dictionary <string, string> parameters = new Dictionary <string, string> ();
                        
                        string[] parameterNames = GetParameterNames ();
                        
-                       foreach (string s in parameterNames) {
+                       foreach (string s in parameterNames)
                                parameters.Add (s, GetParameterValue (s));
-                       }
                        
                        return parameters;
                }
                
-               [MonoTODO]
                public string Condition {
                        get {
                                return taskElement.GetAttribute ("Condition");
@@ -179,10 +233,13 @@ namespace Microsoft.Build.BuildEngine {
                public bool ContinueOnError {
                        get {
                                string str = taskElement.GetAttribute ("ContinueOnError");
-                               if (str == String.Empty) {
+                               if (str == String.Empty)
                                        return false;
-                               } else {
-                                       return Boolean.Parse (str);
+                               else {
+                                       Expression exp = new Expression ();
+                                       exp.Parse (str, ParseOptions.AllowItemsNoMetadataAndSplit);
+                                       return (bool) exp.ConvertTo (parentTarget.Project, typeof (bool),
+                                                       ExpressionOptions.ExpandItemRefs);
                                }
                        }
                        set {
@@ -209,13 +266,29 @@ namespace Microsoft.Build.BuildEngine {
                        get { return taskElement; }
                        set { taskElement = value; }
                }
-               
+
                [MonoTODO]
                public Type Type {
                        get { return parentTarget.Project.TaskDatabase.GetTypeFromClassName (Name); }
                }
+
+               public IEnumerable<string> GetAttributes ()
+               {
+                       foreach (XmlAttribute attrib in TaskElement.Attributes)
+                               yield return attrib.Value;
                
+                       foreach (XmlNode xn in TaskElement.ChildNodes) {
+                               XmlElement xe = xn as XmlElement;
+                               if (xe == null)
+                                       continue;
+                       
+                               //FIXME: error on any other child
+                               if (String.Compare (xe.LocalName, "Output", StringComparison.Ordinal) == 0) {
+                                       foreach (XmlAttribute attrib in xe.Attributes)
+                                               yield return attrib.Value;
+                               }
+                       }
+               }
+
        }
 }
-
-#endif