using System;
using System.Collections;
-using System.Collections.Specialized;
+using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Xml;
namespace Microsoft.Build.BuildEngine {
public class BuildPropertyGroup : IEnumerable {
+ bool read_only;
+ ImportedProject importedProject;
XmlElement propertyGroup;
- XmlAttribute condition;
- string importedFromFilename;
- bool isImported;
GroupingCollection parentCollection;
Project parentProject;
- IList properties;
- IDictionary propertiesByName;
-
+ List <BuildProperty> properties;
+ Dictionary <string, BuildProperty> propertiesByName;
+
public BuildPropertyGroup ()
- : this (true, null)
+ : this (null, null, null, false)
{
}
-
- internal BuildPropertyGroup (bool forXml, Project project)
+
+ internal BuildPropertyGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
{
- this.propertyGroup = null;
- this.condition = null;
- this.importedFromFilename = null;
- this.isImported = false;
+ this.importedProject = importedProject;
this.parentCollection = null;
this.parentProject = project;
- if (forXml == true)
- this.properties = new ArrayList ();
- else
- this.propertiesByName = CollectionsUtil.CreateCaseInsensitiveHashtable ();
+ this.propertyGroup = xmlElement;
+ this.read_only = readOnly;
+
+ if (FromXml) {
+ this.properties = new List <BuildProperty> ();
+ foreach (XmlNode xn in propertyGroup.ChildNodes) {
+ if (!(xn is XmlElement))
+ continue;
+
+ XmlElement xe = (XmlElement) xn;
+ BuildProperty bp = new BuildProperty (parentProject, xe);
+ AddProperty (bp);
+ }
+ } else
+ this.propertiesByName = new Dictionary <string, BuildProperty> (StringComparer.InvariantCultureIgnoreCase);
}
public BuildProperty AddNewProperty (string propertyName,
string propertyValue)
{
- return AddNewProperty (propertyName, propertyValue,
- PropertyType.Normal);
+ return AddNewProperty (propertyName, propertyValue, false);
}
- internal BuildProperty AddNewProperty (string propertyName,
- string propertyValue,
- PropertyType propertyType)
+ public BuildProperty AddNewProperty (string propertyName,
+ string propertyValue,
+ bool treatPropertyValueAsLiteral)
{
- BuildProperty added, existing;
-
- added = new BuildProperty (propertyName, propertyValue);
- added.PropertyType = propertyType;
- if (properties != null) {
- properties.Add (added);
- } else if (propertiesByName != null) {
- if (propertiesByName.Contains (propertyName) == true) {
- existing = (BuildProperty) propertiesByName [added.Name];
- if (added.PropertyType <= existing.PropertyType) {
- propertiesByName.Remove (added.Name);
- propertiesByName.Add (added.Name, added);
- }
- } else {
- propertiesByName.Add (added.Name, added);
- }
+ BuildProperty prop;
+
+ if (FromXml) {
+ XmlElement xe;
+
+ xe = propertyGroup.OwnerDocument.CreateElement (propertyName, Project.XmlNamespace);
+ propertyGroup.AppendChild (xe);
+
+ if (treatPropertyValueAsLiteral)
+ xe.InnerText = Utilities.Escape (propertyValue);
+ else
+ xe.InnerText = propertyValue;
+
+ prop = new BuildProperty (parentProject, xe);
+ AddProperty (prop);
+ parentProject.EvaluatedProperties.AddProperty (prop);
+ return prop;
} else
- throw new Exception ("PropertyGroup is not initialized.");
- return added;
+ throw new InvalidOperationException ("This method is only valid for persisted <System.Object[]> elements.");
}
-
- internal void AddFromExistingProperty (BuildProperty buildProperty)
+
+ internal void AddProperty (BuildProperty property)
{
- BuildProperty added, existing;
-
- added = buildProperty.Clone (false);
- if (propertiesByName.Contains (added.Name) == true) {
- existing = (BuildProperty) propertiesByName [added.Name];
- if (added.PropertyType <= existing.PropertyType) {
- propertiesByName.Remove (added.Name);
- propertiesByName.Add (added.Name, added);
+ if (FromXml) {
+ properties.Add (property);
+ } else {
+ if (propertiesByName.ContainsKey (property.Name)) {
+ BuildProperty existing = propertiesByName [property.Name];
+ if (property.PropertyType <= existing.PropertyType) {
+ propertiesByName.Remove (property.Name);
+ propertiesByName.Add (property.Name, property);
+ }
+ } else {
+ propertiesByName.Add (property.Name, property);
}
- } else
- propertiesByName.Add (added.Name, added);
+ }
}
public void Clear ()
{
+ if (FromXml) {
+ propertyGroup.RemoveAll ();
+ properties = new List <BuildProperty> ();
+ } else
+ propertiesByName = new Dictionary <string, BuildProperty> ();
}
+ [MonoTODO]
public BuildPropertyGroup Clone (bool deepClone)
{
- return null;
+ throw new NotImplementedException ();
}
- // FIXME: what it is doing?
- internal void Evaluate (BuildPropertyGroup evaluatedPropertyBag,
- bool ignoreCondition,
- bool honorCondition,
- Hashtable conditionedPropertiesTable,
- ProcessingPass pass)
- {
- }
-
public IEnumerator GetEnumerator ()
{
- if (properties != null)
+ if (FromXml)
foreach (BuildProperty bp in properties)
yield return bp;
- else if (propertiesByName != null)
- foreach (DictionaryEntry de in propertiesByName)
- yield return (BuildProperty) de.Value;
- else
- throw new Exception ("PropertyGroup is not initialized.");
+ else
+ foreach (KeyValuePair <string, BuildProperty> kvp in propertiesByName)
+ yield return kvp.Value;
}
- public void GetStringArraysForAllProperties (out string[] propertyNames,
- out string[] propertyValues,
- out string[] propertyFinalValues)
+ public void RemoveProperty (BuildProperty propertyToRemove)
{
- propertyNames = null;
- propertyValues = null;
- propertyFinalValues = null;
- int i = 0;
- if (properties != null) {
- foreach (BuildProperty bp in properties) {
- propertyNames [i] = bp.Name;
- propertyValues [i] = bp.Value;
- propertyFinalValues [i] = bp.FinalValue;
- i++;
- }
- } else if (propertiesByName != null) {
- foreach (DictionaryEntry de in propertiesByName) {
- propertyNames [i] = ((BuildProperty) de.Value).Name;
- propertyValues [i] = ((BuildProperty) de.Value).Value;
- propertyFinalValues [i] = ((BuildProperty) de.Value).FinalValue;
- i++;
- }
+ if (FromXml)
+ properties.Remove (propertyToRemove);
+ else {
+ foreach (KeyValuePair <string, BuildProperty> kvp in propertiesByName)
+ if (kvp.Value == propertyToRemove) {
+ propertiesByName.Remove (kvp.Key);
+ break;
+ }
}
}
- public void RemoveProperty (BuildProperty propertyToRemove)
+ public void RemoveProperty (string propertyName)
{
- if (properties == null)
- throw new Exception ("PropertyGroup is not initialized.");
- properties.Remove (propertyToRemove);
+ if (FromXml) {
+ foreach (BuildProperty bp in properties)
+ if (bp.Name == propertyName) {
+ properties.Remove (bp);
+ break;
+ }
+ } else
+ propertiesByName.Remove (propertyName);
}
- public void RemovePropertyByName (string propertyNameToRemove)
+ public void SetProperty (string propertyName,
+ string propertyValue)
{
- if (propertiesByName == null)
- throw new Exception ("PropertyGroup is not initialized.");
- propertiesByName.Remove (propertyNameToRemove);
+ SetProperty (propertyName, propertyValue, false);
}
-
+
+ // FIXME: add a test for SetProperty on property from xml
public void SetProperty (string propertyName,
- string propertyValue)
+ string propertyValue,
+ bool treatPropertyValueAsLiteral)
{
- if (propertiesByName.Contains (propertyName) == false) {
- AddNewProperty (propertyName, propertyValue);
- }
- ((BuildProperty) propertiesByName [propertyName]).Value = propertyValue;
+ if (read_only)
+ return;
+
+ if (propertiesByName.ContainsKey (propertyName))
+ propertiesByName.Remove (propertyName);
+
+ BuildProperty bp;
+ if (treatPropertyValueAsLiteral)
+ bp = new BuildProperty (propertyName, Utilities.Escape (propertyValue));
+ else
+ bp = new BuildProperty (propertyName, propertyValue);
+
+ AddProperty (bp);
+
+ if (IsGlobal)
+ parentProject.ProcessXml ();
}
- internal void BindToXml (XmlElement propertyGroupElement)
+ internal void Evaluate ()
{
- if (propertyGroupElement == null)
- throw new ArgumentNullException ();
- this.properties = new ArrayList ();
- this.propertyGroup = propertyGroupElement;
- this.condition = propertyGroupElement.GetAttributeNode ("Condition");
- this.importedFromFilename = null;
- this.isImported = false;
- foreach (XmlElement xe in propertyGroupElement.ChildNodes) {
- BuildProperty bp = AddNewProperty(xe.Name, xe.InnerText);
- bp.PropertyType = PropertyType.Normal;
- bp.BindToXml (xe);
- Expression finalValue = new Expression (parentProject, bp.Value);
- bp.FinalValue = (string) finalValue.ToNonArray (typeof (string));
- parentProject.EvaluatedProperties.AddFromExistingProperty (bp);
- }
+ if (!FromXml) {
+ throw new InvalidOperationException ();
+ }
+ foreach (BuildProperty bp in properties) {
+ if (bp.Condition == String.Empty)
+ bp.Evaluate ();
+ else {
+ ConditionExpression ce = ConditionParser.ParseCondition (bp.Condition);
+ if (ce.BoolEvaluate (parentProject))
+ bp.Evaluate ();
+ }
+ }
}
public string Condition {
get {
- if (condition == null)
- return null;
- else
- return condition.Value;
+ if (!FromXml)
+ return String.Empty;
+ return propertyGroup.GetAttribute ("Condition");
}
set {
- if (condition != null)
- condition.Value = value;
+ if (!FromXml)
+ throw new InvalidOperationException (
+ "Cannot set a condition on an object not represented by an XML element in the project file.");
+ propertyGroup.SetAttribute ("Condition", value);
}
}
public int Count {
get {
- if (properties != null)
+ if (FromXml)
return properties.Count;
- else if (propertiesByName != null)
- return propertiesByName.Count;
else
- throw new Exception ("PropertyGroup is not initialized.");
+ return propertiesByName.Count;
}
}
- public string ImportedFromFilename {
+ public bool IsImported {
get {
- return importedFromFilename;
+ return importedProject != null;
}
}
- public bool IsImported {
+ internal bool FromXml {
get {
- return isImported;
+ return propertyGroup != null;
}
}
- public BuildProperty this[string propertyName] {
+ bool IsGlobal {
get {
- if (propertiesByName.Contains (propertyName)) {
- return (BuildProperty) propertiesByName [propertyName];
- } else {
+ return parentProject != null && propertyGroup == null;
+ }
+ }
+
+ public BuildProperty this [string propertyName] {
+ get {
+ if (FromXml)
+ throw new InvalidOperationException ("Properties in persisted property groups cannot be accessed by name.");
+
+ if (propertiesByName.ContainsKey (propertyName))
+ return propertiesByName [propertyName];
+ else
return null;
- }
}
set {
propertiesByName [propertyName] = value;
get { return parentCollection; }
set { parentCollection = value; }
}
+
+ internal XmlElement XmlElement {
+ get { return propertyGroup; }
+ }
}
}
-#endif
\ No newline at end of file
+#endif