//This file is part of ORM.NET.
//
//ORM.NET is free software; you can redistribute it and/or
//modify it under the terms of the GNU Lesser General Public
//License as published by the Free Software Foundation; either
//version 2.1 of the License, or (at your option) any later version.
//
//ORM.NET is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public
//License along with ORM.NET; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
namespace OrmLib{
internal class GenericPropertyDescriptor : PropertyDescriptor
{
/// <summary>
/// Use this entry point
/// </summary>
/// <param name="pi">the property to make the PropertyDescriptor for</param>
/// <returns></returns>
internal static GenericPropertyDescriptor GetProperty(PropertyInfo pi)
{
ArrayList attributes = new ArrayList();
foreach ( object o in pi.GetCustomAttributes(true) )
{
if ( o as Attribute != null ) attributes.Add(o);
}
return new GenericPropertyDescriptor(pi.DeclaringType, pi.PropertyType, pi.Name, (Attribute[])attributes.ToArray(typeof(Attribute)));
}
private Type componentType;
private Type propertyType;
/// <summary>
/// Do not use.
/// <see cref="GetProperty(PropertyInfo)"/>
/// </summary>
/// <param name="componentType"></param>
/// <param name="propertyType"></param>
/// <param name="name"></param>
/// <param name="attrs"></param>
protected GenericPropertyDescriptor(Type componentType, Type propertyType, string name, Attribute[] attrs) :base(name, attrs)
{
this.componentType = componentType;
this.propertyType = propertyType;
}
public override Type ComponentType
{
get { return componentType; }
}
public override bool IsReadOnly
{
get { return (Attributes.Matches(ReadOnlyAttribute.Yes)); }
}
public override Type PropertyType
{
get { return propertyType; }
}
public override bool CanResetValue(object component)
{
return false;
}
public override object GetValue(object component)
{
return componentType.GetProperty(this.Name).GetValue(component,null);
}
public override void ResetValue(object component)
{
throw new NotSupportedException();
}
public override void SetValue(object component, object value)
{
componentType.GetProperty(this.Name).SetValue(component,value,null);
}
public override bool ShouldSerializeValue(object component)
{
return true;
}
}
/// <summary>
/// Allows the sql datetime to be edited in the grid
/// Use the static property GetProperty() to create one.
/// </summary>
internal class SqlPropertyDescriptor : PropertyDescriptor
{
/// <summary>
/// Only way to create the PropertyDescriptor
/// </summary>
/// <param name="name"></param>
/// <param name="sqlType"></param>
/// <returns></returns>
internal static SqlPropertyDescriptor GetProperty(string name, Type sqlType)
{
// we need to use the attributes of the base type
Type baseType = sqlType.GetProperty("Value").PropertyType;
ArrayList attribs = new ArrayList(TypeDescriptor.GetAttributes(baseType));
Attribute[] attrs = (Attribute[])attribs.ToArray(typeof(Attribute));
return new SqlPropertyDescriptor(name,attrs,sqlType,baseType);
}
private Type SqlType;
private Type BaseType;
// Unused
protected SqlPropertyDescriptor(MemberDescriptor descr) : base(descr){}
protected SqlPropertyDescriptor(MemberDescriptor descr,Attribute[] attrs) : base(descr,attrs){}
protected SqlPropertyDescriptor(string name,Attribute[] attrs) : base(name,attrs){}
// use this
protected SqlPropertyDescriptor( string name,Attribute[] attrs, Type sqlType, Type baseType ) : base(name,attrs)
{
SqlType = sqlType;
BaseType = baseType;
}
/// <summary>
/// TODO
/// </summary>
/// <param name="component"></param>
/// <returns></returns>
public override bool CanResetValue(object component)
{
return false;
}
/// <summary>
/// TODO
/// </summary>
/// <param name="component"></param>
public override void ResetValue(object component)
{
throw new NotSupportedException();
}
public override bool ShouldSerializeValue(object component)
{
return true;
}
public override Type ComponentType
{
get { return BaseType; }
}
public override bool IsReadOnly
{
get { return false; }
}
public override Type PropertyType
{
get { return BaseType; }
}
public override void SetValue(object component,object value)
{
try
{
PropertyInfo pi = component.GetType().GetProperty(this.Name);
Object o;
if ( value == DBNull.Value )
{
o = pi.PropertyType.GetField("Null", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetField).GetValue(null);
}
else
{
o = pi.PropertyType.GetConstructor(new Type[]{BaseType}).Invoke(new Object[]{value});
}
pi.SetValue(component,o, null);
}
catch(Exception ex)
{
Debug.WriteLine(ex);
}
}
public override object GetValue(object component)
{
try
{
object Property = component.GetType().GetProperty(this.Name).GetValue(component,null);
// handle nulls
if ( (bool)Property.GetType().GetProperty("IsNull").GetValue(Property,null) ) return DBNull.Value;
object Value = Property.GetType().GetProperty("Value").GetValue(Property,null);
return Value;
}
catch(Exception ex)
{
Debug.WriteLine(ex);
}
return null;
}
}
/// <summary>
/// Provides Comparison opreations.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public class ObjectPropertyComparer : IComparer
{
private string PropertyName;
/// <summary>
/// Provides Comparison opreations.
/// </summary>
/// <param name="propertyName">The property to compare</param>
public ObjectPropertyComparer( string propertyName)
{
PropertyName = propertyName;
}
/// <summary>
/// Compares 2 objects by their properties, given on the constructor
/// </summary>
/// <param name="x">First value to compare</param>
/// <param name="y">Second value to compare</param>
/// <returns></returns>
public int Compare(object x, object y)
{
Type t1 = x.GetType();
Type t2 = y.GetType();
PropertyInfo p1 = t1.GetProperty(PropertyName);
PropertyInfo p2 = t2.GetProperty(PropertyName);
Debug.Assert(p1 != null);
Debug.Assert(p2 != null);
object a = p1.GetValue(x, null);
object b = p2.GetValue(y, null);
//object a = x.GetType().GetProperty(PropertyName).GetValue(x, null);
//object b = y.GetType().GetProperty(PropertyName).GetValue(y, null);
if ( a != null && b == null )
return 1;
if ( a == null && b != null )
return -1;
if ( a == null && b == null )
return 0;
return ((IComparable)a).CompareTo(b);
}
}
}
|