using System; using System.Data; using System.Collections; using System.ComponentModel; using System.Reflection; //using CSLA.Resources; namespace GZTW.AyaNova.BLL { #pragma warning disable 1591 /// /// An ReportDataSetAdapter is used to convert data in an object /// or collection into a ReportDataSet suitable for using with AyaNova reporting /// methods. /// public class ReportDataSetAdapter { ArrayList _columns = new ArrayList(); public struct ColumnInfo { internal string name; internal System.Type type; public string ColumnName { get { return name; } } public System.Type ColumnType { get { return type; } } } /// /// Given a data source /// returns an arraylist containing /// ColumnInfo structures /// for each column found /// /// /// public ArrayList GetDataSourceColumns(object source) { AutoDiscover(source); return _columns; } /// /// Fills the DataSet with data from an object or collection. /// /// /// The name of the DataTable being filled is will be the class name of /// the object acting as the data source. The /// DataTable will be inserted if it doesn't already exist in the DataSet. /// /// A reference to the DataSet to be filled. /// A reference to the object or collection acting as a data source. public void Fill(ReportDataSet ds, object source) { string className = source.GetType().Name; Fill(ds, className, source); } /// /// Fills the DataSet with data from an object or collection. /// (internally used by AyaNova for reporting compatibility with DevExpress report designer component) /// /// /// The name of the DataTable being filled is specified as a parameter. The /// DataTable will be inserted if it doesn't already exist in the DataSet. /// /// A reference to the DataSet to be filled. /// /// A reference to the object or collection acting as a data source. public void Fill(ReportDataSet ds, string tableName, object source) { DataTable dt = ds.Tables[tableName]; bool exists = (dt != null); if(!exists) dt = new DataTable(tableName); Fill(dt, source); if(!exists) ds.Tables.Add(dt); } /// /// Fills a DataTable with data values from an object or collection. /// /// A reference to the DataTable to be filled. /// A reference to the object or collection acting as a data source. public void Fill(DataTable dt, object source) { AutoDiscover(source); DataCopy(dt, source); } #region Data Copy void DataCopy(DataTable dt, object source) { if(source == null) return; if(_columns.Count < 1) return; if(source is IListSource) { DataCopyIList(dt, ((IListSource)source).GetList()); } else { if(source is IList) { DataCopyIList(dt, (IList)source); } else { // they gave us a regular object - create a list ArrayList col = new ArrayList(); col.Add(source); DataCopyIList(dt, (IList)col); } } } void DataCopyIList(DataTable dt, IList ds) { // create columns if needed foreach(ColumnInfo column in _columns) { if(!dt.Columns.Contains(column.name)) dt.Columns.Add(column.name,column.type); } // load the data into the control dt.BeginLoadData(); for(int index = 0; index < ds.Count; index++) { DataRow dr = dt.NewRow(); foreach(ColumnInfo column in _columns) { try { dr[column.name] = GetField(ds[index], column.name); } catch(Exception ex) { dr[column.name] = ex.Message; } } dt.Rows.Add(dr); } dt.EndLoadData(); } #endregion #region AutoDiscover void AutoDiscover(object source) { object innerSource; if(source is IListSource) { innerSource = ((IListSource)source).GetList(); } else { innerSource = source; } _columns.Clear(); if(innerSource is DataView) { ScanDataView((DataView)innerSource); } else { if(innerSource is IList) { ScanIList((IList)innerSource); } else { // they gave us a regular object ScanObject(innerSource); } } } void ScanDataView(DataView ds) { for(int field = 0; field < ds.Table.Columns.Count; field++) { ColumnInfo i=new ColumnInfo(); i.name=ds.Table.Columns[field].ColumnName; i.type=ds.Table.Columns[field].DataType; _columns.Add(i); } } void ScanIList(IList ds) { if(ds.Count > 0) { // retrieve the first item from the list object obj = ds[0]; if(obj is ValueType && obj.GetType().IsPrimitive) { // the value is a primitive value type ColumnInfo i=new ColumnInfo(); i.name="Value"; i.type=obj.GetType(); _columns.Add(i); } else { if(obj is string) { // the value is a simple string ColumnInfo i=new ColumnInfo(); i.name="Text"; i.type=typeof(string); _columns.Add(i); } else { // we have a complex Structure or object ScanObject(obj); } } } } void ScanObject(object source) { Type sourceType = source.GetType(); // retrieve a list of all public properties PropertyInfo [] props = sourceType.GetProperties(); for(int column = 0; column < props.Length; column++) if(props[column].CanRead) { ColumnInfo i=new ColumnInfo(); i.name=props[column].Name; if(props[column].PropertyType ==typeof(decimal)) i.type=props[column].PropertyType; else i.type=typeof(object); _columns.Add(i); } // retrieve a list of all public fields FieldInfo [] fields = sourceType.GetFields(); for(int column = 0; column < fields.Length; column++) { ColumnInfo i=new ColumnInfo(); i.name=fields[column].Name; i.type=fields[column].FieldType; _columns.Add(i); } } #endregion #region GetField //case 1346 was string but needs to be object to support images object GetField(object obj, string fieldName) { if(obj is DataRowView) { // this is a DataRowView from a DataView return ((DataRowView)obj)[fieldName].ToString(); } else { if(obj is ValueType && obj.GetType().IsPrimitive) { // this is a primitive value type if(obj == null) return string.Empty; else return obj.ToString(); } else { if(obj is string) { // this is a simple string if(obj == null) return string.Empty; else return obj.ToString(); } else { // this is an object or Structure try { Type sourcetype = obj.GetType(); // see if the field is a property PropertyInfo prop = sourcetype.GetProperty(fieldName); if(prop == null || !prop.CanRead) { // no readable property of that name exists - check for a field FieldInfo field = sourcetype.GetField(fieldName); if(field == null) { // no field exists either, throw an exception throw new System.Data.DataException( "NoSuchValueExistsException" + fieldName); } else { // got a field, return its value return field.GetValue(obj).ToString(); } } else { // found a property, return its value //case 1346 image fields can't be returned as string //so return without conversion to string Type ttt = prop.PropertyType; //case 1632 if (ttt.IsEnum) { //convert to localized text value System.Enum en=prop.GetValue(obj, null) as System.Enum; string s= EnumDescConverter.GetEnumDescription(en); return s; } //case 1346 if (ttt == typeof(byte[]) || ttt == typeof(System.Drawing.Bitmap)) { return prop.GetValue(obj, null); } return prop.GetValue(obj, null).ToString(); } } catch(Exception ex) { throw new System.Data.DataException( "ErrorReadingValueException" + fieldName, ex); } } } } } #endregion } #pragma warning restore 1591 }