* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / TaskElement.cs
1 //
2 // TaskElement.cs: Represents XML element that is a task.
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //
7 // (C) 2005 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.Specialized;
33 using System.Reflection;
34 using System.Xml;
35 using Microsoft.Build.Framework;
36 using Microsoft.Build.Utilities;
37
38 namespace Microsoft.Build.BuildEngine {
39         // FIXME: remove this class
40         /*public class TaskElement {
41         
42                 XmlAttribute    condition;
43                 XmlAttribute    continueOnError;
44                 XmlElement      taskElement;
45                 Target          parentTarget;
46                 object          hostObject;
47                 string          name;
48                 bool            isImported;
49                 
50                 static Type     requiredAttribute;
51                 static Type     outputAttribute;
52                 
53                 public TaskElement ()
54                 {
55                         this.isImported = false;
56                 }
57                 
58                 static TaskElement ()
59                 {
60                         requiredAttribute = typeof (Microsoft.Build.Framework.RequiredAttribute);
61                         outputAttribute = typeof (Microsoft.Build.Framework.OutputAttribute);
62                 }
63
64                 public bool Execute ()
65                 {
66                         bool result;
67                         string rawParameter;
68                         string[] parameterNames;
69                         PropertyInfo[] properties;
70                         PropertyInfo currentProperty;
71                         Hashtable values = new Hashtable ();
72                         Task task;
73                         object value;
74                 
75                         LogTaskStarted ();
76                         
77                         task = (Task)Activator.CreateInstance (Type);
78                         task.BuildEngine = new BuildEngine (parentTarget.Project.ParentEngine, 0, 0,
79                                 ContinueOnError, parentTarget.Project.FullFileName);
80                         parameterNames = GetParameterNames ();
81                         foreach (string parameter in parameterNames) {
82                                 currentProperty = GetType ().GetProperty (parameter);
83                                 if (currentProperty == null)
84                                         throw new InvalidProjectFileException (String.Format ("Task does not have property \"{0}\" defined",
85                                                 parameter));
86                                 rawParameter = GetParameterValue (parameter);
87                                 value = GetObjectFromString (rawParameter, currentProperty.PropertyType);
88                                 values.Add (parameter, value);
89                         }
90                         
91                         properties = GetType().GetProperties ();
92                         foreach (PropertyInfo pi in properties) {
93                                 if (pi.IsDefined (requiredAttribute, false) && values.ContainsKey (pi.Name) == false) {
94                                         throw new InvalidProjectFileException ("Required property not set.");
95                                 }
96                                 if (values.ContainsKey (pi.Name)) {
97                                         pi.SetValue (task, values [pi.Name], null);
98                                 }
99                         }
100                         
101                         result = task.Execute ();
102                         
103                         // output
104                         
105                         foreach (XmlNode xn in taskElement.ChildNodes) {
106                                 if (xn is XmlElement) {
107                                         XmlElement xe = (XmlElement) xn;
108                                         PropertyInfo pi;
109                                         string property, parameter, item;
110                                         object o;
111                                         Project p;
112                                         
113                                         if (xe.Name != "Output")
114                                                 throw new InvalidProjectFileException ("Only Output elements can be Task's child nodes.");
115                                         if (xe.GetAttribute ("ItemName") != "" && xe.GetAttribute ("PropertyName") != "")
116                                                 throw new InvalidProjectFileException ("Only one of ItemName and ProperytyName attributes can be specified.");
117                                         if (xe.GetAttribute ("TaskParameter") == "")
118                                                 throw new InvalidProjectFileException ("TaskParameter attribute must be specified.");
119                                                 
120                                         property = xe.GetAttribute ("PropertyName");
121                                         parameter = xe.GetAttribute ("TaskParameter");
122                                         item = xe.GetAttribute ("ItemName");
123                                         p = parentTarget.Project;
124                                         
125                                         pi = GetType ().GetProperty (parameter);
126                                         if (pi == null)
127                                                 throw new Exception ("Could not get property info.");
128                                         if (pi.IsDefined (outputAttribute, false) == false)
129                                                 throw new Exception ("This is not output property.");
130                                         
131                                         o = pi.GetValue (task, null);
132                                         if (o == null)
133                                                 continue;
134                                         if (xe.GetAttribute ("ItemName") != "") {
135                                                 BuildItemGroup newItems = HandleItemGroup (pi, o, item);
136                                                 if (p.EvaluatedItemsByName.Contains (item)) {
137                                                         BuildItemGroup big = (BuildItemGroup) p.EvaluatedItemsByName [item];
138                                                         big.Clear ();
139                                                         p.EvaluatedItemsByName.Remove (item);
140                                                         p.EvaluatedItemsByName.Add (item, newItems);
141                                                 } else {
142                                                         p.EvaluatedItemsByName.Add (item, newItems);
143                                                 }
144                                         } else {
145                                                 BuildProperty bp = HandleProperty (pi, o, property);
146                                                 p.EvaluatedProperties.AddFromExistingProperty (bp);
147                                         }
148                                 }
149                         }
150                         
151                         // end of output
152                         
153                         LogTaskFinished (result);
154                         
155                         return result;
156                 }
157                 
158                 private BuildProperty HandleProperty (PropertyInfo propertyInfo, object o, string name)
159                 {
160                         string output = null;
161                         BuildProperty bp;
162                         
163                         if (propertyInfo == null)
164                                 throw new ArgumentNullException ("propertyInfo");
165                         if (o == null)
166                                 throw new ArgumentNullException ("o");
167                         if (name == null)
168                                 throw new ArgumentNullException ("name");
169                         
170                         if (propertyInfo.PropertyType == typeof (ITaskItem)) {
171                                 ITaskItem item = (ITaskItem) o;
172                                 bp = ChangeType.TransformToBuildProperty (name, item);
173                         } else if (propertyInfo.PropertyType == typeof (ITaskItem[])) {
174                                 ITaskItem[] items = (ITaskItem[]) o;
175                                 bp = ChangeType.TransformToBuildProperty (name, items);
176                         } else {
177                                 if (propertyInfo.PropertyType.IsArray == true) {
178                                         output = ChangeType.TransformToString ((object[])o, propertyInfo.PropertyType);
179                         } else {
180                                         output = ChangeType.TransformToString (o, propertyInfo.PropertyType);
181                                 }
182                                 bp = ChangeType.TransformToBuildProperty (name, output);
183                         }
184                         return bp;
185                 }
186                 
187                 private BuildItemGroup HandleItemGroup (PropertyInfo propertyInfo, object o, string name)
188                 {
189                         BuildItemGroup big;
190                         string temp;
191                         
192                         if (propertyInfo == null)
193                                 throw new ArgumentNullException ("propertyInfo");
194                         if (o == null)
195                                 throw new ArgumentNullException ("o");
196                         if (name == null)
197                                 throw new ArgumentNullException ("name");
198                                 
199                         if (propertyInfo.PropertyType == typeof (ITaskItem)) {
200                                 ITaskItem item = (ITaskItem) o;
201                                 big = ChangeType.TransformToBuildItemGroup (name, item);
202                         } else if (propertyInfo.PropertyType == typeof (ITaskItem[])) {
203                                 ITaskItem[] items = (ITaskItem[]) o;
204                                 big = ChangeType.TransformToBuildItemGroup (name, items);
205                         } else {
206                                 if (propertyInfo.PropertyType.IsArray == true) {
207                                         temp = ChangeType.TransformToString ((object[]) o, propertyInfo.PropertyType);
208                                 } else {
209                                         temp = ChangeType.TransformToString (o, propertyInfo.PropertyType);
210                                 }
211                                 big = ChangeType.TransformToBuildItemGroup (name, temp);
212                         }
213                         return big;     
214                 }
215
216                 public string[] GetParameterNames ()
217                 {
218                         int attributesCount = 0;
219                         ArrayList tempNames = new ArrayList ();
220                         string[] names;
221                         
222                         foreach (XmlAttribute xmlAttribute in taskElement.Attributes) {
223                                 if (xmlAttribute.Name == "Condition")
224                                         continue;
225                                 if (xmlAttribute.Name == "ContinueOnError")
226                                         continue;
227                                 tempNames.Add (xmlAttribute.Name);
228                         }
229                         names = new string [tempNames.Count];
230                         foreach (string name in tempNames)
231                                 names [attributesCount++] = name;
232                         return names;
233                 }
234
235                 public string GetParameterValue (string attributeName)
236                 {
237                         return taskElement.GetAttribute (attributeName);
238                 }
239                 
240                 private object GetObjectFromString (string raw, Type type)
241                 {
242                         Expression e;
243                         object result;
244                         
245                         e = new Expression (parentTarget.Project, raw);
246                         
247                         if (type == typeof (ITaskItem)) {
248                                 result = (object) e.ToITaskItem ();
249                         } else if (type == typeof (ITaskItem[])) {
250                                 result = (object) e.ToITaskItemArray ();
251                         } else {
252                                 if (type.IsArray) {
253                                         result = e.ToArray (type);
254                                 } else {
255                                         result = e.ToNonArray (type);
256                                 }
257                         }
258                         
259                         return result;
260                 }
261
262                 public void SetParameterValue (string parameterName,
263                                                string parameterValue)
264                 {
265                         taskElement.SetAttribute (parameterName, parameterValue);
266                 }
267                 
268                 internal void BindToXml (XmlElement taskElement,
269                                          Target parentTarget)
270                 {
271                         if (taskElement == null)
272                                 throw new ArgumentNullException ("taskElement");
273                         if (parentTarget == null)
274                                 throw new ArgumentNullException ("parentTarget");
275                         this.taskElement =  taskElement;
276                         this.parentTarget = parentTarget;
277                         this.condition = taskElement.GetAttributeNode ("Condition");
278                         this.continueOnError = taskElement.GetAttributeNode ("ContinueOnError");
279                         this.name  = taskElement.Name;
280                 }
281                 
282                 private void LogTaskStarted ()
283                 {
284                         TaskStartedEventArgs tsea = new TaskStartedEventArgs ("Task started.", null, parentTarget.Project.FullFileName,
285                                 parentTarget.Project.FullFileName, taskElement.Name);
286                         parentTarget.Project.ParentEngine.EventSource.FireTaskStarted (this, tsea);
287                 }
288                 
289                 private void LogTaskFinished (bool succeeded)
290                 {
291                         TaskFinishedEventArgs tfea = new TaskFinishedEventArgs ("Task finished.", null, parentTarget.Project.FullFileName,
292                                 parentTarget.Project.FullFileName, taskElement.Name, succeeded);
293                         parentTarget.Project.ParentEngine.EventSource.FireTaskFinished (this, tfea);
294                 }
295                 
296                 public string Condition {
297                         get { return condition.Value; }
298                         set { condition.Value = value; }
299                 }
300
301                 public bool ContinueOnError {
302                         get {
303                                 // FIXME: insert here text parsing
304                                 if (continueOnError == null)
305                                         return false;
306                                 else
307                                         return Boolean.Parse (continueOnError.Value);
308                         }
309                         set {
310                                 continueOnError.Value = value.ToString ();
311                         }
312                 }
313
314                 public object HostObject {
315                         get {
316                                 return hostObject;
317                         }
318                         set {
319                                 hostObject = value;
320                         }
321                 }
322
323                 public string Name {
324                         get {
325                                 return name;
326                         }
327                 }
328
329                 public Type Type {
330                         get {
331                                 return parentTarget.Project.TaskDatabase.GetTypeFromClassName (name);
332                         }
333                 }
334         }*/
335 }
336
337 #endif