Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[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                 TaskLoggingHelper       task_logger;
46         
47                 internal BuildTask (XmlElement taskElement, Target parentTarget)
48                 {
49                         if (taskElement == null)
50                                 throw new ArgumentNullException ("taskElement");
51                         if (parentTarget == null)
52                                 throw new ArgumentNullException ("parentTarget");
53
54                         this.taskElement =  taskElement;
55                         this.parentTarget = parentTarget;
56                 }
57                 
58                 [MonoTODO]
59                 public void AddOutputItem (string taskParameter,
60                                            string itemName)
61                 {
62                         XmlElement element = parentTarget.Project.XmlDocument.CreateElement ("Output", Project.XmlNamespace);
63                         taskElement.AppendChild (element);
64                         
65                         if (taskParameter != null)
66                                 element.SetAttribute ("TaskParameter", taskParameter);
67                         if (itemName != null)
68                                 element.SetAttribute ("ItemName", itemName);
69                 }
70                 
71                 [MonoTODO]
72                 public void AddOutputProperty (string taskParameter,
73                                                string propertyName)
74                 {
75                         XmlElement element = parentTarget.Project.XmlDocument.CreateElement ("Output", Project.XmlNamespace);
76                         taskElement.AppendChild (element);
77                         
78                         if (taskParameter != null)
79                                 element.SetAttribute ("TaskParameter", taskParameter);
80                         if (propertyName != null)
81                                 element.SetAttribute ("PropertyName", propertyName);
82                 }
83                 
84                 [MonoTODO]
85                 public bool Execute ()
86                 {
87                         bool            result = false;
88                         TaskEngine      taskEngine;
89
90                         LogTaskStarted ();
91                         ITask task = null;
92
93                         try {
94                                 try {
95                                         task = InitializeTask ();
96                                 } catch (Exception e) {
97                                         LogError ("Error initializing task {0}: {1}", taskElement.LocalName, e.Message);
98                                         LogMessage (MessageImportance.Low, "Error initializing task {0}: {1}",
99                                                         taskElement.LocalName, e.ToString ());
100                                         return false;
101                                 }
102
103                                 try {
104                                         taskEngine = new TaskEngine (parentTarget.Project);
105                                         taskEngine.Prepare (task, this.taskElement, GetParameters (), this.Type);
106                                         result = taskEngine.Execute ();
107                                         if (result)
108                                                 taskEngine.PublishOutput ();
109                                 } catch (Exception e) {
110                                         task_logger.LogError ("Error executing task {0}: {1}", taskElement.LocalName, e.Message);
111                                         task_logger.LogMessage (MessageImportance.Low,
112                                                         "Error executing task {0}: {1}", taskElement.LocalName, e.ToString ());
113                                         result = false;
114                                 }
115                         } finally {
116                                 LogTaskFinished (result);
117                         }
118
119                         return result;
120                 }
121
122
123                 public string[] GetParameterNames ()
124                 {
125                         List <string> tempNames = new List <string> ();
126                         
127                         foreach (XmlAttribute xmlAttribute in taskElement.Attributes) {
128                                 if (xmlAttribute.Name == "Condition" || xmlAttribute.Name == "ContinueOnError")
129                                         continue;
130                                 tempNames.Add (xmlAttribute.Name);
131                         }
132                         
133                         return tempNames.ToArray ();
134                 }
135                 
136                 public string GetParameterValue (string attributeName)
137                 {
138                         if (attributeName == "Condition")
139                                 throw new ArgumentException ("Condition attribute cannot be accessed using this method.");
140                         if (attributeName == "ContinueOnError")
141                                 throw new ArgumentException ("ContinueOnError attribute cannot be accessed using this method.");
142
143                         return taskElement.GetAttribute (attributeName);
144                 }
145                 
146                 public void SetParameterValue (string parameterName,
147                                                string parameterValue)
148                 {
149                         SetParameterValue (parameterName, parameterValue, false);
150                 }
151                 
152                 public void SetParameterValue (string parameterName,
153                                                string parameterValue,
154                                                bool treatParameterValueAsLiteral)
155                 {
156                         if (treatParameterValueAsLiteral)
157                                 taskElement.SetAttribute (parameterName, Utilities.Escape (parameterValue));
158                         else
159                                 taskElement.SetAttribute (parameterName, parameterValue);
160                 }
161                 
162                 void LogTaskStarted ()
163                 {
164                         TaskStartedEventArgs tsea = new TaskStartedEventArgs ("Task started.", null,
165                                         parentTarget.Project.FullFileName,
166                                         parentTarget.TargetFile, taskElement.Name);
167                         parentTarget.Project.ParentEngine.EventSource.FireTaskStarted (this, tsea);
168                 }
169                 
170                 void LogTaskFinished (bool succeeded)
171                 {
172                         TaskFinishedEventArgs tfea = new TaskFinishedEventArgs ("Task finished.", null,
173                                         parentTarget.Project.FullFileName,
174                                         parentTarget.TargetFile, taskElement.Name, succeeded);
175                         parentTarget.Project.ParentEngine.EventSource.FireTaskFinished (this, tfea);
176                 }
177
178                 void LogError (string message,
179                                      params object[] messageArgs)
180                 {
181                         parentTarget.Project.ParentEngine.LogError (message, messageArgs);
182                 }
183                 
184                 void LogMessage (MessageImportance importance,
185                                         string message,
186                                         params object[] messageArgs)
187                 {
188                         parentTarget.Project.ParentEngine.LogMessage (importance, message, messageArgs);
189                 }
190
191                 ITask InitializeTask ()
192                 {
193                         ITask task;
194                         
195                         try {
196                                 task = (ITask)Activator.CreateInstance (this.Type);
197                         } catch (InvalidCastException) {
198                                 LogMessage (MessageImportance.Low, "InvalidCastException, ITask: {0} Task type: {1}",
199                                                 typeof (ITask).AssemblyQualifiedName, this.Type.AssemblyQualifiedName);
200                                 throw;
201                         }
202                         parentTarget.Project.ParentEngine.LogMessage (
203                                         MessageImportance.Low,
204                                         "Using task {0} from {1}", Name, this.Type.AssemblyQualifiedName);
205
206                         task.BuildEngine = new BuildEngine (parentTarget.Project.ParentEngine, parentTarget.Project,
207                                                 parentTarget.TargetFile, 0, 0, ContinueOnError);
208                         task_logger = new TaskLoggingHelper (task);
209                         
210                         return task;
211                 }
212                 
213                 IDictionary <string, string> GetParameters ()
214                 {
215                         Dictionary <string, string> parameters = new Dictionary <string, string> ();
216                         
217                         string[] parameterNames = GetParameterNames ();
218                         
219                         foreach (string s in parameterNames)
220                                 parameters.Add (s, GetParameterValue (s));
221                         
222                         return parameters;
223                 }
224                 
225                 public string Condition {
226                         get {
227                                 return taskElement.GetAttribute ("Condition");
228                         }
229                         set {
230                                 taskElement.SetAttribute ("Condition", value);
231                         }
232                 }
233
234                 [MonoTODO]
235                 public bool ContinueOnError {
236                         get {
237                                 string str = taskElement.GetAttribute ("ContinueOnError");
238                                 if (str == String.Empty)
239                                         return false;
240                                 else {
241                                         Expression exp = new Expression ();
242                                         exp.Parse (str, ParseOptions.AllowItemsNoMetadataAndSplit);
243                                         return (bool) exp.ConvertTo (parentTarget.Project, typeof (bool),
244                                                         ExpressionOptions.ExpandItemRefs);
245                                 }
246                         }
247                         set {
248                                 taskElement.SetAttribute ("ContinueOnError", value.ToString ());
249                         }
250                 }
251                 
252                 [MonoTODO]
253                 public ITaskHost HostObject {
254                         get { return hostObject; }
255                         set { hostObject = value; }
256                 }
257                 
258                 public string Name {
259                         get { return taskElement.Name; }
260                 }
261                 
262                 internal Target ParentTarget {
263                         get { return parentTarget; }
264                         set { parentTarget = value; }
265                 }
266                 
267                 internal XmlElement TaskElement {
268                         get { return taskElement; }
269                         set { taskElement = value; }
270                 }
271                 
272                 [MonoTODO]
273                 public Type Type {
274                         get { return parentTarget.Project.TaskDatabase.GetTypeFromClassName (Name); }
275                 }
276                 
277         }
278 }
279
280 #endif