[xbuild] Fix #40094, part 2/2: AssignProjectConfiguration - Fallback to
[mono.git] / mcs / class / Microsoft.Build.Tasks / Microsoft.Build.Tasks / AssignProjectConfiguration.cs
index 5f762c6e538ad201985e3dcab90f7cfb4787a0bf..bb85df584df4eb0e8f41e58f61c9a855bacec375 100644 (file)
@@ -3,8 +3,10 @@
 //
 // Author:
 //   Marek Sieradzki (marek.sieradzki@gmail.com)
+//   Ankit Jain (jankit@novell.com)
 //
 // (C) 2006 Marek Sieradzki
+// Copyright 2009 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-#if NET_2_0
 
 using System;
 using System.IO;
+using System.Collections.Generic;
+using System.Xml;
 using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
 
 namespace Microsoft.Build.Tasks {
        public class AssignProjectConfiguration : ResolveProjectBase {
@@ -37,6 +41,8 @@ namespace Microsoft.Build.Tasks {
                ITaskItem[]     assignedProjects;
                string          solutionConfigurationContents;
                ITaskItem[]     unassignedProjects;
+               Dictionary<Guid, string> guidToConfigPlatform;
+               Dictionary<string, string> absolutePathToConfigPlatform;
        
                public AssignProjectConfiguration ()
                {
@@ -45,9 +51,110 @@ namespace Microsoft.Build.Tasks {
                [MonoTODO]
                public override bool Execute ()
                {
-                       return false;
+                       if (String.IsNullOrEmpty (solutionConfigurationContents))
+                               return true;
+
+                       XmlReader xr = null;
+                       guidToConfigPlatform = new Dictionary<Guid, string> ();
+                       absolutePathToConfigPlatform = new Dictionary<string, string> ();
+                       try {
+                               xr = XmlReader.Create (new StringReader (solutionConfigurationContents));
+
+                               xr.Read ();
+                               while (!xr.EOF) {
+                                       xr.Read ();
+                                       if (xr.NodeType != XmlNodeType.Element)
+                                               continue;
+
+                                       string guid_str = xr.GetAttribute ("Project");
+                                       string abs_path = xr.GetAttribute ("AbsolutePath");
+                                       string config_str = xr.ReadString ();
+
+                                       if (String.IsNullOrEmpty (config_str))
+                                               continue;
+
+                                       Guid guid;
+                                       if (TryParseGuid (guid_str, out guid))
+                                               guidToConfigPlatform [guid] = config_str;
+
+                                       if (!String.IsNullOrEmpty (abs_path)) {
+                                               abs_path = Path.GetFullPath (abs_path);
+                                               absolutePathToConfigPlatform [abs_path] = config_str;
+                                       }
+                               }
+                       } catch (XmlException xe) {
+                               Log.LogError ("XmlException while parsing SolutionConfigurationContents: {0}",
+                                               xe.ToString ());
+
+                               return false;
+                       } finally {
+                               ((IDisposable)xr).Dispose ();
+                       }
+
+                       List<ITaskItem> tempAssignedProjects = new List<ITaskItem> ();
+                       List<ITaskItem> tempUnassignedProjects = new List<ITaskItem> ();
+                       foreach (ITaskItem item in ProjectReferences) {
+                               string config = GetConfigPlatformFromProjectReference (item);
+
+                               if (String.IsNullOrEmpty (config)) {
+                                       tempUnassignedProjects.Add (item);
+                                       continue;
+                               }
+
+                               string [] parts = config.Split (new char [] {'|'}, 2);
+
+                               ITaskItem new_item = new TaskItem (item);
+
+                               new_item.SetMetadata ("SetConfiguration", "Configuration=" + parts [0]);
+                               new_item.SetMetadata ("SetPlatform", "Platform=" +
+                                               ((parts.Length > 1) ? parts [1] : String.Empty));
+
+                               tempAssignedProjects.Add (new_item);
+                       }
+
+                       assignedProjects = tempAssignedProjects.ToArray ();
+                       unassignedProjects = tempUnassignedProjects.ToArray ();
+
+                       return true;
                }
-               
+
+               string GetConfigPlatformFromProjectReference (ITaskItem item)
+               {
+                       string guid_str = item.GetMetadata ("Project");
+                       string proj_full_path = item.GetMetadata ("FullPath");
+
+                       string config;
+                       Guid guid = Guid.Empty;
+                       if (TryParseGuid (guid_str, out guid) && guidToConfigPlatform.TryGetValue (guid, out config))
+                               return config;
+
+                       string abs_path = item.GetMetadata ("FullPath");
+                       if (absolutePathToConfigPlatform.TryGetValue (abs_path, out config))
+                               return config;
+
+                       return null;
+               }
+
+               bool TryParseGuid (string guid_str, out Guid guid)
+               {
+                       guid = Guid.Empty;
+                       if (String.IsNullOrEmpty (guid_str))
+                               return false;
+
+                       try {
+                               guid = new Guid (guid_str);
+                       } catch (ArgumentNullException) {
+                               return false;
+                       } catch (FormatException) {
+                               return false;
+                       } catch (OverflowException) {
+                               return false;
+                       }
+
+                       return true;
+               }
+
+
                [Output]
                public ITaskItem[] AssignedProjects {
                        get { return assignedProjects; }
@@ -67,4 +174,3 @@ namespace Microsoft.Build.Tasks {
        }
 }
 
-#endif
\ No newline at end of file