Line 1: using System;Line 2: using System.Collections;Line 3: using System.Data;Line 4: using System.Data.Common;Line 5: using System.Xml;Line 6: using System.IO;Line 7: Line 8: using XmlElement = System.Xml.XmlElement;Line 9: Line 10: Line 11: namespace MS.CommonLine 12: {Line 13: /// Line 14: /// Discuz!NT缓存类Line 15: /// 对Discuz!NT论坛缓存进行全局控制管理Line 16: /// Line 17: public class WebCacheLine 18: {Line 19: private static XmlElement objectXmlMap;Line 20: private static ICacheStrategy cs;Line 21: private static volatile WebCache instance = null;Line 22: private static object lockHelper = new object();Line 23: private static XmlDocument rootXml = new XmlDocument();Line 24: Line 25: private static System.Timers.Timer cacheConfigTimer = new System.Timers.Timer(15000);Line 26: Line 27: /// Line 28: /// 构造函数Line 29: /// Line 30: private WebCache()Line 31: {Line 32: cs = new Util_Cache();Line 33: objectXmlMap = rootXml.CreateElement("Cache");Line 34: //建立内部XML文档.Line 35: rootXml.AppendChild(objectXmlMap);Line 36: Line 37: //LogVisitor clv = new CacheLogVisitor();Line 38: //cs.Accept(clv);Line 39: Line 40: cacheConfigTimer.AutoReset = true;Line 41: cacheConfigTimer.Enabled = true;Line 42: cacheConfigTimer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);Line 43: cacheConfigTimer.Start();Line 44: }Line 45: Line 46: private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)Line 47: {Line 48: //检查并移除相应的缓存项Line 49: instance = CachesFileMonitor.CheckAndRemoveCache(instance);Line 50: }Line 51: Line 52: /// Line 53: /// 单体模式返回当前类的实例Line 54: /// Line 55: /// Line 56: public static WebCache GetCacheService()Line 57: {Line 58: Line 59: if (instance == null)Line 60: {Line 61: lock (lockHelper)Line 62: {Line 63: if (instance == null)Line 64: {Line 65: instance = CachesFileMonitor.CheckAndRemoveCache(new WebCache());Line 66: }Line 67: }Line 68: }Line 69: Line 70: return instance;Line 71: }Line 72: Line 73: /// Line 74: /// 添加单值路径,在XML映射文档中加入当前对象信息Line 75: /// Line 76: /// 分级对象的路径 Line 77: /// 被缓存的对象Line 78: public virtual void AddSingleObject(string xpath, object o)Line 79: {Line 80: AddObject(xpath + "/Single", o);Line 81: }Line 82: Line 83: Line 84: /// Line 85: /// 添加单值路径,在XML映射文档中加入当前对象信息Line 86: /// Line 87: /// 分级对象的路径 Line 88: /// 被缓存的对象Line 89: public virtual void AddSingleObject(string xpath, object o, string[] files)Line 90: {Line 91: AddObject(xpath + "/Single", o, files);Line 92: }Line 93: Line 94: Line 95: /// Line 96: /// 添加多点路径,在当前的键上插入多值的域Line 97: /// Line 98: /// 键值Line 99: /// 插入的数组Line 100: /// Line 101: public virtual bool AddMultiObjects(string xpath, object[] objValue)Line 102: {Line 103: lock (lockHelper)Line 104: {Line 105: if (xpath != null && xpath != "" && xpath.Length > 0 && objValue != null)Line 106: {Line 107: Line 108: for (int i = 0; i < objValue.Length; i++)Line 109: {Line 110: AddObject(xpath + "/Multi/_" + i.ToString(), objValue[i]);Line 111: }Line 112: Line 113: return true;Line 114: }Line 115: return false;Line 116: }Line 117: }Line 118: Line 119: Line 120: Line 121: Line 122: /// Line 123: /// 添加多点路径,在当前的键上插入多值的域Line 124: /// Line 125: /// 键值Line 126: /// 插入的数组Line 127: /// Line 128: public virtual bool AddMultiObjects(string xpath, object[] objValue, string[] files)Line 129: {Line 130: lock (lockHelper)Line 131: {Line 132: if (xpath != null && xpath != "" && xpath.Length != 0 && objValue != null)Line 133: {Line 134: Line 135: for (int i = 0; i < objValue.Length; i++)Line 136: {Line 137: AddObject(xpath + "/Multi/_" + i.ToString(), objValue[i], files);Line 138: }Line 139: }Line 140: return true;Line 141: }Line 142: }Line 143: Line 144: Line 145: /// Line 146: /// 缓存标志位类型Line 147: /// Line 148: private enum CacheFlagLine 149: {Line 150: /// Line 151: /// 缓存失败Line 152: /// Line 153: Cachefails,Line 154: Line 155: /// Line 156: /// 缓存中无数据Line 157: /// Line 158: CacheNoData,Line 159: Line 160: /// Line 161: /// 缓存中有数据Line 162: /// Line 163: CacheHaveDataLine 164: }Line 165: Line 166: /// Line 167: /// 添加表类型数据缓存Line 168: /// Line 169: /// 分级对象的路径Line 170: /// 缓存的数据Line 171: public virtual void AddObject(string xpath, DataTable dt)Line 172: {Line 173: lock (lockHelper)Line 174: {Line 175: if (dt.Rows.Count > 0)Line 176: {Line 177: AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 178: }Line 179: elseLine 180: {Line 181: AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 182: }Line 183: AddObject(xpath, (object)dt);Line 184: }Line 185: }Line 186: Line 187: /// Line 188: /// 添加字符串类型数据缓存Line 189: /// Line 190: /// 分级对象的路径Line 191: /// 缓存的数据Line 192: public virtual void AddObject(string xpath, string str)Line 193: {Line 194: lock (lockHelper)Line 195: {Line 196: if ((str != null) && (str != ""))Line 197: {Line 198: AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 199: }Line 200: elseLine 201: {Line 202: AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 203: }Line 204: AddObject(xpath, (object)str);Line 205: }Line 206: }Line 207: Line 208: /// Line 209: /// 添加数据行类型数据缓存Line 210: /// Line 211: /// 分级对象的路径Line 212: /// 缓存的数据Line 213: public virtual void AddObject(string xpath, DataRow dr)Line 214: {Line 215: lock (lockHelper)Line 216: {Line 217: if (dr == null)Line 218: {Line 219: AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 220: }Line 221: elseLine 222: {Line 223: AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 224: }Line 225: AddObject(xpath, (object)dr);Line 226: }Line 227: }Line 228: Line 229: /// Line 230: /// 添加int类型数据缓存Line 231: /// Line 232: /// 分级对象的路径Line 233: /// 缓存的数据Line 234: public virtual void AddObject(string xpath, int intvalue)Line 235: {Line 236: lock (lockHelper)Line 237: {Line 238: if (intvalue.Equals(null))Line 239: {Line 240: AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 241: }Line 242: elseLine 243: {Line 244: AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 245: }Line 246: AddObject(xpath, (object)intvalue);Line 247: }Line 248: }Line 249: Line 250: /// Line 251: /// 添加CustomEditorButtonInfo类型数据缓存Line 252: /// Line 253: /// 分级对象的路径Line 254: /// 缓存的数据Line 255: //public virtual void AddObject(string xpath, CustomEditorButtonInfo[] cuebiArray)Line 256: //{Line 257: // lock (lockHelper)Line 258: // {Line 259: // if (cuebiArray.Length > 0)Line 260: // {Line 261: // AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 262: // }Line 263: // elseLine 264: // {Line 265: // AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 266: // }Line 267: // AddObject(xpath, (object)cuebiArray);Line 268: // }Line 269: //}Line 270: Line 271: /// Line 272: /// 添加GoodsinfoCollection类型数据缓存Line 273: /// Line 274: /// 分级对象的路径Line 275: /// 缓存的数据Line 276: //public virtual void AddObject(string xpath, GoodsinfoCollection goodsinfocoll)Line 277: //{Line 278: // lock (lockHelper)Line 279: // {Line 280: // if (goodsinfocoll.Count > 0)Line 281: // {Line 282: // AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 283: // }Line 284: // elseLine 285: // {Line 286: // AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 287: // }Line 288: // AddObject(xpath, (object)goodsinfocoll);Line 289: // }Line 290: //}Line 291: Line 292: Line 293: /// Line 294: /// 添加字符串数组类型数据缓存Line 295: /// Line 296: /// 分级对象的路径Line 297: /// 缓存的数据Line 298: public virtual void AddObject(string xpath, string[] strArray)Line 299: {Line 300: lock (lockHelper)Line 301: {Line 302: if (strArray.Length > 0)Line 303: {Line 304: AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 305: }Line 306: elseLine 307: {Line 308: AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 309: }Line 310: AddObject(xpath, (object)strArray);Line 311: }Line 312: }Line 313: Line 314: Line 315: /// Line 316: /// 添加userGroupInfoArray类型数据缓存Line 317: /// Line 318: /// 分级对象的路径Line 319: /// 缓存的数据Line 320: //public virtual void AddObject(string xpath, UserGroupInfo[] userGroupInfoArray)Line 321: //{Line 322: // lock (lockHelper)Line 323: // {Line 324: // if (userGroupInfoArray.Length > 0)Line 325: // {Line 326: // AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 327: // }Line 328: // elseLine 329: // {Line 330: // AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 331: // }Line 332: // AddObject(xpath, (object)userGroupInfoArray);Line 333: // }Line 334: //}Line 335: Line 336: Line 337: /// Line 338: /// 添加SmiliesInfo类型数据缓存Line 339: /// Line 340: /// 分级对象的路径Line 341: /// 缓存的数据Line 342: //public virtual void AddObject(string xpath, SmiliesInfo[] smiliesInfoArray)Line 343: //{Line 344: // lock (lockHelper)Line 345: // {Line 346: // if (smiliesInfoArray.Length > 0)Line 347: // {Line 348: // AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 349: // }Line 350: // elseLine 351: // {Line 352: // AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 353: // }Line 354: // AddObject(xpath, (object)smiliesInfoArray);Line 355: // }Line 356: //}Line 357: Line 358: Line 359: /// Line 360: /// 添加ModeratorInfo类型数据缓存Line 361: /// Line 362: /// 分级对象的路径Line 363: /// 缓存的数据Line 364: //public virtual void AddObject(string xpath, ModeratorInfo[] moderatorInfoArray)Line 365: //{Line 366: // lock (lockHelper)Line 367: // {Line 368: // if (moderatorInfoArray.Length > 0)Line 369: // {Line 370: // AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 371: // }Line 372: // elseLine 373: // {Line 374: // AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 375: // }Line 376: // AddObject(xpath, (object)moderatorInfoArray);Line 377: // }Line 378: //}Line 379: Line 380: /// Line 381: /// 添加ForumInfo类型数据缓存Line 382: /// Line 383: /// 分级对象的路径Line 384: /// 缓存的数据Line 385: //public virtual void AddObject(string xpath, ForumInfo[] forumInfoArray)Line 386: //{Line 387: // lock (lockHelper)Line 388: // {Line 389: // if (forumInfoArray.Length > 0)Line 390: // {Line 391: // AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 392: // }Line 393: // elseLine 394: // {Line 395: // AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 396: // }Line 397: // AddObject(xpath, (object)forumInfoArray);Line 398: // }Line 399: //}Line 400: Line 401: Line 402: /// Line 403: /// 添加AdminGroupInfo类型数据缓存Line 404: /// Line 405: /// 分级对象的路径Line 406: /// 缓存的数据Line 407: //public virtual void AddObject(string xpath, AdminGroupInfo[] admingroupinfo)Line 408: //{Line 409: // lock (lockHelper)Line 410: // {Line 411: // if (admingroupinfo.Length > 0)Line 412: // {Line 413: // AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 414: // }Line 415: // elseLine 416: // {Line 417: // AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 418: // }Line 419: // AddObject(xpath, (object)admingroupinfo);Line 420: // }Line 421: //}Line 422: Line 423: /// Line 424: /// 添加SortedList类型数据缓存Line 425: /// Line 426: /// 分级对象的路径Line 427: /// 缓存的数据Line 428: //#if NET1Line 429: // public virtual void AddObject(string xpath, SortedList __sortedlist) Line 430: //#elseLine 431: // public virtual void AddObject(string xpath, Discuz.Common.Generic.SortedList __sortedlist)Line 432: //#endifLine 433: // {Line 434: // lock (lockHelper)Line 435: // {Line 436: // if (__sortedlist.Count > 0)Line 437: // {Line 438: // AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 439: // }Line 440: // elseLine 441: // {Line 442: // AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 443: // }Line 444: // AddObject(xpath, (object)__sortedlist);Line 445: // }Line 446: // }Line 447: Line 448: /// Line 449: /// 添加CollectionBase类型数据缓存Line 450: /// Line 451: /// 分级对象的路径Line 452: /// 缓存的数据Line 453: public virtual void AddObject(string xpath, CollectionBase __collection)Line 454: {Line 455: lock (lockHelper)Line 456: {Line 457: if (__collection.Count > 0)Line 458: {Line 459: AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 460: }Line 461: elseLine 462: {Line 463: AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 464: }Line 465: AddObject(xpath, (object)__collection);Line 466: }Line 467: }Line 468: Line 469: Line 470: /// Line 471: /// 添加ICollection类型数据缓存Line 472: /// Line 473: /// 分级对象的路径Line 474: /// 缓存的数据Line 475: public virtual void AddObject(string xpath, ICollection __collection)Line 476: {Line 477: lock (lockHelper)Line 478: {Line 479: if (__collection.Count > 0)Line 480: {Line 481: AddObject(xpath + "flag", CacheFlag.CacheHaveData);Line 482: }Line 483: elseLine 484: {Line 485: AddObject(xpath + "flag", CacheFlag.CacheNoData);Line 486: }Line 487: AddObject(xpath, (object)__collection);Line 488: }Line 489: }Line 490: Line 491: Line 492: Line 493: /// Line 494: /// 在XML映射文档中的指定路径,加入当前对象信息Line 495: /// Line 496: /// 分级对象的路径 Line 497: /// 被缓存的对象Line 498: public virtual void AddObject(string xpath, object o)Line 499: {Line 500: lock (lockHelper)Line 501: {Line 502: //当缓存到期时间为0或负值,则不再放入缓存Line 503: if (cs.TimeOut <= 0) return;Line 504: Line 505: //整理XPATH表达式信息Line 506: string newXpath = PrepareXpath(xpath);Line 507: int separator = newXpath.LastIndexOf("/");Line 508: //找到相关的组名Line 509: string group = newXpath.Substring(0, separator);Line 510: //找到相关的对象Line 511: string element = newXpath.Substring(separator + 1);Line 512: Line 513: XmlNode groupNode = objectXmlMap.SelectSingleNode(group);Line 514: Line 515: //建立对象的唯一键值, 用以映射XML和缓存对象的键Line 516: string objectId = "";Line 517: Line 518: XmlNode node = objectXmlMap.SelectSingleNode(PrepareXpath(xpath));Line 519: if (node != null)Line 520: {Line 521: objectId = node.Attributes["objectId"].Value;Line 522: }Line 523: Line 524: if (objectId == "")Line 525: {Line 526: groupNode = CreateNode(group);Line 527: objectId = Guid.NewGuid().ToString();Line 528: //建立新元素和一个属性 for this perticular objectLine 529: XmlElement objectElement = objectXmlMap.OwnerDocument.CreateElement(element);Line 530: XmlAttribute objectAttribute = objectXmlMap.OwnerDocument.CreateAttribute("objectId");Line 531: objectAttribute.Value = objectId;Line 532: objectElement.Attributes.Append(objectAttribute);Line 533: //为XML文档建立新元素Line 534: groupNode.AppendChild(objectElement);Line 535: }Line 536: elseLine 537: {Line 538: //建立新元素和一个属性 for this perticular objectLine 539: XmlElement objectElement = objectXmlMap.OwnerDocument.CreateElement(element);Line 540: XmlAttribute objectAttribute = objectXmlMap.OwnerDocument.CreateAttribute("objectId");Line 541: objectAttribute.Value = objectId;Line 542: objectElement.Attributes.Append(objectAttribute);Line 543: //为XML文档建立新元素Line 544: groupNode.ReplaceChild(objectElement, node);Line 545: }Line 546: Line 547: //向缓存加入新的对象Line 548: cs.AddObject(objectId, o);Line 549: }Line 550: }Line 551: Line 552: Line 553: Line 554: /// Line 555: /// 在XML映射文档中的指定路径,加入当前对象信息Line 556: /// Line 557: /// 分级对象的路径 Line 558: /// 被缓存的对象Line 559: public virtual void AddObject(string xpath, object o, string[] files)Line 560: {Line 561: xpath = xpath.Replace(" ", "_SPACE_"); //如果xpath中出现空格,则将空格替换为_SPACE_Line 562: lock (lockHelper)Line 563: {Line 564: //当缓存到期时间为0或负值,则不再放入缓存Line 565: if (cs.TimeOut <= 0) return;Line 566: Line 567: //整理XPATH表达式信息Line 568: string newXpath = PrepareXpath(xpath);Line 569: int separator = newXpath.LastIndexOf("/");Line 570: //找到相关的组名Line 571: string group = newXpath.Substring(0, separator);Line 572: //找到相关的对象Line 573: string element = newXpath.Substring(separator + 1);Line 574: Line 575: XmlNode groupNode = objectXmlMap.SelectSingleNode(group);Line 576: //建立对象的唯一键值, 用以映射XML和缓存对象的键Line 577: string objectId = "";Line 578: Line 579: XmlNode node = objectXmlMap.SelectSingleNode(PrepareXpath(xpath));Line 580: if (node != null)Line 581: {Line 582: objectId = node.Attributes["objectId"].Value;Line 583: }Line 584: if (objectId == "")Line 585: {Line 586: groupNode = CreateNode(group);Line 587: objectId = Guid.NewGuid().ToString();Line 588: //建立新元素和一个属性 for this perticular objectLine 589: XmlElement objectElement = objectXmlMap.OwnerDocument.CreateElement(element);Line 590: XmlAttribute objectAttribute = objectXmlMap.OwnerDocument.CreateAttribute("objectId");Line 591: objectAttribute.Value = objectId;Line 592: objectElement.Attributes.Append(objectAttribute);Line 593: //为XML文档建立新元素Line 594: groupNode.AppendChild(objectElement);Line 595: }Line 596: elseLine 597: {Line 598: //建立新元素和一个属性 for this perticular objectLine 599: XmlElement objectElement = objectXmlMap.OwnerDocument.CreateElement(element);Line 600: XmlAttribute objectAttribute = objectXmlMap.OwnerDocument.CreateAttribute("objectId");Line 601: objectAttribute.Value = objectId;Line 602: objectElement.Attributes.Append(objectAttribute);Line 603: //为XML文档建立新元素Line 604: groupNode.ReplaceChild(objectElement, node);Line 605: }Line 606: Line 607: //向缓存加入新的对象Line 608: cs.AddObjectWithFileChange(objectId, o, files);Line 609: }Line 610: }Line 611: Line 612: Line 613: Line 614: Line 615: Line 616: /// Line 617: /// 通过分级地址返回单值路径上被缓存的对象Line 618: /// Line 619: /// 分级对象的路径Line 620: /// 被缓存的对象Line 621: public virtual object RetrieveSingleObject(string xpath)Line 622: {Line 623: xpath = xpath.Replace(" ", "_SPACE_"); //如果xpath中出现空格,则将空格替换为_SPACE_Line 624: object o = null;Line 625: XmlNode node = objectXmlMap.SelectSingleNode(PrepareXpath(xpath + "/Single"));Line 626: //如果分级地址存在,则返回,否则为NULLLine 627: if (node != null)Line 628: {Line 629: string objectId = node.Attributes["objectId"].Value;Line 630: //通过缓存策略返回对象Line 631: o = cs.RetrieveObject(objectId);Line 632: }Line 633: return o;Line 634: }Line 635: Line 636: Line 637: /// Line 638: /// 返回当前路径的多值域部分Line 639: /// Line 640: /// 分级对象的路径Line 641: /// Line 642: public virtual object[] RetrieveMultiObjects(string xpath)Line 643: {Line 644: return RetrieveObjectList(xpath + "/Multi");Line 645: }Line 646: Line 647: Line 648: Line 649: /// Line 650: /// 返回指定XML路径下的数据项Line 651: /// Line 652: /// 分级对象的路径Line 653: /// Line 654: public virtual object RetrieveOriginObject(string xpath)Line 655: {Line 656: XmlNode node = objectXmlMap.SelectSingleNode(PrepareXpath(xpath));Line 657: if (node != null)Line 658: {Line 659: string objectId = node.Attributes["objectId"].Value;Line 660: Line 661: return cs.RetrieveObject(objectId);Line 662: }Line 663: return null;Line 664: }Line 665: Line 666: Line 667: /// Line 668: /// 取得指定XML路径下的数据项Line 669: /// Line 670: /// 分级对象的路径Line 671: /// Line 672: public virtual object RetrieveObject(string xpath)Line 673: {Line 674: tryLine 675: {Line 676: object cacheObject = RetrieveOriginObject(xpath);Line 677: Line 678: CacheFlag cf = (CacheFlag)RetrieveOriginObject(xpath + "flag");Line 679: Line 680: Line 681: //当标志位中有数据时Line 682: if (cf == CacheFlag.CacheHaveData)Line 683: {Line 684: string otype = cacheObject.GetType().Name.ToString();Line 685: Line 686: //当缓存类型是数据表类型时Line 687: if (otype.IndexOf("Table") > 0)Line 688: {Line 689: System.Data.DataTable dt = cacheObject as DataTable;Line 690: if ((dt == null) || (dt.Rows.Count == 0))Line 691: {Line 692: return null;Line 693: }Line 694: elseLine 695: {Line 696: return cacheObject;Line 697: }Line 698: }Line 699: Line 700: //当缓存类型是CustomEditorButtonInfo[],string[],UserGroupInfo[],ModeratorInfo[],SmiliesInfo[],ForumInfo[]Line 701: if (otype.IndexOf("[]") > 0)Line 702: {Line 703: if (((Array)cacheObject).Length == 0)Line 704: {Line 705: return null;Line 706: }Line 707: elseLine 708: {Line 709: return cacheObject;Line 710: }Line 711: }Line 712: Line 713: //当缓存类型是CustomEditorButtonInfo[],string[],UserGroupInfo[],ModeratorInfo[],SmiliesInfo[],ForumInfo[]Line 714: if (otype.IndexOf("Collection") > 0)Line 715: {Line 716: if (((CollectionBase)cacheObject).Count == 0)Line 717: {Line 718: return null;Line 719: }Line 720: elseLine 721: {Line 722: return cacheObject;Line 723: }Line 724: }Line 725: Line 726: //当缓存类型是字符串类型时Line 727: if (otype == "String")Line 728: {Line 729: if (cacheObject.ToString() == "")Line 730: {Line 731: return null;Line 732: }Line 733: elseLine 734: {Line 735: return cacheObject;Line 736: }Line 737: }Line 738: Line 739: //当缓存类型是数据行Line 740: if (otype.IndexOf("Row") >= 0)Line 741: {Line 742: if (cacheObject == null)Line 743: {Line 744: return null;Line 745: }Line 746: elseLine 747: {Line 748: return cacheObject;Line 749: }Line 750: }Line 751: Line 752: //当缓存类型是intLine 753: if (otype.IndexOf("Int") >= 0)Line 754: {Line 755: if (((int)cacheObject).Equals(null))Line 756: {Line 757: return null;Line 758: }Line 759: elseLine 760: {Line 761: return cacheObject;Line 762: }Line 763: }Line 764: Line 765: //当缓存类型是SortedListLine 766: // if (otype.IndexOf("SortedList") >= 0)Line 767: // {Line 768: //#if NET1Line 769: // if(((SortedList)cacheObject).Count==0)Line 770: //#elseLine 771: // if (((Discuz.Common.Generic.SortedList)cacheObject).Count == 0)Line 772: //#endifLine 773: // {Line 774: // return null;Line 775: // }Line 776: // elseLine 777: // {Line 778: // return cacheObject;Line 779: // }Line 780: // }Line 781: Line 782: //当缓存类型是CollectionBaseLine 783: if (otype.IndexOf("CollectionBase") >= 0)Line 784: {Line 785: if (((CollectionBase)cacheObject).Count == 0)Line 786: {Line 787: return null;Line 788: }Line 789: elseLine 790: {Line 791: return cacheObject;Line 792: }Line 793: }Line 794: }Line 795: Line 796: return cacheObject;Line 797: }Line 798: catchLine 799: {Line 800: return null;Line 801: }Line 802: }Line 803: Line 804: Line 805: /// Line 806: /// 返回一个当前路径下的通过AddObject()方法加入的对象列表Line 807: /// Line 808: /// 分级地址Line 809: /// 返回对象数组Line 810: public virtual object[] RetrieveObjectList(string xpath)Line 811: {Line 812: XmlNode group = objectXmlMap.SelectSingleNode(PrepareXpath(xpath));Line 813: XmlNodeList results = group.SelectNodes(PrepareXpath(xpath) + "/*[@objectId]");Line 814: ArrayList objects = new ArrayList();Line 815: string objectId = null;Line 816: //搜索节点并通过缓存策略链接在对象列表中的对象到存储的对象Line 817: foreach (XmlNode result in results)Line 818: {Line 819: objectId = result.Attributes["objectId"].Value;Line 820: objects.Add(cs.RetrieveObject(objectId));Line 821: }Line 822: //转换 ArrayList 为 object[]Line 823: return (object[])objects.ToArray(typeof(Object));Line 824: }Line 825: Line 826: Line 827: /// Line 828: /// 通过指定的路径删除缓存中的单值部分对象Line 829: /// Line 830: /// 分级对象的路径Line 831: public virtual void RemoveSingleObject(string xpath)Line 832: {Line 833: tryLine 834: {Line 835: //去掉当前键的子节点部分Line 836: XmlNode result = objectXmlMap.SelectSingleNode(PrepareXpath(xpath + "/Single/"));Line 837: //检查路径是否指向一个组或一个被缓存的实例元素Line 838: if (result.HasChildNodes)Line 839: {Line 840: //删除所有对象和子结点的信息Line 841: XmlNodeList objects = result.SelectNodes("*[@objectId]");Line 842: string objectId = "";Line 843: foreach (XmlNode node in objects)Line 844: {Line 845: objectId = node.Attributes["objectId"].Value;Line 846: node.ParentNode.RemoveChild(node);Line 847: //删除对象Line 848: cs.RemoveObject(objectId);Line 849: }Line 850: }Line 851: elseLine 852: {Line 853: //删除元素结点和相关的对象Line 854: string objectId = result.Attributes["objectId"].Value;Line 855: result.ParentNode.RemoveChild(result);Line 856: cs.RemoveObject(objectId);Line 857: }Line 858: }Line 859: catchLine 860: { //如出错误表明当前路径不存在Line 861: }Line 862: }Line 863: Line 864: /// Line 865: /// 通过指定的路径删除缓存中的多值部分对象Line 866: /// Line 867: /// 分级对象的路径Line 868: public virtual void RemoveMultiObjects(string xpath)Line 869: {Line 870: tryLine 871: {Line 872: XmlNode result = objectXmlMap.SelectSingleNode(PrepareXpath(xpath + "/Multi/"));Line 873: //检查路径是否指向一个组或一个被缓存的实例元素Line 874: if (result.HasChildNodes)Line 875: {Line 876: //删除所有对象和子结点的信息Line 877: XmlNodeList objects = result.SelectNodes("*[@objectId]");Line 878: string objectId = "";Line 879: foreach (XmlNode node in objects)Line 880: {Line 881: objectId = node.Attributes["objectId"].Value;Line 882: node.ParentNode.RemoveChild(node);Line 883: //删除对象Line 884: cs.RemoveObject(objectId);Line 885: }Line 886: }Line 887: elseLine 888: {Line 889: //删除元素结点和相关的对象Line 890: string objectId = result.Attributes["objectId"].Value;Line 891: result.ParentNode.RemoveChild(result);Line 892: cs.RemoveObject(objectId);Line 893: }Line 894: }Line 895: catchLine 896: { //如出错误表明当前路径不存在Line 897: }Line 898: }Line 899: Line 900: Line 901: /// Line 902: /// 通过指定的路径删除缓存中的对象Line 903: /// Line 904: /// 分级对象的路径Line 905: public virtual void RemoveObject(string xpath)Line 906: {Line 907: lock (lockHelper)Line 908: {Line 909: RemoveObject(xpath, true);Line 910: }Line 911: }Line 912: Line 913: Line 914: /// Line 915: /// 通过指定的路径删除缓存中的对象Line 916: /// Line 917: /// 分级对象的路径Line 918: /// 是否写入文件Line 919: public virtual void RemoveObject(string xpath, bool writeconfig)Line 920: {Line 921: lock (lockHelper)Line 922: {Line 923: tryLine 924: {Line 925: if (writeconfig)Line 926: {Line 927: CachesFileMonitor.UpdateCacheItem(xpath);Line 928: }Line 929: Line 930: XmlNode result = objectXmlMap.SelectSingleNode(PrepareXpath(xpath));Line 931: //检查路径是否指向一个组或一个被缓存的实例元素Line 932: if (result.HasChildNodes)Line 933: {Line 934: //删除所有对象和子结点的信息Line 935: XmlNodeList objects = result.SelectNodes("*[@objectId]");Line 936: string objectId = "";Line 937: foreach (XmlNode node in objects)Line 938: {Line 939: objectId = node.Attributes["objectId"].Value;Line 940: node.ParentNode.RemoveChild(node);Line 941: //删除对象Line 942: cs.RemoveObject(objectId);Line 943: }Line 944: }Line 945: elseLine 946: {Line 947: //删除元素结点和相关的对象Line 948: string objectId = result.Attributes["objectId"].Value;Line 949: result.ParentNode.RemoveChild(result);Line 950: cs.RemoveObject(objectId);Line 951: }Line 952: Line 953: //检查并移除相应的缓存项Line 954: Line 955: }Line 956: catchLine 957: { //如出错误表明当前路径不存在Line 958: }Line 959: Line 960: }Line 961: }Line 962: Line 963: /// Line 964: /// 对象树形分级对象节点Line 965: /// Line 966: /// 分级路径 locationLine 967: /// Line 968: private XmlNode CreateNode(string xpath)Line 969: {Line 970: lock (lockHelper)Line 971: {Line 972: string[] xpathArray = xpath.Split('/');Line 973: string root = "";Line 974: XmlNode parentNode = objectXmlMap;Line 975: //建立相关节点Line 976: for (int i = 1; i < xpathArray.Length; i++)Line 977: {Line 978: XmlNode node = objectXmlMap.SelectSingleNode(root + "/" + xpathArray[i]);Line 979: // 如果当前路径不存在则建立,否则设置当前路径到它的子路径上Line 980: if (node == null)Line 981: {Line 982: XmlElement newElement = objectXmlMap.OwnerDocument.CreateElement(xpathArray[i]);Line 983: parentNode.AppendChild(newElement);Line 984: }Line 985: //设置低一级的路径Line 986: root = root + "/" + xpathArray[i];Line 987: parentNode = objectXmlMap.SelectSingleNode(root);Line 988: }Line 989: return parentNode;Line 990: }Line 991: }Line 992: Line 993: /// Line 994: /// 整理 xpath 确保 '/'被删除 is removedLine 995: /// Line 996: /// 分级地址Line 997: /// Line 998: private string PrepareXpath(string xpath)Line 999: {Line 1000: lock (lockHelper)Line 1001: {Line 1002: string[] xpathArray = xpath.Split('/');Line 1003: xpath = "/Cache";Line 1004: foreach (string s in xpathArray)Line 1005: {Line 1006: if (s != "")Line 1007: {Line 1008: xpath = xpath + "/" + s;Line 1009: }Line 1010: }Line 1011: return xpath;Line 1012: }Line 1013: }Line 1014: Line 1015: /// Line 1016: /// 加载指定的缓存策略Line 1017: /// Line 1018: /// Line 1019: public void LoadCacheStrategy(ICacheStrategy ics)Line 1020: {Line 1021: lock (lockHelper)Line 1022: {Line 1023: cs = ics;Line 1024: }Line 1025: }Line 1026: Line 1027: /// Line 1028: /// 加载默认的缓存策略Line 1029: /// Line 1030: public void LoadDefaultCacheStrategy()Line 1031: {Line 1032: lock (lockHelper)Line 1033: {Line 1034: cs = new Util_Cache();Line 1035: }Line 1036: }Line 1037: Line 1038: }Line 1039: Line 1040: /// Line 1041: /// 缓存文件监视器类Line 1042: /// Line 1043: public class CachesFileMonitorLine 1044: {Line 1045: private static string path = "";//Utils.GetMapPath(BaseConfigs.GetForumPath + "cache/cache.config");Line 1046: Line 1047: /// Line 1048: /// 程序刚加载时cache.config文件修改时间Line 1049: /// Line 1050: private static DateTime cachefileoldchange;Line 1051: Line 1052: /// Line 1053: /// 最新general.config文件修改时间Line 1054: /// Line 1055: private static DateTime cachefilenewchange;Line 1056: Line 1057: Line 1058: Line 1059: private static object cachelockHelper = new object();Line 1060: Line 1061: /// Line 1062: /// 静态构造函数Line 1063: /// Line 1064: static CachesFileMonitor()Line 1065: {Line 1066: if (!Utils.FileExists(path))Line 1067: {Line 1068: string content = "\r\n";Line 1069: content += "\r\n\r\n";Line 1070: Line 1071: using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))Line 1072: {Line 1073: Byte[] info = System.Text.Encoding.UTF8.GetBytes(content);Line 1074: fs.Write(info, 0, info.Length);Line 1075: fs.Close();Line 1076: }Line 1077: }Line 1078: cachefileoldchange = System.IO.File.GetLastWriteTime(path);Line 1079: }Line 1080: Line 1081: /// Line 1082: /// 检查和移除缓存Line 1083: /// Line 1084: /// Line 1085: /// Line 1086: public static WebCache CheckAndRemoveCache(WebCache instance)//Line 1087: {Line 1088: //当程序运行中cache.config发生变化时则对缓存对象做删除的操作Line 1089: cachefilenewchange = System.IO.File.GetLastWriteTime(path);Line 1090: if (cachefileoldchange != cachefilenewchange)Line 1091: {Line 1092: lock (cachelockHelper)Line 1093: {Line 1094: if (cachefileoldchange != cachefilenewchange)Line 1095: {Line 1096: //当有要清除的项时Line 1097: DataSet dsSrc = new DataSet();Line 1098: dsSrc.ReadXml(path);Line 1099: foreach (DataRow dr in dsSrc.Tables[0].Rows)Line 1100: {Line 1101: if (dr["xpath"].ToString().Trim() != "")Line 1102: {Line 1103: DateTime removedatetime = DateTime.Now;Line 1104: tryLine 1105: {Line 1106: removedatetime = Convert.ToDateTime(dr["removedatetime"].ToString().Trim());Line 1107: }Line 1108: catchLine 1109: {Line 1110: ;Line 1111: }Line 1112: Line 1113: if (removedatetime > cachefilenewchange.AddSeconds(-2))Line 1114: {Line 1115: string xpath = dr["xpath"].ToString().Trim();Line 1116: instance.RemoveObject(xpath, false);Line 1117: }Line 1118: }Line 1119: }Line 1120: Line 1121: cachefileoldchange = cachefilenewchange;Line 1122: Line 1123: dsSrc.Dispose();Line 1124: }Line 1125: }Line 1126: }Line 1127: return instance;Line 1128: }Line 1129: Line 1130: /// Line 1131: /// 更新或插入相应的缓存路径Line 1132: /// Line 1133: /// Line 1134: public static void UpdateCacheItem(string xpath)Line 1135: {Line 1136: DataTable dt = new DataTable("cachetableremove");Line 1137: dt.Columns.Add("xpath", System.Type.GetType("System.String"));Line 1138: dt.Columns.Add("removedatetime", System.Type.GetType("System.DateTime"));Line 1139: Line 1140: //当有要清除的项时Line 1141: DataSet dsSrc = new DataSet();Line 1142: lock (cachelockHelper)Line 1143: {Line 1144: dsSrc.ReadXml(path);Line 1145: Line 1146: bool nohasone = true;Line 1147: foreach (DataRow dr in dsSrc.Tables[0].Rows)Line 1148: {Line 1149: if (dr["xpath"].ToString().Trim() == xpath)Line 1150: {Line 1151: dr["removedatetime"] = DateTime.Now.ToString();Line 1152: nohasone = false;Line 1153: break;Line 1154: }Line 1155: }Line 1156: Line 1157: if (nohasone)Line 1158: {Line 1159: DataRow dr = dsSrc.Tables[0].NewRow();Line 1160: dr["xpath"] = xpath;Line 1161: dr["removedatetime"] = DateTime.Now.ToString();Line 1162: dsSrc.Tables[0].Rows.Add(dr);Line 1163: }Line 1164: Line 1165: dsSrc.WriteXml(path);Line 1166: dsSrc.Dispose();Line 1167: }Line 1168: }Line 1169: }Line 1170: Line 1171: }Line 1172:
|