Update of /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Util
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv17044/Util
Modified Files:
ReflectionUtils.cs
Removed Files:
AttributeUtils.cs ExtendedAttributeBuilder.cs
SafeAttributeUtils.cs
Log Message:
Refactored Stan D. contribution [SPRNET-606]
Index: ReflectionUtils.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Util/ReflectionUtils.cs,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -d -r1.52 -r1.53
*** ReflectionUtils.cs 11 Oct 2007 05:57:25 -0000 1.52
--- ReflectionUtils.cs 3 Dec 2007 09:07:18 -0000 1.53
***************
*** 23,26 ****
--- 23,30 ----
using System;
using System.Collections;
+ #if NET_2_0
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ #endif
using System.Globalization;
using System.Reflection;
***************
*** 38,42 ****
/// <author>Rod Johnson</author>
/// <author>Juergen Hoeller</author>
! /// <author>Aleksandar Seovic (.Net)</author>
/// <version>$Id$</version>
public sealed class ReflectionUtils
--- 42,48 ----
/// <author>Rod Johnson</author>
/// <author>Juergen Hoeller</author>
! /// <author>Aleksandar Seovic (.NET)</author>
! /// <author>Stan Dvoychenko (.NET)</author>
! /// <author>Bruno Baia (.NET)</author>
/// <version>$Id$</version>
public sealed class ReflectionUtils
***************
*** 654,661 ****
string name = criteria as string;
return String.Compare(method.Name, name, true, CultureInfo.InvariantCulture) == 0;
! }
! /// <summary>
! /// Creates a custom <see cref="System.Attribute"/>.
/// </summary>
/// <remarks>
--- 660,667 ----
string name = criteria as string;
return String.Compare(method.Name, name, true, CultureInfo.InvariantCulture) == 0;
! }
! /// <summary>
! /// Creates a <see cref="System.Reflection.Emit.CustomAttributeBuilder"/>.
/// </summary>
/// <remarks>
***************
*** 777,781 ****
/// <summary>
! /// Creates a custom <see cref="System.Attribute"/>.
/// </summary>
/// <param name="type">
--- 783,787 ----
/// <summary>
! /// Creates a <see cref="System.Reflection.Emit.CustomAttributeBuilder"/>.
/// </summary>
/// <param name="type">
***************
*** 793,797 ****
/// <summary>
! /// Creates a custom <see cref="System.Attribute"/>.
/// </summary>
/// <param name="sourceAttribute">
--- 799,803 ----
/// <summary>
! /// Creates a <see cref="System.Reflection.Emit.CustomAttributeBuilder"/>.
/// </summary>
/// <param name="sourceAttribute">
***************
*** 809,813 ****
/// <summary>
! /// Creates a custom <see cref="System.Attribute"/>.
/// </summary>
/// <param name="type">
--- 815,819 ----
/// <summary>
! /// Creates a <see cref="System.Reflection.Emit.CustomAttributeBuilder"/>.
/// </summary>
/// <param name="type">
***************
*** 821,825 ****
/// <summary>
! /// Creates a custom <see cref="System.Attribute"/>.
/// </summary>
/// <param name="type">
--- 827,831 ----
/// <summary>
! /// Creates a <see cref="System.Reflection.Emit.CustomAttributeBuilder"/>.
/// </summary>
/// <param name="type">
***************
*** 837,840 ****
--- 843,959 ----
}
+ #if NET_2_0
+ /// <summary>
+ /// Creates a <see cref="System.Reflection.Emit.CustomAttributeBuilder"/>.
+ /// </summary>
+ /// <param name="attributeData">
+ /// The <see cref="System.Reflection.CustomAttributeData"/> to create
+ /// the custom attribute builder from.
+ /// </param>
+ /// <returns>A custom attribute builder.</returns>
+ public static CustomAttributeBuilder CreateCustomAttribute(CustomAttributeData attributeData)
+ {
+ object[] parameterValues = new object[attributeData.ConstructorArguments.Count];
+ Type[] parameterTypes = new Type[attributeData.ConstructorArguments.Count];
+ object[] namedParameterValues = new object[attributeData.NamedArguments.Count];
+
+ // Fill arrays of the constructor parameters
+ for (int i = 0; i < attributeData.ConstructorArguments.Count; i++)
+ {
+ parameterTypes[i] = attributeData.ConstructorArguments[i].ArgumentType;
+ parameterValues[i] = attributeData.ConstructorArguments[i].Value;
+ }
+
+ Type attributeType = attributeData.Constructor.DeclaringType;
+ PropertyInfo[] attributeProperties = attributeType.GetProperties(
+ BindingFlags.Instance | BindingFlags.Public);
+ // Not using generics bellow as probably Spring.NET tries to keep
+ // it on .NET1 compatibility level right now I believe (SD)
+ // In case of using List<CustomAttributesData> the above note makes
+ // no sense (SD:)
+ IList propertiesToSet = new ArrayList();
+ int k = 0;
+ // Fills arrays of the constructor named parameters
+ foreach (CustomAttributeNamedArgument namedArgument in attributeData.NamedArguments)
+ {
+ // Now iterate through all of the PropertyInfo, find the
+ // one with the corresponding to the NamedProperty name
+ // and add it to the array of properties to set.
+ for (int j = 0; j < attributeProperties.Length; j++)
+ {
+ if (attributeProperties[j].Name == namedArgument.MemberInfo.Name)
+ {
+ propertiesToSet.Add(attributeProperties[j]);
+ namedParameterValues[k++] = ResolveValues(namedArgument.TypedValue.Value);
+ break;
+ }
+ else
+ {
+ if (j == attributeProperties.Length - 1)
+ {
+ // In case of no match, throw
+ throw new InvalidOperationException(
+ String.Format(CultureInfo.InvariantCulture,
+ "The property with name {0} can't be found in the " +
+ "type {1}, but is present as a named property " +
+ "on the attributeData {2}", namedArgument.MemberInfo.Name,
+ attributeType.FullName, attributeData));
+ }
+ }
+ }
+ }
+
+ // Get constructor corresponding to the parameters and their types
+ ConstructorInfo constructor = attributeType.GetConstructor(parameterTypes);
+
+ PropertyInfo[] namedProperties = new PropertyInfo[propertiesToSet.Count];
+ propertiesToSet.CopyTo(namedProperties, 0);
+
+ return new CustomAttributeBuilder(
+ constructor, parameterValues, namedProperties, namedParameterValues);
+ }
+
+ private static object ResolveValues(object value)
+ {
+ if (value == null) return value;
+
+ // We are only hunting for the case of the ReadOnlyCollection<T> here.
+ ReadOnlyCollection<CustomAttributeTypedArgument> sourceArray =
+ value as ReadOnlyCollection<CustomAttributeTypedArgument>;
+
+ if (sourceArray == null) return value;
+
+ Type underlyingType = null; // type to be used for arguments
+ Type listType = null;
+ object list = null;
+ List<int> prototypeList = new List<int>();
+
+ foreach (CustomAttributeTypedArgument typedArgument in sourceArray)
+ {
+ if (underlyingType == null)
+ {
+ underlyingType = typedArgument.ArgumentType;
+
+ listType = Type.GetType(
+ "System.Collections.Generic.List`1[[" + underlyingType.AssemblyQualifiedName + "]], " + prototypeList.GetType().Assembly.FullName, true, false);
+ list = Activator.CreateInstance(listType);
+ }
+ if (!underlyingType.Equals(typedArgument.ArgumentType))
+ {
+ throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
+ "Types for the same named parameter of array type are expected to be same"));
+ }
+
+ MethodInfo addMethod = listType.GetMethod("Add");
+ object[] addMethodParameters = new object[1];
+ addMethodParameters[0] = typedArgument.Value;
+ addMethod.Invoke(list, addMethodParameters);
+ }
+
+ MethodInfo toArrayMethod = listType.GetMethod("ToArray");
+ return toArrayMethod.Invoke(list, new object[] { });
+ }
+ #endif
+
/// <summary>
/// Tries to find matching methods in the specified <see cref="System.Type"/>
***************
*** 1090,1120 ****
#endregion Field Cache Management for "MemberwiseCopy"
- private static MethodInfo[] GetCandidateMethods(Type type, string methodName, BindingFlags bindingFlags, int argCount)
- {
- MethodInfo[] methods = type.GetMethods(bindingFlags);
- ArrayList matches = new ArrayList();
! foreach (MethodInfo method in methods)
! {
! if (method.Name == methodName)
! {
! ParameterInfo[] parameters = method.GetParameters();
! if (parameters.Length == argCount)
! {
! matches.Add(method);
! }
! else if (parameters.Length > 0)
! {
! ParameterInfo lastParameter = parameters[parameters.Length - 1];
! if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0)
! {
! matches.Add(method);
! }
! }
! }
! }
! return (MethodInfo[]) matches.ToArray(typeof(MethodInfo));
! }
}
}
\ No newline at end of file
--- 1209,1328 ----
#endregion Field Cache Management for "MemberwiseCopy"
! #region CustomAttributeBuilderBuilder inner class definition
! /// <summary>
! /// Creates a <see cref=" CustomAttributeBuilder"/>.
! /// </summary>
! /// <author>Bruno Baia</author>
! /// <version>$Id$</version>
! public class CustomAttributeBuilderBuilder
! {
! #region Fields
!
! private Type type;
! private ArrayList constructorArgs;
! private ArrayList namedProperties;
! private ArrayList propertyValues;
!
! #endregion
!
! #region Constructor(s) / Destructor
!
! /// <summary>
! /// Creates a new instance of the
! /// <see cref="CustomAttributeBuilderBuilder"/> class.
! /// </summary>
! /// <param name="attributeType">The custom attribute type.</param>
! public CustomAttributeBuilderBuilder(Type attributeType)
! :
! this(attributeType, ObjectUtils.EmptyObjects)
! {
! }
!
! /// <summary>
! /// Creates a new instance of the
! /// <see cref="CustomAttributeBuilderBuilder"/> class.
! /// </summary>
! /// <param name="attributeType">The custom attribute type.</param>
! /// <param name="constructorArgs">The custom attribute constructor arguments.</param>
! public CustomAttributeBuilderBuilder(Type attributeType, params object[] constructorArgs)
! {
! AssertUtils.ArgumentNotNull(attributeType, "attributeType");
! if (!typeof(Attribute).IsAssignableFrom(attributeType))
! {
! throw new ArgumentException(
! string.Format("[{0}] does not derive from the [System.Attribute] class.",
! attributeType.FullName));
! }
! this.type = attributeType;
! this.constructorArgs = new ArrayList(constructorArgs);
! this.namedProperties = new ArrayList();
! this.propertyValues = new ArrayList();
! }
!
! #endregion
!
! #region Public Methods
!
! /// <summary>
! /// Adds the specified values to the constructor argument list
! /// used to create the custom attribute.
! /// </summary>
! /// <param name="values">An array of argument values.</param>
! public void AddContructorArgument(params object[] values)
! {
! this.constructorArgs.AddRange(values);
! }
!
! /// <summary>
! /// Adds a property value to the custom attribute.
! /// </summary>
! /// <param name="name">The property name.</param>
! /// <param name="value">The property value.</param>
! public void AddPropertyValue(string name, object value)
! {
! PropertyInfo propertyInfo = this.type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
! if (propertyInfo == null)
! {
! throw new ArgumentException(
! String.Format("The property '{0}' does no exist in the attribute '{1}'.", name, this.type));
! }
!
! this.namedProperties.Add(propertyInfo);
! this.propertyValues.Add(value);
! }
!
! /// <summary>
! /// Creates the <see cref="CustomAttributeBuilderBuilder"/>.
! /// </summary>
! /// <returns>The created <see cref="CustomAttributeBuilderBuilder"/>.</returns>
! public CustomAttributeBuilder Build()
! {
! object[] caArray = (object[])this.constructorArgs.ToArray(typeof(object));
! ConstructorInfo ci = this.type.GetConstructor(ReflectionUtils.GetTypes(caArray));
! if (ci == null && caArray.Length == 0)
! {
! ci = this.type.GetConstructors()[0];
! caArray = ReflectionUtils.GetDefaultValues(ReflectionUtils.GetParameterTypes(ci.GetParameters()));
! }
!
! if (namedProperties.Count > 0)
! {
! PropertyInfo[] npArray = (PropertyInfo[])this.namedProperties.ToArray(typeof(PropertyInfo));
! object[] pvArray = (object[])this.propertyValues.ToArray(typeof(object));
! return new CustomAttributeBuilder(ci, caArray, npArray, pvArray);
! }
! else
! {
! return new CustomAttributeBuilder(ci, caArray);
! }
!
! }
!
! #endregion
! }
!
! #endregion
}
}
\ No newline at end of file
--- AttributeUtils.cs DELETED ---
--- SafeAttributeUtils.cs DELETED ---
--- ExtendedAttributeBuilder.cs DELETED ---
|