[xbuild] Fix #40094, part 2/2: AssignProjectConfiguration - Fallback to
[mono.git] / mcs / class / Microsoft.Build.Tasks / Microsoft.Build.Tasks / AssignProjectConfiguration.cs
1 //
2 // AssignProjectConfiguration.cs
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //   Ankit Jain (jankit@novell.com)
7 //
8 // (C) 2006 Marek Sieradzki
9 // Copyright 2009 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30
31 using System;
32 using System.IO;
33 using System.Collections.Generic;
34 using System.Xml;
35 using Microsoft.Build.Framework;
36 using Microsoft.Build.Utilities;
37
38 namespace Microsoft.Build.Tasks {
39         public class AssignProjectConfiguration : ResolveProjectBase {
40         
41                 ITaskItem[]     assignedProjects;
42                 string          solutionConfigurationContents;
43                 ITaskItem[]     unassignedProjects;
44                 Dictionary<Guid, string> guidToConfigPlatform;
45                 Dictionary<string, string> absolutePathToConfigPlatform;
46         
47                 public AssignProjectConfiguration ()
48                 {
49                 }
50                 
51                 [MonoTODO]
52                 public override bool Execute ()
53                 {
54                         if (String.IsNullOrEmpty (solutionConfigurationContents))
55                                 return true;
56
57                         XmlReader xr = null;
58                         guidToConfigPlatform = new Dictionary<Guid, string> ();
59                         absolutePathToConfigPlatform = new Dictionary<string, string> ();
60                         try {
61                                 xr = XmlReader.Create (new StringReader (solutionConfigurationContents));
62
63                                 xr.Read ();
64                                 while (!xr.EOF) {
65                                         xr.Read ();
66                                         if (xr.NodeType != XmlNodeType.Element)
67                                                 continue;
68
69                                         string guid_str = xr.GetAttribute ("Project");
70                                         string abs_path = xr.GetAttribute ("AbsolutePath");
71                                         string config_str = xr.ReadString ();
72
73                                         if (String.IsNullOrEmpty (config_str))
74                                                 continue;
75
76                                         Guid guid;
77                                         if (TryParseGuid (guid_str, out guid))
78                                                 guidToConfigPlatform [guid] = config_str;
79
80                                         if (!String.IsNullOrEmpty (abs_path)) {
81                                                 abs_path = Path.GetFullPath (abs_path);
82                                                 absolutePathToConfigPlatform [abs_path] = config_str;
83                                         }
84                                 }
85                         } catch (XmlException xe) {
86                                 Log.LogError ("XmlException while parsing SolutionConfigurationContents: {0}",
87                                                 xe.ToString ());
88
89                                 return false;
90                         } finally {
91                                 ((IDisposable)xr).Dispose ();
92                         }
93
94                         List<ITaskItem> tempAssignedProjects = new List<ITaskItem> ();
95                         List<ITaskItem> tempUnassignedProjects = new List<ITaskItem> ();
96                         foreach (ITaskItem item in ProjectReferences) {
97                                 string config = GetConfigPlatformFromProjectReference (item);
98
99                                 if (String.IsNullOrEmpty (config)) {
100                                         tempUnassignedProjects.Add (item);
101                                         continue;
102                                 }
103
104                                 string [] parts = config.Split (new char [] {'|'}, 2);
105
106                                 ITaskItem new_item = new TaskItem (item);
107
108                                 new_item.SetMetadata ("SetConfiguration", "Configuration=" + parts [0]);
109                                 new_item.SetMetadata ("SetPlatform", "Platform=" +
110                                                 ((parts.Length > 1) ? parts [1] : String.Empty));
111
112                                 tempAssignedProjects.Add (new_item);
113                         }
114
115                         assignedProjects = tempAssignedProjects.ToArray ();
116                         unassignedProjects = tempUnassignedProjects.ToArray ();
117
118                         return true;
119                 }
120
121                 string GetConfigPlatformFromProjectReference (ITaskItem item)
122                 {
123                         string guid_str = item.GetMetadata ("Project");
124                         string proj_full_path = item.GetMetadata ("FullPath");
125
126                         string config;
127                         Guid guid = Guid.Empty;
128                         if (TryParseGuid (guid_str, out guid) && guidToConfigPlatform.TryGetValue (guid, out config))
129                                 return config;
130
131                         string abs_path = item.GetMetadata ("FullPath");
132                         if (absolutePathToConfigPlatform.TryGetValue (abs_path, out config))
133                                 return config;
134
135                         return null;
136                 }
137
138                 bool TryParseGuid (string guid_str, out Guid guid)
139                 {
140                         guid = Guid.Empty;
141                         if (String.IsNullOrEmpty (guid_str))
142                                 return false;
143
144                         try {
145                                 guid = new Guid (guid_str);
146                         } catch (ArgumentNullException) {
147                                 return false;
148                         } catch (FormatException) {
149                                 return false;
150                         } catch (OverflowException) {
151                                 return false;
152                         }
153
154                         return true;
155                 }
156
157
158                 [Output]
159                 public ITaskItem[] AssignedProjects {
160                         get { return assignedProjects; }
161                         set { assignedProjects = value; }
162                 }
163                 
164                 public string SolutionConfigurationContents {
165                         get { return solutionConfigurationContents; }
166                         set { solutionConfigurationContents = value; }
167                 }
168                 
169                 [Output]
170                 public ITaskItem[] UnassignedProjects {
171                         get { return unassignedProjects; }
172                         set { unassignedProjects = value; }
173                 }
174         }
175 }
176