**** Merged from MCS ****
[mono-project.git] / mcs / nant / src / Task.cs
blob2a4eafaebd160428d4e1715fd3a206824329af07
1 // NAnt - A .NET build tool
2 // Copyright (C) 2001 Gerry Shaw
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // Gerry Shaw (gerry_shaw@yahoo.com)
19 // Mike Krueger (mike@icsharpcode.net)
20 // Ian MacLean (ian_maclean@another.com)
22 namespace SourceForge.NAnt {
24 using System;
25 using System.Reflection;
26 using System.Xml;
28 public abstract class Task {
30 /// <summary>Gets and sets how much spacing log prefix names will be padded.</summary>
31 /// <remarks>
32 /// Includes characters for a space after the name and the [ ] brackets. Default is 12.
33 /// </remarks>
34 public static int LogPrefixPadding = Log.IndentSize;
36 Location _location = Location.UnknownLocation;
37 Target _target = null;
38 Project _project = null;
40 /// <summary>
41 /// Location in build file where task is defined.
42 /// </summary>
43 protected Location Location {
44 get { return _location; }
45 set { _location = value; }
48 public string Name {
49 get {
50 string name = null;
51 TaskNameAttribute taskName = (TaskNameAttribute) Attribute.GetCustomAttribute(GetType(), typeof(TaskNameAttribute));
52 if (taskName != null) {
53 name = taskName.Name;
55 return name;
59 public string LogPrefix {
60 get {
61 string prefix = "[" + Name + "] ";
62 return prefix.PadLeft(LogPrefixPadding);
66 public Target Target {
67 get { return _target; }
68 set { _target = value; }
71 public Project Project {
72 get { return _project; }
73 set { _project = value; }
76 protected void AutoInitializeAttributes(XmlNode taskNode) {
78 // TODO: BooleanValidatorAttribute and Int32ValidatorAttribute implementation in Task
80 // Go down the inheritance tree to find the private fields in the object.
81 // We are looking for task attributes to initialize.
82 Type currentType = GetType();
83 while (currentType != typeof(object)) {
84 FieldInfo[] fieldInfoArray = currentType.GetFields(BindingFlags.NonPublic|BindingFlags.Instance);
85 foreach (FieldInfo fieldInfo in fieldInfoArray) {
87 // process TaskAttribute attributes
88 TaskAttributeAttribute taskAttribute = (TaskAttributeAttribute) Attribute.GetCustomAttribute(fieldInfo, typeof(TaskAttributeAttribute));
89 if (taskAttribute != null) {
91 // get value from xml file
92 XmlNode node = taskNode.SelectSingleNode("@" + taskAttribute.Name);
94 // check if its required
95 if (node == null && taskAttribute.Required) {
96 // TODO: add Location to exception
97 throw new BuildException(String.Format("{0} is a required attribute.", taskAttribute.Name), Location);
100 if (node != null) {
101 fieldInfo.SetValue(this, Convert.ChangeType(node.Value, fieldInfo.FieldType));
105 // process TaskFileSet attributes
106 TaskFileSetAttribute fileSetAttribute = (TaskFileSetAttribute) Attribute.GetCustomAttribute(fieldInfo, typeof(TaskFileSetAttribute));
107 if (fileSetAttribute != null) {
108 // have file set initialize itself
109 FileSet fileSet = (FileSet) fieldInfo.GetValue(this);
111 // set task fileset belongs to
112 fileSet.Task = this;
114 // load values from build file
115 XmlNode fileSetNode = taskNode.SelectSingleNode(fileSetAttribute.Name);
116 if (fileSetNode != null) {
118 XmlNode baseDirectoryNode = fileSetNode.SelectSingleNode("@basedir");
119 if (baseDirectoryNode != null) {
120 fileSet.BaseDirectory = baseDirectoryNode.Value;
123 foreach (XmlNode node in fileSetNode.SelectNodes("includes")) {
124 string pathname = node.SelectSingleNode("@name").Value;
125 fileSet.Includes.Add(pathname);
128 foreach (XmlNode node in fileSetNode.SelectNodes("excludes")) {
129 fileSet.Excludes.Add(node.SelectSingleNode("@name").Value);
134 currentType = currentType.BaseType;
138 protected void AutoExpandAttributes() {
140 // Go down the inheritance tree to find the private fields in the object.
141 // We are looking for task attributes to initialize.
142 Type currentType = GetType();
143 while (currentType != typeof(object)) {
144 FieldInfo[] fieldInfoArray = currentType.GetFields(BindingFlags.NonPublic|BindingFlags.Instance);
145 foreach (FieldInfo fieldInfo in fieldInfoArray) {
147 // proces string parameters
148 TaskAttributeAttribute taskAttribute = (TaskAttributeAttribute) Attribute.GetCustomAttribute(fieldInfo, typeof(TaskAttributeAttribute));
149 if (taskAttribute != null) {
150 if (taskAttribute.ExpandText) {
151 string value = (string) fieldInfo.GetValue(this);
152 value = Project.ExpandText(value);
153 fieldInfo.SetValue(this, value);
156 // if a field also has a validator attribute then ensure that value is correct
157 ValidatorAttribute[] validators = (ValidatorAttribute[]) Attribute.GetCustomAttributes(fieldInfo, typeof(ValidatorAttribute));
158 foreach (ValidatorAttribute validator in validators) {
159 string errorMessage = validator.Validate(fieldInfo.GetValue(this));
160 if (errorMessage != null) {
161 throw new BuildException(String.Format("Error processing '{0}' attribute in <{1}> task: {2}", taskAttribute.Name, Name, errorMessage), Location);
166 currentType = currentType.BaseType;
170 public void Initialize(XmlNode taskNode) {
171 Initialize(taskNode, null);
174 public void Initialize(XmlNode taskNode, Location location) {
175 if (location != null) {
176 _location = location;
178 AutoInitializeAttributes(taskNode);
179 InitializeTask(taskNode);
182 public void Execute() {
183 AutoExpandAttributes();
184 ExecuteTask();
187 protected virtual void InitializeTask(XmlNode taskNode) {
190 protected abstract void ExecuteTask();