Log Message:
-----------
Started work on displaying the properties for the selected item in the configuration hierarchy.
Modified Paths:
--------------
trunk/project/Validator/ConfigurationHierarchy.cs
trunk/project/Validator/Validator.csproj
Added Paths:
-----------
trunk/project/Validator/ConfigurationTypeDescriptor.cs
Modified: trunk/project/Validator/ConfigurationHierarchy.cs
===================================================================
--- trunk/project/Validator/ConfigurationHierarchy.cs 2010-01-11 21:05:46 UTC (rev 6690)
+++ trunk/project/Validator/ConfigurationHierarchy.cs 2010-01-11 22:55:16 UTC (rev 6691)
@@ -1,18 +1,15 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using System.Drawing;
-using System.Data;
-using System.Text;
+using System.IO;
+using System.Threading;
using System.Windows.Forms;
-using System.IO;
+using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core;
-using ThoughtWorks.CruiseControl.Core.Tasks;
using ThoughtWorks.CruiseControl.Core.Config;
using ThoughtWorks.CruiseControl.Core.Security;
-using Exortech.NetReflector;
+using ThoughtWorks.CruiseControl.Core.Tasks;
using ThoughtWorks.CruiseControl.Core.Triggers;
-using System.Threading;
namespace Validator
{
@@ -409,7 +406,14 @@
/// <param name="e">The <see cref="TreeViewEventArgs"/> instance containing the event data.</param>
private void hierarchy_AfterSelect(object sender, TreeViewEventArgs e)
{
- this.itemDetails.SelectedObject = e.Node.Tag;
+ if (e.Node.Tag == null)
+ {
+ this.itemDetails.SelectedObject = null;
+ }
+ else
+ {
+ this.itemDetails.SelectedObject = new ConfigurationTypeDescriptor(e.Node.Tag);
+ }
}
#endregion
Added: trunk/project/Validator/ConfigurationTypeDescriptor.cs
===================================================================
--- trunk/project/Validator/ConfigurationTypeDescriptor.cs (rev 0)
+++ trunk/project/Validator/ConfigurationTypeDescriptor.cs 2010-01-11 22:55:16 UTC (rev 6691)
@@ -0,0 +1,563 @@
+namespace Validator
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+ using System.ComponentModel;
+ using System.Reflection;
+ using Exortech.NetReflector;
+ using ThoughtWorks.CruiseControl.Core.Util;
+
+ /// <summary>
+ /// Provides an implementation of <see cref="ICustomTypeDescriptor"/> to retrieve the configuration properties.
+ /// </summary>
+ public class ConfigurationTypeDescriptor
+ : ICustomTypeDescriptor
+ {
+ #region Private fields
+ private readonly PropertyDescriptorCollection properties;
+ private readonly object value;
+ #endregion
+
+ #region Constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ConfigurationTypeDescriptor"/> class.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ public ConfigurationTypeDescriptor(object value)
+ {
+ this.value = value;
+ var descriptors = new List<PropertyDescriptor>();
+
+ if (value != null)
+ {
+ var type = this.value.GetType();
+
+ // Get all the fields
+ var fields = type.GetFields();
+ foreach (var field in fields)
+ {
+ var name = this.GetReflectionName(field);
+ if (name != null)
+ {
+ descriptors.Add(new FieldPropertyDescriptor(name, field, this.value));
+ }
+ }
+
+ // Get all the properties
+ var properties = type.GetProperties();
+ foreach (var property in properties)
+ {
+ var name = this.GetReflectionName(property);
+ if (name != null)
+ {
+ descriptors.Add(new PropertyPropertyDescriptor(name, property, this.value));
+ }
+ }
+ }
+
+ this.properties = new PropertyDescriptorCollection(descriptors.ToArray(), true);
+ }
+ #endregion
+
+ #region Public methods
+ #region GetAttributes()
+ /// <summary>
+ /// Returns a collection of custom attributes for this instance of a component.
+ /// </summary>
+ /// <returns>
+ /// An <see cref="T:AttributeCollection"/> containing the attributes for this object.
+ /// </returns>
+ public AttributeCollection GetAttributes()
+ {
+ return TypeDescriptor.GetAttributes(this.value, true);
+ }
+ #endregion
+
+ #region GetClassName()
+ /// <summary>
+ /// Returns the class name of this instance of a component.
+ /// </summary>
+ /// <returns>
+ /// The class name of the object, or null if the class does not have a name.
+ /// </returns>
+ public string GetClassName()
+ {
+ return TypeDescriptor.GetClassName(this.value, true);
+ }
+ #endregion
+
+ #region GetComponentName()
+ /// <summary>
+ /// Returns the name of this instance of a component.
+ /// </summary>
+ /// <returns>
+ /// The name of the object, or null if the object does not have a name.
+ /// </returns>
+ public string GetComponentName()
+ {
+ return TypeDescriptor.GetComponentName(this.value, true);
+ }
+ #endregion
+
+ #region GetConverter()
+ /// <summary>
+ /// Returns a type converter for this instance of a component.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="T:TypeConverter"/> that is the converter for this object, or null if there is no <see cref="T:System.ComponentModel.TypeConverter"/> for this object.
+ /// </returns>
+ public TypeConverter GetConverter()
+ {
+ return TypeDescriptor.GetConverter(this.value, true);
+ }
+ #endregion
+
+ #region GetDefaultEvent()
+ /// <summary>
+ /// Returns the default event for this instance of a component.
+ /// </summary>
+ /// <returns>
+ /// An <see cref="T:EventDescriptor"/> that represents the default event for this object, or null if this object does not have events.
+ /// </returns>
+ public EventDescriptor GetDefaultEvent()
+ {
+ return TypeDescriptor.GetDefaultEvent(this.value, true);
+ }
+ #endregion
+
+ #region GetDefaultProperty()
+ /// <summary>
+ /// Returns the default property for this instance of a component.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="T:PropertyDescriptor"/> that represents the default property for this object, or null if this object does not have
+ /// properties.
+ /// </returns>
+ public PropertyDescriptor GetDefaultProperty()
+ {
+ return null;
+ }
+ #endregion
+
+ #region GetEditor()
+ /// <summary>
+ /// Returns an editor of the specified type for this instance of a component.
+ /// </summary>
+ /// <param name="editorBaseType">A <see cref="T:Type"/> that represents the editor for this object.</param>
+ /// <returns>
+ /// An <see cref="T:Object"/> of the specified type that is the editor for this object, or null if the editor cannot be found.
+ /// </returns>
+ public object GetEditor(Type editorBaseType)
+ {
+ return TypeDescriptor.GetEditor(this.value, editorBaseType, true);
+ }
+ #endregion
+
+ #region GetEvents()
+ /// <summary>
+ /// Returns the events for this instance of a component using the specified attribute array as a filter.
+ /// </summary>
+ /// <param name="attributes">An array of type <see cref="T:Attribute"/> that is used as a filter.</param>
+ /// <returns>
+ /// An <see cref="T:EventDescriptorCollection"/> that represents the filtered events for this component instance.
+ /// </returns>
+ public EventDescriptorCollection GetEvents(Attribute[] attributes)
+ {
+ return TypeDescriptor.GetEvents(this.value, attributes, true);
+ }
+
+ /// <summary>
+ /// Returns the events for this instance of a component.
+ /// </summary>
+ /// <returns>
+ /// An <see cref="T:EventDescriptorCollection"/> that represents the events for this component instance.
+ /// </returns>
+ public EventDescriptorCollection GetEvents()
+ {
+ return TypeDescriptor.GetEvents(this.value, true);
+ }
+ #endregion
+
+ #region GetProperties()
+ /// <summary>
+ /// Returns the properties for this instance of a component using the attribute array as a filter.
+ /// </summary>
+ /// <param name="attributes">An array of type <see cref="T:Attribute"/> that is used as a filter.</param>
+ /// <returns>
+ /// A <see cref="T:PropertyDescriptorCollection"/> that represents the filtered properties for this component instance.
+ /// </returns>
+ public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
+ {
+ return this.GetProperties();
+ }
+
+ /// <summary>
+ /// Returns the properties for this instance of a component.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="T:PropertyDescriptorCollection"/> that represents the properties for this component instance.
+ /// </returns>
+ public PropertyDescriptorCollection GetProperties()
+ {
+ return this.properties;
+ }
+ #endregion
+
+ #region GetPropertyOwner()
+ /// <summary>
+ /// Returns an object that contains the property described by the specified property descriptor.
+ /// </summary>
+ /// <param name="pd">A <see cref="T:PropertyDescriptor"/> that represents the property whose owner is to be found.</param>
+ /// <returns>
+ /// An <see cref="T:Object"/> that represents the owner of the specified property.
+ /// </returns>
+ public object GetPropertyOwner(PropertyDescriptor pd)
+ {
+ return this.value;
+ }
+ #endregion
+
+ #region ToString()
+ /// <summary>
+ /// Returns a <see cref="String"/> that represents this instance.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="String"/> that represents this instance.
+ /// </returns>
+ public override string ToString()
+ {
+ return this.GetReflectionName(this.value);
+ }
+ #endregion
+ #endregion
+
+ #region Private methods
+ #region GetReflectionName()
+ /// <summary>
+ /// Gets the name of a field or property from reflection.
+ /// </summary>
+ /// <param name="value">The field or property to get the name from.</param>
+ /// <returns>The name from reflection if found, null otherwise.</returns>
+ private string GetReflectionName(MemberInfo value)
+ {
+ string valueName = null;
+ var attributes = value.GetCustomAttributes(true);
+ foreach (var attribute in attributes)
+ {
+ var reflection = attribute as ReflectorPropertyAttribute;
+ if (reflection != null)
+ {
+ valueName = reflection.Name;
+ break;
+ }
+ }
+
+ return valueName;
+ }
+ /// <summary>
+ /// Gets the name of an item from reflection.
+ /// </summary>
+ /// <param name="value">The value to get the name from.</param>
+ /// <returns>The name from reflection if found, string.Empty otherwise.</returns>
+ private string GetReflectionName(object value)
+ {
+ string valueName = string.Empty;
+ var reflection = value.GetType().GetCustomAttributes(typeof(ReflectorTypeAttribute), true);
+ if (reflection.Length > 0)
+ {
+ valueName = (reflection[0] as ReflectorTypeAttribute).Name;
+ }
+
+ return valueName;
+ }
+ #endregion
+ #endregion
+
+ #region Public classes
+ #region PropertyDescriptorBase
+ /// <summary>
+ /// Provides a base implementation of <see cref="PropertyDescriptor"/>.
+ /// </summary>
+ public abstract class PropertyDescriptorBase
+ : PropertyDescriptor
+ {
+ #region Constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FieldPropertyDescriptor"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="attributes">The attributes.</param>
+ /// <param name="value">The object containing the values.</param>
+ public PropertyDescriptorBase(string name, Attribute[] attributes, object value)
+ : base(name, attributes)
+ {
+ this.Value = value;
+ }
+ #endregion
+
+ #region Public properties
+ #region Value
+ /// <summary>
+ /// Gets the instance containing the values.
+ /// </summary>
+ /// <value>The field information.</value>
+ public object Value { get; private set; }
+ #endregion
+
+ #region IsReadOnly
+ /// <summary>
+ /// Gets a value indicating whether this property is read-only.
+ /// </summary>
+ /// <value></value>
+ /// <returns>true if the property is read-only; otherwise, false.
+ /// </returns>
+ public override bool IsReadOnly
+ {
+ get { return true; }
+ }
+ #endregion
+ #endregion
+
+ #region Public methods
+ #region ResetValue()
+ /// <summary>
+ /// Resets the value for this property of the component to the default value.
+ /// </summary>
+ /// <param name="component">The component with the property value that is to be reset to the default value.</param>
+ public override void ResetValue(object component)
+ {
+ }
+ #endregion
+
+ #region CanResetValue()
+ /// <summary>
+ /// Returns whether resetting an object changes its value.
+ /// </summary>
+ /// <param name="component">The component to test for reset capability.</param>
+ /// <returns>
+ /// true if resetting the component changes its value; otherwise, false.
+ /// </returns>
+ public override bool CanResetValue(object component)
+ {
+ return false;
+ }
+ #endregion
+
+ #region ShouldSerializeValue()
+ /// <summary>
+ /// Determines a value indicating whether the value of this property needs to be persisted.
+ /// </summary>
+ /// <param name="component">The component with the property to be examined for persistence.</param>
+ /// <returns>
+ /// true if the property should be persisted; otherwise, false.
+ /// </returns>
+ public override bool ShouldSerializeValue(object component)
+ {
+ return false;
+ }
+ #endregion
+
+ #region SetValue()
+ /// <summary>
+ /// Sets the value of the component to a different value.
+ /// </summary>
+ /// <param name="component">The component with the property value that is to be set.</param>
+ /// <param name="value">The new value.</param>
+ public override void SetValue(object component, object value)
+ {
+ }
+ #endregion
+
+ #region WrapValue()
+ /// <summary>
+ /// Wraps the value.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns>The wrapped value if necessary, otherwise the base value.</returns>
+ public object WrapValue(object value)
+ {
+ if (value == null)
+ {
+ return value;
+ }
+ else
+ {
+ var type = value.GetType();
+ if (type.IsPrimitive || (type == typeof(string)) || (type == typeof(PrivateString)) || type.IsArray)
+ {
+ return value;
+ }
+ else
+ {
+ return new ConfigurationTypeDescriptor(value);
+ }
+ }
+ }
+ #endregion
+ #endregion
+ }
+ #endregion
+
+ #region FieldPropertyDescriptor
+ /// <summary>
+ /// Implements <see cref="PropertyDescriptor"/> for fields.
+ /// </summary>
+ public class FieldPropertyDescriptor
+ : PropertyDescriptorBase
+ {
+ #region Constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FieldPropertyDescriptor"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="field">The field.</param>
+ /// <param name="value">The object containing the values.</param>
+ public FieldPropertyDescriptor(string name, FieldInfo field, object value)
+ : base(name, (Attribute[])field.GetCustomAttributes(typeof(Attribute), true), value)
+ {
+ this.Field = field;
+ }
+ #endregion
+
+ #region Public properties
+ #region Field
+ /// <summary>
+ /// Gets the underlying field.
+ /// </summary>
+ /// <value>The field information.</value>
+ public FieldInfo Field { get; private set; }
+ #endregion
+
+ #region ComponentType
+ /// <summary>
+ /// Fets the type of the component this property is bound to.
+ /// </summary>
+ /// <value></value>
+ /// <returns>
+ /// A <see cref="T:Type"/> that represents the type of component this property is bound to. When the
+ /// <see cref="M:PropertyDescriptor.GetValue(System.Object)"/> or
+ /// <see cref="M:PropertyDescriptor.SetValue(System.Object,System.Object)"/> methods are invoked, the object specified might be an
+ /// instance of this type.
+ /// </returns>
+ public override Type ComponentType
+ {
+ get { return this.Field.DeclaringType; }
+ }
+ #endregion
+
+ #region PropertyType
+ /// <summary>
+ /// Gets the type of the property.
+ /// </summary>
+ /// <value></value>
+ /// <returns>
+ /// A <see cref="T:System.Type"/> that represents the type of the property.
+ /// </returns>
+ public override Type PropertyType
+ {
+ get { return this.Field.FieldType; }
+ }
+ #endregion
+ #endregion
+
+ #region Public methods
+ #region GetValue()
+ /// <summary>
+ /// Gets the current value of the property on a component.
+ /// </summary>
+ /// <param name="component">The component with the property for which to retrieve the value.</param>
+ /// <returns>
+ /// The value of a property for a given component.
+ /// </returns>
+ public override object GetValue(object component)
+ {
+ return this.WrapValue(this.Field.GetValue(this.Value));
+ }
+ #endregion
+ #endregion
+ }
+ #endregion
+
+ #region PropertyPropertyDescriptor
+ /// <summary>
+ /// Implements <see cref="PropertyDescriptor"/> for properties.
+ /// </summary>
+ public class PropertyPropertyDescriptor
+ : PropertyDescriptorBase
+ {
+ #region Constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PropertyPropertyDescriptor"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="property">The property.</param>
+ /// <param name="value">The object containing the values.</param>
+ public PropertyPropertyDescriptor(string name, PropertyInfo property, object value)
+ : base(name, (Attribute[])property.GetCustomAttributes(typeof(Attribute), true), value)
+ {
+ this.Property = property;
+ }
+ #endregion
+
+ #region Public properties
+ #region Property
+ /// <summary>
+ /// Gets the underlying property.
+ /// </summary>
+ /// <value>The property information.</value>
+ public PropertyInfo Property { get; private set; }
+ #endregion
+
+ #region ComponentType
+ /// <summary>
+ /// Fets the type of the component this property is bound to.
+ /// </summary>
+ /// <value></value>
+ /// <returns>
+ /// A <see cref="T:Type"/> that represents the type of component this property is bound to. When the
+ /// <see cref="M:PropertyDescriptor.GetValue(System.Object)"/> or
+ /// <see cref="M:PropertyDescriptor.SetValue(System.Object,System.Object)"/> methods are invoked, the object specified might be an
+ /// instance of this type.
+ /// </returns>
+ public override Type ComponentType
+ {
+ get { return this.Property.DeclaringType; }
+ }
+ #endregion
+
+ #region PropertyType
+ /// <summary>
+ /// Gets the type of the property.
+ /// </summary>
+ /// <value></value>
+ /// <returns>
+ /// A <see cref="T:System.Type"/> that represents the type of the property.
+ /// </returns>
+ public override Type PropertyType
+ {
+ get { return this.Property.PropertyType; }
+ }
+ #endregion
+ #endregion
+
+ #region Public methods
+ #region GetValue()
+ /// <summary>
+ /// Gets the current value of the property on a component.
+ /// </summary>
+ /// <param name="component">The component with the property for which to retrieve the value.</param>
+ /// <returns>
+ /// The value of a property for a given component.
+ /// </returns>
+ public override object GetValue(object component)
+ {
+ return this.WrapValue(this.Property.GetValue(this.Value, new object[0]));
+ }
+ #endregion
+ #endregion
+ }
+ #endregion
+ #endregion
+ }
+}
Modified: trunk/project/Validator/Validator.csproj
===================================================================
--- trunk/project/Validator/Validator.csproj 2010-01-11 21:05:46 UTC (rev 6690)
+++ trunk/project/Validator/Validator.csproj 2010-01-11 22:55:16 UTC (rev 6691)
@@ -78,6 +78,7 @@
<Compile Include="ConfigurationHierarchy.Designer.cs">
<DependentUpon>ConfigurationHierarchy.cs</DependentUpon>
</Compile>
+ <Compile Include="ConfigurationTypeDescriptor.cs" />
<Compile Include="ConfigViewMode.cs" />
<Compile Include="HtmlAttribute.cs" />
<Compile Include="MainForm.cs">
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.