DictionaryHelper.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Windows.Forms;
  6. using FastReport.CrossView;
  7. namespace FastReport.Data
  8. {
  9. internal class DictionaryHelper
  10. {
  11. #region Private Fields
  12. private Dictionary<string, Base> aliases;
  13. private Dictionary<string, Base> allObjects;
  14. private Dictionary<string, Base> allReportObjects;
  15. private Dictionary<string, Base> dataComponents;
  16. private Dictionary dictionary;
  17. private Dictionary<string, Base> fullNames;
  18. #endregion Private Fields
  19. #region Internal Methods
  20. internal void RegisterDataSet(DataSet data, string referenceName, bool enabled)
  21. {
  22. foreach (DataTable table in data.Tables)
  23. {
  24. PRegisterDataTable(table, referenceName + "." + table.TableName, enabled);
  25. }
  26. foreach (DataRelation relation in data.Relations)
  27. {
  28. PRegisterDataRelation(relation, referenceName + "." + relation.RelationName, enabled);
  29. }
  30. }
  31. internal void ReRegisterData(List<Dictionary.RegDataItem> fRegisteredItems, bool flag)
  32. {
  33. foreach (Dictionary.RegDataItem item in fRegisteredItems)
  34. {
  35. PRegisterData(item.data, item.name, flag);
  36. }
  37. }
  38. #endregion Internal Methods
  39. #region Private Methods
  40. private void AddBaseToDictionary(Base b)
  41. {
  42. if (b is DataComponentBase && (b as DataComponentBase).ReferenceName != null)
  43. {
  44. dataComponents[(b as DataComponentBase).ReferenceName] = b;
  45. }
  46. if ((b is DataComponentBase || b is Relation) && (b as DataComponentBase).Alias != null)
  47. {
  48. aliases[(b as DataComponentBase).Alias] = b;
  49. }
  50. if (b is DataSourceBase)
  51. {
  52. string fullname = (b as DataSourceBase).FullName;
  53. if (fullname != null)
  54. fullNames[fullname] = b;
  55. }
  56. if (b.Name != null)
  57. {
  58. allObjects[b.Name] = b;
  59. allReportObjects[b.Name] = b;
  60. }
  61. }
  62. private void AddBaseWithChiledToDictonary(Base b)
  63. {
  64. AddBaseToDictionary(b);
  65. foreach (Base obj in b.AllObjects)
  66. AddBaseToDictionary(obj);
  67. }
  68. private string CreateUniqueAlias(string alias)
  69. {
  70. string baseAlias = alias;
  71. int i = 1;
  72. while (FindByAlias(alias) != null)
  73. {
  74. alias = baseAlias + i.ToString();
  75. i++;
  76. }
  77. return alias;
  78. }
  79. private string CreateUniqueName(string name)
  80. {
  81. string baseName = name;
  82. int i = 1;
  83. while (FindByName(name) != null || FindReportObjectByName(name) != null)
  84. {
  85. name = baseName + i.ToString();
  86. i++;
  87. }
  88. return name;
  89. }
  90. private DataComponentBase FindByAlias(string alias)
  91. {
  92. Base result = null;
  93. if (aliases.TryGetValue(alias, out result))
  94. {
  95. if ((result is DataConnectionBase || result is Relation))
  96. return result as DataComponentBase;
  97. }
  98. if (fullNames.TryGetValue(alias, out result))
  99. if (result is DataSourceBase)
  100. return result as DataComponentBase;
  101. return null;
  102. }
  103. private Base FindByName(string name)
  104. {
  105. Base result = null;
  106. if (allObjects.TryGetValue(name, out result))
  107. {
  108. if (result is DataConnectionBase || result is DataSourceBase || result is Relation ||
  109. (result is Parameter && result.Parent == dictionary) || result is Total)
  110. return result;
  111. }
  112. return null;
  113. }
  114. private DataComponentBase FindDataComponent(string referenceName)
  115. {
  116. Base c;
  117. if (dataComponents.TryGetValue(referenceName, out c))
  118. if (c is DataComponentBase)
  119. return c as DataComponentBase;
  120. return null;
  121. }
  122. private Base FindReportObjectByName(string name)
  123. {
  124. Base result = null;
  125. if (allReportObjects.TryGetValue(name, out result))
  126. {
  127. return result;
  128. }
  129. return null;
  130. }
  131. private void PRegisterBusinessObject(IEnumerable data, string referenceName, int maxNestingLevel, bool enabled)
  132. {
  133. dictionary.AddRegisteredItem(data, referenceName);
  134. Type dataType = data.GetType();
  135. if (data is BindingSource)
  136. {
  137. if ((data as BindingSource).DataSource is Type)
  138. dataType = ((data as BindingSource).DataSource as Type);
  139. else
  140. dataType = (data as BindingSource).DataSource.GetType();
  141. }
  142. BusinessObjectConverter converter = new BusinessObjectConverter(dictionary);
  143. BusinessObjectDataSource source = FindDataComponent(referenceName) as BusinessObjectDataSource;
  144. if (source != null)
  145. {
  146. source.Reference = data;
  147. source.DataType = dataType;
  148. converter.UpdateExistingObjects(source, maxNestingLevel);
  149. }
  150. else
  151. {
  152. source = new BusinessObjectDataSource();
  153. source.ReferenceName = referenceName;
  154. source.Reference = data;
  155. source.DataType = dataType;
  156. source.Name = CreateUniqueName(referenceName);
  157. source.Alias = CreateUniqueAlias(source.Alias);
  158. source.Enabled = enabled;
  159. dictionary.DataSources.Add(source);
  160. converter.CreateInitialObjects(source, maxNestingLevel);
  161. AddBaseWithChiledToDictonary(source);
  162. }
  163. }
  164. private void PRegisterData(object data, string name, bool enabled)
  165. {
  166. if (data is DataSet)
  167. {
  168. RegisterDataSet(data as DataSet, name, enabled);
  169. }
  170. else if (data is DataTable)
  171. {
  172. PRegisterDataTable(data as DataTable, name, enabled);
  173. }
  174. else if (data is DataView)
  175. {
  176. PRegisterDataView(data as DataView, name, enabled);
  177. }
  178. else if (data is DataRelation)
  179. {
  180. PRegisterDataRelation(data as DataRelation, name, enabled);
  181. }
  182. else if (data is IEnumerable)
  183. {
  184. PRegisterBusinessObject(data as IEnumerable, name, 1, enabled);
  185. }
  186. else if (data is IBaseCubeLink)
  187. {
  188. PRegisterCubeLink(data as IBaseCubeLink, name, enabled);
  189. }
  190. }
  191. private void PRegisterDataRelation(DataRelation relation, string referenceName, bool enabled)
  192. {
  193. dictionary.AddRegisteredItem(relation, referenceName);
  194. if (FindDataComponent(referenceName) != null)
  195. return;
  196. Relation rel = new Relation();
  197. rel.ReferenceName = referenceName;
  198. rel.Reference = relation;
  199. rel.Name = relation.RelationName;
  200. rel.Enabled = enabled;
  201. rel.ParentDataSource = dictionary.FindDataTableSource(relation.ParentTable);
  202. rel.ChildDataSource = dictionary.FindDataTableSource(relation.ChildTable);
  203. string[] parentColumns = new string[relation.ParentColumns.Length];
  204. string[] childColumns = new string[relation.ChildColumns.Length];
  205. for (int i = 0; i < relation.ParentColumns.Length; i++)
  206. {
  207. parentColumns[i] = relation.ParentColumns[i].Caption;
  208. }
  209. for (int i = 0; i < relation.ChildColumns.Length; i++)
  210. {
  211. childColumns[i] = relation.ChildColumns[i].Caption;
  212. }
  213. rel.ParentColumns = parentColumns;
  214. rel.ChildColumns = childColumns;
  215. dictionary.Relations.Add(rel);
  216. AddBaseWithChiledToDictonary(rel);
  217. }
  218. private void PRegisterDataTable(DataTable table, string referenceName, bool enabled)
  219. {
  220. dictionary.AddRegisteredItem(table, referenceName);
  221. TableDataSource source = FindDataComponent(referenceName) as TableDataSource;
  222. if (source != null)
  223. {
  224. source.Reference = table;
  225. source.InitSchema();
  226. source.RefreshColumns(true);
  227. AddBaseWithChiledToDictonary(source);
  228. }
  229. else
  230. {
  231. // check tables inside connections. Are we trying to replace the connection table
  232. // with table provided by an application?
  233. source = FindByAlias(referenceName) as TableDataSource;
  234. // check "Data.TableName" case
  235. if (source == null && referenceName.StartsWith("Data."))
  236. source = FindByAlias(referenceName.Remove(0, 5)) as TableDataSource;
  237. if (source != null && (source.Connection != null || source.IgnoreConnection))
  238. {
  239. source.IgnoreConnection = true;
  240. source.Reference = table;
  241. source.InitSchema();
  242. source.RefreshColumns(true);
  243. AddBaseWithChiledToDictonary(source);
  244. }
  245. else
  246. {
  247. source = new TableDataSource();
  248. source.ReferenceName = referenceName;
  249. source.Reference = table;
  250. source.Name = CreateUniqueName(referenceName.Contains(".") ? table.TableName : referenceName);
  251. source.Alias = CreateUniqueAlias(source.Alias);
  252. source.Enabled = enabled;
  253. source.InitSchema();
  254. dictionary.DataSources.Add(source);
  255. AddBaseWithChiledToDictonary(source);
  256. }
  257. }
  258. }
  259. private void PRegisterDataView(DataView view, string referenceName, bool enabled)
  260. {
  261. dictionary.AddRegisteredItem(view, referenceName);
  262. ViewDataSource source = FindDataComponent(referenceName) as ViewDataSource;
  263. if (source != null)
  264. {
  265. source.Reference = view;
  266. source.InitSchema();
  267. source.RefreshColumns();
  268. }
  269. else
  270. {
  271. source = new ViewDataSource();
  272. source.ReferenceName = referenceName;
  273. source.Reference = view;
  274. source.Name = CreateUniqueName(referenceName);
  275. source.Alias = CreateUniqueAlias(source.Alias);
  276. source.Enabled = enabled;
  277. source.InitSchema();
  278. dictionary.DataSources.Add(source);
  279. AddBaseWithChiledToDictonary(source);
  280. }
  281. }
  282. private void PRegisterCubeLink(IBaseCubeLink cubeLink, string referenceName, bool enabled)
  283. {
  284. dictionary.AddRegisteredItem(cubeLink, referenceName);
  285. CubeSourceBase source = FindDataComponent(referenceName) as CubeSourceBase;
  286. if (source != null)
  287. {
  288. source.Reference = cubeLink;
  289. // source.InitSchema();
  290. }
  291. else
  292. {
  293. source = new SliceCubeSource();
  294. source.ReferenceName = referenceName;
  295. source.Reference = cubeLink;
  296. source.Name = CreateUniqueName(referenceName);
  297. source.Alias = CreateUniqueAlias(source.Alias);
  298. source.Enabled = enabled;
  299. // source.InitSchema();
  300. dictionary.CubeSources.Add(source);
  301. AddBaseWithChiledToDictonary(source);
  302. }
  303. }
  304. #endregion Private Methods
  305. #region Public Constructors
  306. public DictionaryHelper(Dictionary dictionary, ObjectCollection AllDictionaryObjects, ObjectCollection AllDictionaryReportObjects)
  307. {
  308. this.dictionary = dictionary;
  309. dataComponents = new Dictionary<string, Base>();
  310. aliases = new Dictionary<string, Base>();
  311. fullNames = new Dictionary<string, Base>();
  312. allObjects = new Dictionary<string, Base>();
  313. allReportObjects = new Dictionary<string, Base>();
  314. foreach (Base obj in AllDictionaryObjects)
  315. {
  316. AddBaseToDictionary(obj);
  317. }
  318. foreach (Base obj in AllDictionaryReportObjects)
  319. {
  320. if (obj.Name != null)
  321. allReportObjects[obj.Name] = obj;
  322. }
  323. }
  324. #endregion Public Constructors
  325. }
  326. }