* Makefile ($(build_lib)): Make CYCLIC_DEP_FILES depend on this.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / BuildTask.cs
1 //
2 // BuildTask.cs: Represents a Task element in a project.
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 // 
7 // (C) 2006 Marek Sieradzki
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 #if NET_2_0
29
30 using System;
31 using System.Collections;
32 using System.Collections.Generic;
33 using System.Collections.Specialized;
34 using System.Reflection;
35 using System.Xml;
36 using Microsoft.Build.Framework;
37 using Microsoft.Build.Utilities;
38
39 namespace Microsoft.Build.BuildEngine {
40         public class BuildTask {
41         
42                 ITaskHost               hostObject;
43                 Target                  parentTarget;
44                 XmlElement              taskElement;
45         
46                 internal BuildTask (XmlElement taskElement, Target parentTarget)
47                 {
48                         if (taskElement == null)
49                                 throw new ArgumentNullException ("taskElement");
50                         if (parentTarget == null)
51                                 throw new ArgumentNullException ("parentTarget");
52
53                         this.taskElement =  taskElement;
54                         this.parentTarget = parentTarget;
55                 }
56                 
57                 [MonoTODO]
58                 public void AddOutputItem (string taskParameter,
59                                            string itemName)
60                 {
61                         XmlElement element = parentTarget.Project.XmlDocument.CreateElement ("Output", Project.XmlNamespace);
62                         taskElement.AppendChild (element);
63                         
64                         if (taskParameter != null)
65                                 element.SetAttribute ("TaskParameter", taskParameter);
66                         if (itemName != null)
67                                 element.SetAttribute ("ItemName", itemName);
68                 }
69                 
70                 [MonoTODO]
71                 public void AddOutputProperty (string taskParameter,
72                                                string propertyName)
73                 {
74                         XmlElement element = parentTarget.Project.XmlDocument.CreateElement ("Output", Project.XmlNamespace);
75                         taskElement.AppendChild (element);
76                         
77                         if (taskParameter != null)
78                                 element.SetAttribute ("TaskParameter", taskParameter);
79                         if (propertyName != null)
80                                 element.SetAttribute ("PropertyName", propertyName);
81                 }
82                 
83                 [MonoTODO]
84                 public bool Execute ()
85                 {
86                         bool            result;
87                         TaskEngine      taskEngine;
88
89                         LogTaskStarted ();
90
91                         try {
92                                 taskEngine = new TaskEngine (parentTarget.Project);             
93                                 taskEngine.Prepare (InitializeTask (), this.taskElement, GetParameters (), this.Type);
94                                 result = taskEngine.Execute ();
95                                 if (result)
96                                         taskEngine.PublishOutput ();
97                         // FIXME: it should be logged (exception)
98                         } catch (Exception e) {
99                                 Console.Error.WriteLine (e);
100                                 result = false;
101                         }
102
103                         LogTaskFinished (result);
104                 
105                         return result;
106                 }
107
108
109                 public string[] GetParameterNames ()
110                 {
111                         List <string> tempNames = new List <string> ();
112                         
113                         foreach (XmlAttribute xmlAttribute in taskElement.Attributes) {
114                                 if (xmlAttribute.Name == "Condition" || xmlAttribute.Name == "ContinueOnError")
115                                         continue;
116                                 tempNames.Add (xmlAttribute.Name);
117                         }
118                         
119                         return tempNames.ToArray ();
120                 }
121                 
122                 public string GetParameterValue (string attributeName)
123                 {
124                         if (attributeName == "Condition")
125                                 throw new ArgumentException ("Condition attribute cannot be accessed using this method.");
126                         if (attributeName == "ContinueOnError")
127                                 throw new ArgumentException ("ContinueOnError attribute cannot be accessed using this method.");
128
129                         return taskElement.GetAttribute (attributeName);
130                 }
131                 
132                 public void SetParameterValue (string parameterName,
133                                                string parameterValue)
134                 {
135                         SetParameterValue (parameterName, parameterValue, false);
136                 }
137                 
138                 public void SetParameterValue (string parameterName,
139                                                string parameterValue,
140                                                bool treatParameterValueAsLiteral)
141                 {
142                         if (treatParameterValueAsLiteral)
143                                 taskElement.SetAttribute (parameterName, Utilities.Escape (parameterValue));
144                         else
145                                 taskElement.SetAttribute (parameterName, parameterValue);
146                 }
147                 
148                 void LogTaskStarted ()
149                 {
150                         TaskStartedEventArgs tsea = new TaskStartedEventArgs ("Task started.", null, parentTarget.Project.FullFileName,
151                                 parentTarget.Project.FullFileName, taskElement.Name);
152                         parentTarget.Project.ParentEngine.EventSource.FireTaskStarted (this, tsea);
153                 }
154                 
155                 void LogTaskFinished (bool succeeded)
156                 {
157                         TaskFinishedEventArgs tfea = new TaskFinishedEventArgs ("Task finished.", null, parentTarget.Project.FullFileName,
158                                 parentTarget.Project.FullFileName, taskElement.Name, succeeded);
159                         parentTarget.Project.ParentEngine.EventSource.FireTaskFinished (this, tfea);
160                 }
161                 
162                 ITask InitializeTask ()
163                 {
164                         ITask task;
165                         
166                         task = (ITask)Activator.CreateInstance (this.Type);
167                         task.BuildEngine = new BuildEngine (parentTarget.Project.ParentEngine, parentTarget.Project, 0, 0, ContinueOnError);
168                         
169                         return task;
170                 }
171                 
172                 IDictionary <string, string> GetParameters ()
173                 {
174                         Dictionary <string, string> parameters = new Dictionary <string, string> ();
175                         
176                         string[] parameterNames = GetParameterNames ();
177                         
178                         foreach (string s in parameterNames)
179                                 parameters.Add (s, GetParameterValue (s));
180                         
181                         return parameters;
182                 }
183                 
184                 public string Condition {
185                         get {
186                                 return taskElement.GetAttribute ("Condition");
187                         }
188                         set {
189                                 taskElement.SetAttribute ("Condition", value);
190                         }
191                 }
192
193                 [MonoTODO]
194                 public bool ContinueOnError {
195                         get {
196                                 string str = taskElement.GetAttribute ("ContinueOnError");
197                                 if (str == String.Empty)
198                                         return false;
199                                 else {
200                                         Expression exp = new Expression ();
201                                         exp.Parse (str, true);
202                                         return (bool) exp.ConvertTo (parentTarget.Project, typeof (bool));
203                                 }
204                         }
205                         set {
206                                 taskElement.SetAttribute ("ContinueOnError", value.ToString ());
207                         }
208                 }
209                 
210                 [MonoTODO]
211                 public ITaskHost HostObject {
212                         get { return hostObject; }
213                         set { hostObject = value; }
214                 }
215                 
216                 public string Name {
217                         get { return taskElement.Name; }
218                 }
219                 
220                 internal Target ParentTarget {
221                         get { return parentTarget; }
222                         set { parentTarget = value; }
223                 }
224                 
225                 internal XmlElement TaskElement {
226                         get { return taskElement; }
227                         set { taskElement = value; }
228                 }
229                 
230                 [MonoTODO]
231                 public Type Type {
232                         get { return parentTarget.Project.TaskDatabase.GetTypeFromClassName (Name); }
233                 }
234                 
235         }
236 }
237
238 #endif