Added support for batching.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / ExpressionCollection.cs
1 //
2 // ExpressionCollection.cs
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.Text;
34 using Microsoft.Build.Framework;
35 using Microsoft.Build.Utilities;
36
37 namespace Microsoft.Build.BuildEngine {
38
39         internal class ExpressionCollection {
40         
41                 IList objects;
42         
43                 public ExpressionCollection ()
44                 {
45                         objects = new ArrayList ();
46                 }
47
48                 public int Count {
49                         get { return objects.Count; }
50                 }
51                 
52                 public void Add (ItemReference itemReference)
53                 {
54                         objects.Add (itemReference);
55                 }
56                 
57                 public void Add (MetadataReference metadataReference)
58                 {
59                         objects.Add (metadataReference);
60                 }
61                 
62                 public void Add (PropertyReference propertyReference)
63                 {
64                         objects.Add (propertyReference);
65                 }
66                 
67                 public void Add (string s)
68                 {
69                         objects.Add (s);
70                 }
71                 
72                 public object ConvertTo (Project project, Type type)
73                 {
74                         if (type.IsArray) {
75                                 if (type == typeof (ITaskItem[]))
76                                         return ConvertToITaskItemArray (project);
77                                 else
78                                         return ConvertToArray (project, type);
79                         } else {
80                                 if (type == typeof (ITaskItem))
81                                         return ConvertToITaskItem (project);
82                                 else
83                                         return ConvertToNonArray (project, type);
84                         }
85                 }
86                 
87                 public IEnumerator GetEnumerator ()
88                 {
89                         foreach (object o in objects)
90                                 yield return o;
91                 }
92                 
93                 object ConvertToNonArray (Project project, Type type)
94                 {
95                         return ConvertToObject (ConvertToString (project), type);
96                 }
97
98                 object ConvertToArray (Project project, Type type)
99                 {
100                         string [] rawTable = ConvertToString (project).Split (';');
101
102                         Array arr = Array.CreateInstance (type.GetElementType (), rawTable.Length);
103                         for (int i = 0; i < arr.Length; i++)
104                                 arr.SetValue (ConvertToObject (rawTable [i], type.GetElementType ()), i);
105                         return arr;
106                 }
107                 
108                 object ConvertToObject (string raw, Type type)
109                 {
110                         if (type == typeof (bool))
111                                 return Boolean.Parse (raw);
112                         else if (type == typeof (string))
113                                 return raw;
114                         else if (type == typeof (int))
115                                 return Int32.Parse (raw);
116                         else if (type == typeof (uint))
117                                 return UInt32.Parse (raw);
118                         else if (type == typeof (DateTime))
119                                 return DateTime.Parse (raw);
120                         else
121                                 throw new Exception (String.Format ("Unknown type: {0}", type.ToString ()));
122                 }
123                 string ConvertToString (Project project)
124                 {
125                         StringBuilder sb = new StringBuilder ();
126                         
127                         foreach (object o in objects) {
128                                 if (o is string) {
129                                         sb.Append ((string) o);
130                                 } else if (o is ItemReference) {
131                                         ItemReference ir = (ItemReference) o;
132                                         sb.Append (ir.ConvertToString (project));
133                                 } else if (o is PropertyReference) {
134                                         PropertyReference pr = (PropertyReference) o;
135                                         sb.Append (pr.ConvertToString (project));
136                                 } else if (o is MetadataReference) {
137                                         MetadataReference mr = (MetadataReference) o;
138                                         sb.Append (mr.ConvertToString (project));
139                                 } else {
140                                         throw new Exception ("Invalid type in objects collection.");
141                                 }
142                         }
143                         return sb.ToString ();
144                 }
145
146                 ITaskItem ConvertToITaskItem (Project project)
147                 {
148                         ITaskItem item;
149                         
150                         if (objects == null)
151                                 throw new Exception ("Cannot cast empty expression to ITaskItem.");
152                         
153                         if (objects [0] is ItemReference) {
154                                 ItemReference ir = (ItemReference) objects [0];
155                                 ITaskItem[] array = ir.ConvertToITaskItemArray (project);
156                                 if (array.Length == 1) {
157                                         return array [0];
158                                 } else {
159                                         throw new Exception ("TaskItem array too long");
160                                 }
161                         } else {
162                                 item = new TaskItem (ConvertToString (project));
163                                 return item;
164                         }
165                 }
166                 
167                 ITaskItem[] ConvertToITaskItemArray (Project project)
168                 {
169                         List <ITaskItem> finalItems = new List <ITaskItem> ();
170                         ArrayList tempItems = new ArrayList ();
171                         ITaskItem[] array;
172                         
173                         foreach (object o in objects) {
174                                 if (o is ItemReference) {
175                                         tempItems.Add (o);
176                                 } else if (o is PropertyReference) {
177                                         PropertyReference pr = (PropertyReference) o;
178                                         tempItems.Add (pr.ConvertToString (project));
179                                 } else if (o is MetadataReference) {
180                                         // FIXME: not handled yet
181                                 } else if (o is string) {
182                                         tempItems.Add (o);
183                                 } else {
184                                         throw new Exception ("Invalid type in objects collection.");
185                                 }
186                         }
187                         foreach (object o in tempItems) {
188                                 if (o is ItemReference) {
189                                         ItemReference ir = (ItemReference) o;
190                                         array = ir.ConvertToITaskItemArray (project);
191                                         if (array != null)
192                                                 finalItems.AddRange (array);
193                                 } else if (o is string) {
194                                         string s = (string) o;
195                                         array = ConvertToITaskItemArrayFromString (project, s);
196                                         finalItems.AddRange (array);
197                                 } else {
198                                         throw new Exception ("Invalid type in tempItems collection.");
199                                 }
200                         }
201                         
202                         return finalItems.ToArray ();
203                 }
204                 
205                 ITaskItem [] ConvertToITaskItemArrayFromString (Project project, string source)
206                 {
207                         List <ITaskItem> items = new List <ITaskItem> ();
208                         string [] splitSource = source.Split (';');
209                         foreach (string s in splitSource) {
210                                 if (s != String.Empty) {
211                                         items.Add (new TaskItem (s));
212                                 }
213                         }
214                         return items.ToArray ();
215                 }
216         }
217 }
218
219 #endif