2007-01-16 Marek Sieradzki <marek.sieradzki@gmail.com>
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / BuildItemGroup.cs
1 //
2 // BuildItemGroup.cs: Represents a group of build items.
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.Reflection;
32 using System.Collections;
33 using System.Collections.Generic;
34 using System.Xml;
35 using Microsoft.Build.Framework;
36 using Microsoft.Build.Utilities;
37
38 namespace Microsoft.Build.BuildEngine {
39         public class BuildItemGroup : IEnumerable {
40         
41                 List <BuildItem>        buildItems;
42                 ImportedProject         importedProject;
43                 XmlElement              itemGroupElement;
44                 GroupingCollection      parentCollection;
45                 Project                 parentProject;
46                 bool                    read_only;
47
48                 public BuildItemGroup ()
49                         : this (null, null, null, false)
50                 {
51                 }
52                 
53                 internal BuildItemGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
54                 {
55                         this.buildItems = new List <BuildItem> ();
56                         this.importedProject = importedProject;
57                         this.itemGroupElement = xmlElement;
58                         this.parentProject = project;
59                         this.read_only = readOnly;
60                         
61                         if (!FromXml)
62                                 return;
63
64                         foreach (XmlNode xn in xmlElement.ChildNodes) {
65                                 if (!(xn is XmlElement))
66                                         continue;
67                                         
68                                 XmlElement xe = (XmlElement) xn;
69                                 BuildItem bi = new BuildItem (xe, this);
70                                 buildItems.Add (bi);
71                         }
72                 }
73
74                 public BuildItem AddNewItem (string itemName,
75                                              string itemInclude)
76                 {
77                         return AddNewItem (itemName, itemInclude, false);
78                 }
79                 
80                 [MonoTODO]
81                 public BuildItem AddNewItem (string itemName,
82                                              string itemInclude,
83                                              bool treatItemIncludeAsLiteral)
84                 {
85                         BuildItem item;
86
87                         if (treatItemIncludeAsLiteral)
88                                 itemInclude = Utilities.Escape (itemInclude);
89
90                         if (FromXml) {
91                                 XmlElement element = itemGroupElement.OwnerDocument.CreateElement (itemName, Project.XmlNamespace);
92                                 itemGroupElement.AppendChild (element);
93                                 element.SetAttribute ("Include", itemInclude);
94                                 item = new BuildItem (element, this);
95                         } else {
96                                 item = new BuildItem (itemName, itemInclude);
97                         }
98
99                         item.Evaluate (null, true);
100
101                         if (!read_only)
102                                 buildItems.Add (item);
103
104                         if (parentProject != null) {
105                                 parentProject.MarkProjectAsDirty ();
106                                 parentProject.NeedToReevaluate ();
107                         }
108
109                         return item;
110                 }
111                 
112                 public void Clear ()
113                 {
114                         if (FromXml)
115                                 itemGroupElement.RemoveAll ();
116                         
117                         buildItems = new List <BuildItem> ();
118
119                         if (parentProject != null) {
120                                 parentProject.MarkProjectAsDirty ();
121                                 parentProject.NeedToReevaluate ();
122                         }
123                 }
124
125                 [MonoTODO]
126                 public BuildItemGroup Clone (bool deepClone)
127                 {
128                         if (deepClone) {
129                                 if (FromXml)
130                                         throw new NotImplementedException ();
131                                 else
132                                         throw new NotImplementedException ();
133                         } else {
134                                 if (FromXml)
135                                         throw new InvalidOperationException ("A shallow clone of this object cannot be created.");
136                                 else
137                                         throw new NotImplementedException ();
138                         }
139                 }
140
141                 public IEnumerator GetEnumerator ()
142                 {
143                         return buildItems.GetEnumerator ();
144                 }
145
146                 public void RemoveItem (BuildItem itemToRemove)
147                 {
148                         if (itemToRemove == null)
149                                 return;
150
151                         itemToRemove.Detach ();
152
153                         buildItems.Remove (itemToRemove);
154                 }
155
156                 public void RemoveItemAt (int index)
157                 {
158                         BuildItem item = buildItems [index];
159
160                         RemoveItem (item);
161                 }
162
163                 public BuildItem[] ToArray ()
164                 {
165                         return buildItems.ToArray ();
166                 }
167
168                 internal void AddItem (BuildItem buildItem)
169                 {
170                         buildItems.Add (buildItem);
171                 }
172
173                 internal void AddItem (string name, ITaskItem taskItem)
174                 {
175                         BuildItem buildItem;
176                         buildItem = new BuildItem (name, taskItem);
177                         buildItems.Add (buildItem);
178                 }
179
180                 internal string ConvertToString (Expression transform,
181                                                  Expression separator)
182                 {
183                         string separatorString;
184                         
185                         if (separator == null)
186                                 separatorString = ";";
187                         else
188                                 separatorString = (string) separator.ConvertTo (parentProject, typeof (string));
189                 
190                         string[] items = new string [buildItems.Count];
191                         int i = 0;
192                         foreach (BuildItem bi in  buildItems)
193                                 items [i++] = bi.ConvertToString (transform);
194                         return String.Join (separatorString, items);
195                 }
196
197                 internal ITaskItem[] ConvertToITaskItemArray (Expression transform)
198                 {
199                         ITaskItem[] array = new ITaskItem [buildItems.Count];
200                         int i = 0;
201                         foreach (BuildItem item in buildItems)
202                                 array [i++] = item.ConvertToITaskItem (transform);
203                         return array;
204                 }
205
206                 internal void Detach ()
207                 {
208                         if (!FromXml)
209                                 throw new InvalidOperationException ();
210
211                         itemGroupElement.ParentNode.RemoveChild (itemGroupElement);
212                 }
213
214                 internal void Evaluate ()
215                 {
216                         foreach (BuildItem bi in buildItems) {
217                                 if (bi.Condition == String.Empty)
218                                         bi.Evaluate (parentProject, true);
219                                 else {
220                                         ConditionExpression ce = ConditionParser.ParseCondition (bi.Condition);
221                                         bi.Evaluate (parentProject, ce.BoolEvaluate (parentProject));
222                                 }
223                         }
224                 }               
225
226                 internal void ReplaceWith (BuildItem item, List <BuildItem> list)
227                 {
228                         int index = buildItems.IndexOf (item);
229                         buildItems.RemoveAt (index);
230                         buildItems.InsertRange (index, list);
231                 }
232                 
233                 public string Condition {
234                         get {
235                                 if (FromXml)
236                                         return itemGroupElement.GetAttribute ("Condition");
237                                 else
238                                         return String.Empty;
239                         }
240                         set {
241                                 if (FromXml)
242                                         itemGroupElement.SetAttribute ("Condition", value);
243                                 else
244                                         throw new InvalidOperationException ("Cannot set a condition on an object not represented by an XML element in the project file.");
245                         }
246                 }
247
248                 public int Count {
249                         get { return buildItems.Count; }
250                 }
251
252                 public bool IsImported {
253                         get { return importedProject != null; }
254                 }
255
256                 
257                 [MonoTODO]
258                 public BuildItem this [int index] {
259                         get {
260                                 return buildItems [index];
261                         }
262                 }
263                 
264                 internal GroupingCollection GroupingCollection {
265                         get { return parentCollection; }
266                         set { parentCollection = value; }
267                 }
268                 
269                 internal Project ParentProject {
270                         get { return parentProject; }
271                 }
272
273                 internal bool FromXml {
274                         get {
275                                 return itemGroupElement != null;
276                         }
277                 }
278
279                 internal XmlElement XmlElement {
280                         get {
281                                 return itemGroupElement;
282                         }       
283                 }
284         }
285 }
286
287 #endif