PageRenderTime 159ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildPropertyGroup.cs

https://bitbucket.org/luobailiang/mono
C# | 302 lines | 232 code | 44 blank | 26 comment | 40 complexity | f77f7e3841ab3899512a004396a1919f MD5 | raw file
  1. //
  2. // BuildPropertyGroup.cs: Represents a group of properties
  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. #if NET_2_0
  28. using System;
  29. using System.Collections;
  30. using System.Collections.Generic;
  31. using System.Reflection;
  32. using System.Text;
  33. using System.Xml;
  34. namespace Microsoft.Build.BuildEngine {
  35. public class BuildPropertyGroup : IEnumerable {
  36. bool read_only;
  37. ImportedProject importedProject;
  38. XmlElement propertyGroup;
  39. GroupingCollection parentCollection;
  40. Project parentProject;
  41. List <BuildProperty> properties;
  42. Dictionary <string, BuildProperty> propertiesByName;
  43. bool evaluated;
  44. public BuildPropertyGroup ()
  45. : this (null, null, null, false)
  46. {
  47. }
  48. internal BuildPropertyGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
  49. {
  50. this.importedProject = importedProject;
  51. this.parentCollection = null;
  52. this.parentProject = project;
  53. this.propertyGroup = xmlElement;
  54. this.read_only = readOnly;
  55. if (FromXml) {
  56. this.properties = new List <BuildProperty> ();
  57. foreach (XmlNode xn in propertyGroup.ChildNodes) {
  58. if (!(xn is XmlElement))
  59. continue;
  60. XmlElement xe = (XmlElement) xn;
  61. BuildProperty bp = new BuildProperty (parentProject, xe);
  62. AddProperty (bp);
  63. }
  64. } else
  65. this.propertiesByName = new Dictionary <string, BuildProperty> (StringComparer.InvariantCultureIgnoreCase);
  66. }
  67. public BuildProperty AddNewProperty (string propertyName,
  68. string propertyValue)
  69. {
  70. return AddNewProperty (propertyName, propertyValue, false);
  71. }
  72. public BuildProperty AddNewProperty (string propertyName,
  73. string propertyValue,
  74. bool treatPropertyValueAsLiteral)
  75. {
  76. if (!FromXml)
  77. throw new InvalidOperationException ("This method is only valid for persisted property groups.");
  78. if (treatPropertyValueAsLiteral)
  79. propertyValue = Utilities.Escape (propertyValue);
  80. XmlElement element = propertyGroup.OwnerDocument.CreateElement (propertyName, Project.XmlNamespace);
  81. propertyGroup.AppendChild (element);
  82. BuildProperty property = new BuildProperty (parentProject, element);
  83. property.Value = propertyValue;
  84. AddProperty (property);
  85. parentProject.MarkProjectAsDirty ();
  86. parentProject.NeedToReevaluate ();
  87. return property;
  88. }
  89. internal void AddProperty (BuildProperty property)
  90. {
  91. if (FromXml)
  92. properties.Add (property);
  93. else {
  94. if (propertiesByName.ContainsKey (property.Name)) {
  95. BuildProperty existing = propertiesByName [property.Name];
  96. if (property.PropertyType <= existing.PropertyType) {
  97. propertiesByName.Remove (property.Name);
  98. propertiesByName.Add (property.Name, property);
  99. }
  100. } else
  101. propertiesByName.Add (property.Name, property);
  102. }
  103. }
  104. public void Clear ()
  105. {
  106. if (FromXml) {
  107. propertyGroup.RemoveAll ();
  108. properties = new List <BuildProperty> ();
  109. } else
  110. propertiesByName = new Dictionary <string, BuildProperty> ();
  111. }
  112. [MonoTODO]
  113. public BuildPropertyGroup Clone (bool deepClone)
  114. {
  115. BuildPropertyGroup bpg = new BuildPropertyGroup (propertyGroup, parentProject, importedProject, read_only);
  116. if (FromXml) {
  117. foreach (BuildProperty bp in properties) {
  118. if (deepClone)
  119. bpg.AddProperty (bp.Clone (true));
  120. else
  121. bpg.AddNewProperty (bp.Name, bp.FinalValue);
  122. }
  123. } else {
  124. foreach (BuildProperty bp in propertiesByName.Values) {
  125. if (deepClone)
  126. bpg.AddProperty (bp.Clone (true));
  127. else
  128. bpg.AddNewProperty (bp.Name, bp.FinalValue);
  129. }
  130. }
  131. return bpg;
  132. }
  133. public IEnumerator GetEnumerator ()
  134. {
  135. if (FromXml)
  136. foreach (BuildProperty bp in properties)
  137. yield return bp;
  138. else
  139. foreach (KeyValuePair <string, BuildProperty> kvp in propertiesByName)
  140. yield return kvp.Value;
  141. }
  142. public void RemoveProperty (BuildProperty propertyToRemove)
  143. {
  144. if (propertyToRemove == null)
  145. throw new ArgumentNullException ("propertyToRemove");
  146. if (FromXml) {
  147. if (!propertyToRemove.FromXml)
  148. throw new InvalidOperationException ("The specified property does not belong to the current property group.");
  149. propertyToRemove.XmlElement.ParentNode.RemoveChild (propertyToRemove.XmlElement);
  150. properties.Remove (propertyToRemove);
  151. } else
  152. propertiesByName.Remove (propertyToRemove.Name);
  153. }
  154. public void RemoveProperty (string propertyName)
  155. {
  156. if (FromXml) {
  157. foreach (BuildProperty bp in properties)
  158. if (bp.Name == propertyName) {
  159. RemoveProperty (bp);
  160. break;
  161. }
  162. } else
  163. propertiesByName.Remove (propertyName);
  164. }
  165. public void SetProperty (string propertyName,
  166. string propertyValue)
  167. {
  168. SetProperty (propertyName, propertyValue, false);
  169. }
  170. public void SetProperty (string propertyName,
  171. string propertyValue,
  172. bool treatPropertyValueAsLiteral)
  173. {
  174. if (read_only)
  175. return;
  176. if (FromXml)
  177. throw new InvalidOperationException (
  178. "This method is only valid for virtual property groups, not <PropertyGroup> elements.");
  179. if (treatPropertyValueAsLiteral)
  180. propertyValue = Utilities.Escape (propertyValue);
  181. if (propertiesByName.ContainsKey (propertyName))
  182. propertiesByName.Remove (propertyName);
  183. BuildProperty bp = new BuildProperty (propertyName, propertyValue);
  184. if (Char.IsDigit (propertyName [0]))
  185. throw new ArgumentException (String.Format (
  186. "The name \"{0}\" contains an invalid character \"{1}\".", propertyName, propertyName [0]));
  187. AddProperty (bp);
  188. if (IsGlobal)
  189. parentProject.NeedToReevaluate ();
  190. }
  191. internal void Evaluate ()
  192. {
  193. if (evaluated)
  194. return;
  195. foreach (BuildProperty bp in properties)
  196. if (ConditionParser.ParseAndEvaluate (bp.Condition, parentProject))
  197. bp.Evaluate ();
  198. evaluated = true;
  199. }
  200. public string Condition {
  201. get {
  202. if (!FromXml)
  203. return String.Empty;
  204. return propertyGroup.GetAttribute ("Condition");
  205. }
  206. set {
  207. if (!FromXml)
  208. throw new InvalidOperationException (
  209. "Cannot set a condition on an object not represented by an XML element in the project file.");
  210. propertyGroup.SetAttribute ("Condition", value);
  211. }
  212. }
  213. public int Count {
  214. get {
  215. if (FromXml)
  216. return properties.Count;
  217. else
  218. return propertiesByName.Count;
  219. }
  220. }
  221. public bool IsImported {
  222. get {
  223. return importedProject != null;
  224. }
  225. }
  226. internal bool FromXml {
  227. get {
  228. return propertyGroup != null;
  229. }
  230. }
  231. bool IsGlobal {
  232. get {
  233. return parentProject != null && propertyGroup == null;
  234. }
  235. }
  236. public BuildProperty this [string propertyName] {
  237. get {
  238. if (FromXml)
  239. throw new InvalidOperationException ("Properties in persisted property groups cannot be accessed by name.");
  240. if (propertiesByName.ContainsKey (propertyName))
  241. return propertiesByName [propertyName];
  242. else
  243. return null;
  244. }
  245. set {
  246. propertiesByName [propertyName] = value;
  247. }
  248. }
  249. internal GroupingCollection GroupingCollection {
  250. get { return parentCollection; }
  251. set { parentCollection = value; }
  252. }
  253. internal XmlElement XmlElement {
  254. get { return propertyGroup; }
  255. }
  256. }
  257. }
  258. #endif