// Copyright (c) 2012, Outercurve Foundation. // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // - Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // - Neither the name of the Outercurve Foundation nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; using System.Reflection; using System.Data; using System.Collections; using System.Collections.Generic; using WebsitePanel.Providers; namespace WebsitePanel.EnterpriseServer { /// /// Summary description for ObjectUtils. /// public class ObjectUtils { public static DT ConvertObject(ST so) { Dictionary sProps = GetTypePropertiesHash(typeof(ST)); Dictionary dProps = GetTypePropertiesHash(typeof(DT)); DT dobj = (DT)Activator.CreateInstance(typeof(DT)); // copy properties foreach (string propName in sProps.Keys) { if (dProps.ContainsKey(propName) && sProps[propName].Name != "Item") { if (sProps[propName].CanRead) { object val = sProps[propName].GetValue(so, null); if (dProps[propName] != null) { if (val != null && dProps[propName].CanWrite) { dProps[propName].SetValue(dobj, val, null); } } } } } return dobj; } private static Hashtable typeProperties = new Hashtable(); public static Hashtable GetObjectProperties(object obj, bool persistentOnly) { Hashtable hash = new Hashtable(); Type type = obj.GetType(); PropertyInfo[] props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo prop in props) { // check for persistent attribute object[] attrs = prop.GetCustomAttributes(typeof(PersistentAttribute), false); if (!persistentOnly || (persistentOnly && attrs.Length > 0) && !hash.ContainsKey(prop.Name)) { object val = prop.GetValue(obj, null); string s = ""; if (val != null) { if (prop.PropertyType == typeof(string[])) s = String.Join(";", (string[])val); else if (prop.PropertyType == typeof(int[])) { int[] ivals = (int[])val; string[] svals = new string[ivals.Length]; for (int i = 0; i < svals.Length; i++) svals[i] = ivals[i].ToString(); s = String.Join(";", svals); } else s = val.ToString(); } // add property to hash hash.Add(prop.Name, s); } } return hash; } public static void FillCollectionFromDataSet(List list, DataSet ds) { if (ds.Tables.Count == 0) return; FillCollectionFromDataView(list, ds.Tables[0].DefaultView); } public static void FillCollectionFromDataView(List list, DataView dv) { Type type = typeof(T); PropertyInfo[] props = GetTypeProperties(type); foreach (DataRowView dr in dv) { // create an instance T obj = (T)Activator.CreateInstance(type); list.Add(obj); // fill properties for (int i = 0; i < props.Length; i++) { string propName = props[i].Name; if (dv.Table.Columns[propName] == null) continue; object propVal = dr[propName]; if (propVal == DBNull.Value) props[i].SetValue(obj, GetNull(props[i].PropertyType), null); else { try { // try implicit type conversion props[i].SetValue(obj, propVal, null); } catch { // convert to string and then set property value try { string strVal = propVal.ToString(); props[i].SetValue(obj, Cast(strVal, props[i].PropertyType), null); } catch { // skip property init } } } } // for properties } // for rows } public static List CreateListFromDataReader(IDataReader reader) { List list = new List(); FillCollectionFromDataReader(list, reader); return list; } public static List CreateListFromDataSet(DataSet ds) { List list = new List(); FillCollectionFromDataSet(list, ds); return list; } public static void FillCollectionFromDataReader(List list, IDataReader reader) { Type type = typeof(T); try { // get type properties PropertyInfo[] props = GetTypeProperties(type); // iterate through reader while (reader.Read()) { T obj = (T)Activator.CreateInstance(type); list.Add(obj); // set properties for (int i = 0; i < props.Length; i++) { string propName = props[i].Name; try { object propVal = reader[propName]; if (propVal == DBNull.Value) props[i].SetValue(obj, GetNull(props[i].PropertyType), null); else { try { // try implicit type conversion props[i].SetValue(obj, propVal, null); } catch { // convert to string and then set property value try { string strVal = propVal.ToString(); props[i].SetValue(obj, Cast(strVal, props[i].PropertyType), null); } catch { } } } } catch { } // just skip } // for properties } } finally { reader.Close(); } } public static T FillObjectFromDataView(DataView dv) { Type type = typeof(T); T obj = default(T); // get type properties PropertyInfo[] props = GetTypeProperties(type); // iterate through reader foreach (DataRowView dr in dv) { obj = (T)Activator.CreateInstance(type); // set properties for (int i = 0; i < props.Length; i++) { string propName = props[i].Name; try { // verify if there is such a column if (!dr.Row.Table.Columns.Contains(propName.ToLower())) { // if not, we move to another property // because this one we cannot set continue; } object propVal = dr[propName]; if (propVal == DBNull.Value) props[i].SetValue(obj, GetNull(props[i].PropertyType), null); else { try { string strVal = propVal.ToString(); //convert to DateTime if (props[i].PropertyType.UnderlyingSystemType.FullName == typeof(DateTime).FullName) { DateTime date = DateTime.MinValue; if (DateTime.TryParse(strVal, out date)) { props[i].SetValue(obj, date, null); } } else { //Convert generic props[i].SetValue(obj, Cast(strVal, props[i].PropertyType), null); } } catch { // skip property init } } } catch { } // just skip } // for properties } return obj; } public static T FillObjectFromDataReader(IDataReader reader) { Type type = typeof(T); T obj = default(T); try { // get type properties PropertyInfo[] props = GetTypeProperties(type); // iterate through reader while (reader.Read()) { obj = (T)Activator.CreateInstance(type); // set properties for (int i = 0; i < props.Length; i++) { string propName = props[i].Name; try { if (!IsColumnExists(propName, reader.GetSchemaTable())) { continue; } object propVal = reader[propName]; if (propVal == DBNull.Value) props[i].SetValue(obj, GetNull(props[i].PropertyType), null); else { try { //try string first if (props[i].PropertyType.UnderlyingSystemType.FullName == typeof(String).FullName) { props[i].SetValue(obj, propVal.ToString(), null); } else { // then, try implicit type conversion props[i].SetValue(obj, propVal, null); } } catch { // convert to string and then set property value try { string strVal = propVal.ToString(); props[i].SetValue(obj, Cast(strVal, props[i].PropertyType), null); } catch { // skip property init } } } } catch { } // just skip } // for properties } } finally { reader.Close(); } return obj; } private static Hashtable propertiesCache = new Hashtable(); public static object CreateObjectFromDataview(Type type, DataView dv, string nameColumn, string valueColumn, bool persistentOnly) { // create hash of properties from datareader Hashtable propValues = new Hashtable(); foreach (DataRowView dr in dv) { if (propValues[dr[nameColumn]] == null && !propValues.ContainsKey(dr[nameColumn])) propValues.Add(dr[nameColumn], dr[valueColumn]); } return CreateObjectFromHash(type, propValues, persistentOnly); } public static object CreateObjectFromDataReader(Type type, IDataReader reader, string nameColumn, string valueColumn, bool persistentOnly) { // create hash of properties from datareader Hashtable propValues = new Hashtable(); while (reader.Read()) { if (propValues[reader[nameColumn]] == null && !propValues.ContainsKey(reader[nameColumn])) propValues.Add(reader[nameColumn], reader[valueColumn]); } reader.Close(); return CreateObjectFromHash(type, propValues, persistentOnly); } public static object CreateObjectFromHash(Type type, Hashtable propValues, bool persistentOnly) { // create object object obj = Activator.CreateInstance(type); CreateObjectFromHash(obj, propValues, persistentOnly); return obj; } public static void CopyPersistentPropertiesFromSource(T source, T target) where T : ServiceProviderItem { // var typeSource = source.GetType(); var typeTarget = target.GetType(); // get all property infos Hashtable props = null; if (propertiesCache[typeSource.Name] != null) { // load properties from cache props = (Hashtable)propertiesCache[typeSource.Name]; } else { // create properties cache props = new Hashtable(); // PropertyInfo[] objProps = typeSource.GetProperties(BindingFlags.Instance //| BindingFlags.DeclaredOnly | BindingFlags.Public); foreach (PropertyInfo prop in objProps) { // check for persistent attribute object[] attrs = prop.GetCustomAttributes(typeof(PersistentAttribute), false); // Persistent only if (attrs.Length > 0 && !props.ContainsKey(prop.Name)) { // add property to hash props.Add(prop.Name, prop); } } if (!propertiesCache.ContainsKey(typeSource.Name)) { // add to cache propertiesCache.Add(typeSource.Name, props); } } // Copy the data foreach (PropertyInfo propertyInfo in props.Values) { propertyInfo.SetValue(target, propertyInfo.GetValue(source, null), null); } } public static void CreateObjectFromHash(object obj, Hashtable propValues, bool persistentOnly) { Type type = obj.GetType(); // get all property infos Hashtable props = null; if (propertiesCache[type.Name] != null) { // load properties from cache props = (Hashtable)propertiesCache[type.Name]; } else { // create properties cache props = new Hashtable(); PropertyInfo[] objProps = type.GetProperties(BindingFlags.Instance //| BindingFlags.DeclaredOnly | BindingFlags.Public); foreach (PropertyInfo prop in objProps) { // check for persistent attribute object[] attrs = prop.GetCustomAttributes(typeof(PersistentAttribute), false); if (!persistentOnly || (persistentOnly && attrs.Length > 0) && !props.ContainsKey(prop.Name)) { // add property to hash props.Add(prop.Name, prop); } } if (!propertiesCache.ContainsKey(type.Name)) { // add to cache propertiesCache.Add(type.Name, props); } } // fill properties foreach (string propName in propValues.Keys) { // try to locate specified property if (props[propName] != null) { // set property // we support: // String // Int32 // Boolean // Float PropertyInfo prop = (PropertyInfo)props[propName]; string val = propValues[propName].ToString(); if (prop.PropertyType == typeof(String)) prop.SetValue(obj, val, null); else if (prop.PropertyType == typeof(Int32)) prop.SetValue(obj, Int32.Parse(val), null); else if (prop.PropertyType == typeof(long)) prop.SetValue(obj, long.Parse(val), null); else if (prop.PropertyType == typeof(Boolean)) prop.SetValue(obj, Boolean.Parse(val), null); else if (prop.PropertyType == typeof(Single)) prop.SetValue(obj, Single.Parse(val), null); else if (prop.PropertyType.IsEnum) prop.SetValue(obj, Enum.Parse(prop.PropertyType, val, true), null); else if (prop.PropertyType == typeof(Guid)) prop.SetValue(obj, new Guid(val), null); else if (prop.PropertyType == typeof(string[])) { if (val == "") prop.SetValue(obj, new string[0], null); else prop.SetValue(obj, val.Split(';'), null); } else if (prop.PropertyType == typeof(int[])) { string[] svals = val.Split(';'); int[] ivals = new int[svals.Length]; for (int i = 0; i < svals.Length; i++) ivals[i] = Int32.Parse(svals[i]); if (val == "") ivals = new int[0]; prop.SetValue(obj, ivals, null); } } } } private static Dictionary GetTypePropertiesHash(Type type) { Dictionary hash = new Dictionary(); PropertyInfo[] props = GetTypeProperties(type); foreach (PropertyInfo prop in props) { if (!hash.ContainsKey(prop.Name)) { hash.Add(prop.Name, prop); } } return hash; } private static PropertyInfo[] GetTypeProperties(Type type) { string typeName = type.AssemblyQualifiedName; if (typeProperties[typeName] != null) return (PropertyInfo[])typeProperties[typeName]; PropertyInfo[] props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); typeProperties[typeName] = props; return props; } public static object GetNull(Type type) { if (type == typeof(string)) return null; if (type == typeof(Int32)) return 0; if (type == typeof(Int64)) return 0; if (type == typeof(Boolean)) return false; if (type == typeof(Decimal)) return 0M; else return null; } public static object Cast(string val, Type type) { if (type == typeof(string)) return val; if (type == typeof(Int32)) return Int32.Parse(val); if (type == typeof(Int64)) return Int64.Parse(val); if (type == typeof(Boolean)) return Boolean.Parse(val); if (type == typeof(Decimal)) return Decimal.Parse(val); if (type == typeof(string[]) && val != null) { return val.Split(';'); } if (type.IsEnum) return Enum.Parse(type, val, true); if (type == typeof(int[]) && val != null) { string[] sarr = val.Split(';'); int[] iarr = new int[sarr.Length]; for (int i = 0; i < sarr.Length; i++) iarr[i] = Int32.Parse(sarr[i]); return iarr; } else return val; } public static string GetTypeFullName(Type type) { return type.FullName + ", " + type.Assembly.GetName().Name; } #region Helper Functions /// /// This function is used to determine whether IDataReader contains a Column. /// /// Name of the column. /// The schema that decribes result-set contains. /// True, when required column exists in the . Otherwise, false. /// /// The followin example shows how to look for the "Role" column in the . /// /// IDataReader reader = .... /// if (!IsColumnExists("Role", reader.GetSchemaTable()) /// { /// continue; /// } /// /// object roleValue = reader["Role"]; /// /// static bool IsColumnExists(string columnName, DataTable schemaTable) { foreach (DataRow row in schemaTable.Rows) { if (String.Compare(row[0].ToString(), columnName, StringComparison.OrdinalIgnoreCase) == 0) { return true; } } return false; } #endregion } }