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.Common
Line 12: {
Line 13: /// <summary>
Line 14: /// Discuz!NT缓存类
Line 15: /// 对Discuz!NT论坛缓存进行全局控制管理
Line 16: /// </summary>
Line 17: public class WebCache
Line 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: /// <summary>
Line 28: /// 构造函数
Line 29: /// </summary>
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: /// <summary>
Line 53: /// 单体模式返回当前类的实例
Line 54: /// </summary>
Line 55: /// <returns></returns>
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: /// <summary>
Line 74: /// 添加单值路径,在XML映射文档中加入当前对象信息
Line 75: /// </summary>
Line 76: /// <param name="xpath">分级对象的路径 </param>
Line 77: /// <param name="o">被缓存的对象</param>
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: /// <summary>
Line 85: /// 添加单值路径,在XML映射文档中加入当前对象信息
Line 86: /// </summary>
Line 87: /// <param name="xpath">分级对象的路径 </param>
Line 88: /// <param name="o">被缓存的对象</param>
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: /// <summary>
Line 96: /// 添加多点路径,在当前的键上插入多值的域
Line 97: /// </summary>
Line 98: /// <param name="xpath">键值</param>
Line 99: /// <param name="objValue">插入的数组</param>
Line 100: /// <returns></returns>
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: /// <summary>
Line 123: /// 添加多点路径,在当前的键上插入多值的域
Line 124: /// </summary>
Line 125: /// <param name="xpath">键值</param>
Line 126: /// <param name="objValue">插入的数组</param>
Line 127: /// <returns></returns>
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: /// <summary>
Line 146: /// 缓存标志位类型
Line 147: /// </summary>
Line 148: private enum CacheFlag
Line 149: {
Line 150: /// <summary>
Line 151: /// 缓存失败
Line 152: /// </summary>
Line 153: Cachefails,
Line 154:
Line 155: /// <summary>
Line 156: /// 缓存中无数据
Line 157: /// </summary>
Line 158: CacheNoData,
Line 159:
Line 160: /// <summary>
Line 161: /// 缓存中有数据
Line 162: /// </summary>
Line 163: CacheHaveData
Line 164: }
Line 165:
Line 166: /// <summary>
Line 167: /// 添加表类型数据缓存
Line 168: /// </summary>
Line 169: /// <param name="xpath">分级对象的路径</param>
Line 170: /// <param name="dt">缓存的数据</param>
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: else
Line 180: {
Line 181: AddObject(xpath + "flag", CacheFlag.CacheNoData);
Line 182: }
Line 183: AddObject(xpath, (object)dt);
Line 184: }
Line 185: }
Line 186:
Line 187: /// <summary>
Line 188: /// 添加字符串类型数据缓存
Line 189: /// </summary>
Line 190: /// <param name="xpath">分级对象的路径</param>
Line 191: /// <param name="str">缓存的数据</param>
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: else
Line 201: {
Line 202: AddObject(xpath + "flag", CacheFlag.CacheNoData);
Line 203: }
Line 204: AddObject(xpath, (object)str);
Line 205: }
Line 206: }
Line 207:
Line 208: /// <summary>
Line 209: /// 添加数据行类型数据缓存
Line 210: /// </summary>
Line 211: /// <param name="xpath">分级对象的路径</param>
Line 212: /// <param name="dr">缓存的数据</param>
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: else
Line 222: {
Line 223: AddObject(xpath + "flag", CacheFlag.CacheNoData);
Line 224: }
Line 225: AddObject(xpath, (object)dr);
Line 226: }
Line 227: }
Line 228:
Line 229: /// <summary>
Line 230: /// 添加int类型数据缓存
Line 231: /// </summary>
Line 232: /// <param name="xpath">分级对象的路径</param>
Line 233: /// <param name="intvalue">缓存的数据</param>
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: else
Line 243: {
Line 244: AddObject(xpath + "flag", CacheFlag.CacheNoData);
Line 245: }
Line 246: AddObject(xpath, (object)intvalue);
Line 247: }
Line 248: }
Line 249:
Line 250: /// <summary>
Line 251: /// 添加CustomEditorButtonInfo类型数据缓存
Line 252: /// </summary>
Line 253: /// <param name="xpath">分级对象的路径</param>
Line 254: /// <param name="cuebiArray">缓存的数据</param>
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: // else
Line 264: // {
Line 265: // AddObject(xpath + "flag", CacheFlag.CacheNoData);
Line 266: // }
Line 267: // AddObject(xpath, (object)cuebiArray);
Line 268: // }
Line 269: //}
Line 270:
Line 271: /// <summary>
Line 272: /// 添加GoodsinfoCollection类型数据缓存
Line 273: /// </summary>
Line 274: /// <param name="xpath">分级对象的路径</param>
Line 275: /// <param name="cuebiArray">缓存的数据</param>
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: // else
Line 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: /// <summary>
Line 294: /// 添加字符串数组类型数据缓存
Line 295: /// </summary>
Line 296: /// <param name="xpath">分级对象的路径</param>
Line 297: /// <param name="strArray">缓存的数据</param>
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: else
Line 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: /// <summary>
Line 316: /// 添加userGroupInfoArray类型数据缓存
Line 317: /// </summary>
Line 318: /// <param name="xpath">分级对象的路径</param>
Line 319: /// <param name="userGroupInfoArray">缓存的数据</param>
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: // else
Line 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: /// <summary>
Line 338: /// 添加SmiliesInfo类型数据缓存
Line 339: /// </summary>
Line 340: /// <param name="xpath">分级对象的路径</param>
Line 341: /// <param name="smiliesInfoArray">缓存的数据</param>
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: // else
Line 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: /// <summary>
Line 360: /// 添加ModeratorInfo类型数据缓存
Line 361: /// </summary>
Line 362: /// <param name="xpath">分级对象的路径</param>
Line 363: /// <param name="moderatorInfoArray">缓存的数据</param>
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: // else
Line 373: // {
Line 374: // AddObject(xpath + "flag", CacheFlag.CacheNoData);
Line 375: // }
Line 376: // AddObject(xpath, (object)moderatorInfoArray);
Line 377: // }
Line 378: //}
Line 379:
Line 380: /// <summary>
Line 381: /// 添加ForumInfo类型数据缓存
Line 382: /// </summary>
Line 383: /// <param name="xpath">分级对象的路径</param>
Line 384: /// <param name="forumInfoArray">缓存的数据</param>
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: // else
Line 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: /// <summary>
Line 403: /// 添加AdminGroupInfo类型数据缓存
Line 404: /// </summary>
Line 405: /// <param name="xpath">分级对象的路径</param>
Line 406: /// <param name="admingroupinfo">缓存的数据</param>
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: // else
Line 416: // {
Line 417: // AddObject(xpath + "flag", CacheFlag.CacheNoData);
Line 418: // }
Line 419: // AddObject(xpath, (object)admingroupinfo);
Line 420: // }
Line 421: //}
Line 422:
Line 423: /// <summary>
Line 424: /// 添加SortedList类型数据缓存
Line 425: /// </summary>
Line 426: /// <param name="xpath">分级对象的路径</param>
Line 427: /// <param name="__sortedlist">缓存的数据</param>
Line 428: //#if NET1
Line 429: // public virtual void AddObject(string xpath, SortedList __sortedlist)
Line 430: //#else
Line 431: // public virtual void AddObject(string xpath, Discuz.Common.Generic.SortedList<int, object> __sortedlist)
Line 432: //#endif
Line 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: // else
Line 441: // {
Line 442: // AddObject(xpath + "flag", CacheFlag.CacheNoData);
Line 443: // }
Line 444: // AddObject(xpath, (object)__sortedlist);
Line 445: // }
Line 446: // }
Line 447:
Line 448: /// <summary>
Line 449: /// 添加CollectionBase类型数据缓存
Line 450: /// </summary>
Line 451: /// <param name="xpath">分级对象的路径</param>
Line 452: /// <param name="__collection">缓存的数据</param>
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: else
Line 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: /// <summary>
Line 471: /// 添加ICollection类型数据缓存
Line 472: /// </summary>
Line 473: /// <param name="xpath">分级对象的路径</param>
Line 474: /// <param name="__collection">缓存的数据</param>
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: else
Line 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: /// <summary>
Line 494: /// 在XML映射文档中的指定路径,加入当前对象信息
Line 495: /// </summary>
Line 496: /// <param name="xpath">分级对象的路径 </param>
Line 497: /// <param name="o">被缓存的对象</param>
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 object
Line 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: else
Line 537: {
Line 538: //建立新元素和一个属性 for this perticular object
Line 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: /// <summary>
Line 555: /// 在XML映射文档中的指定路径,加入当前对象信息
Line 556: /// </summary>
Line 557: /// <param name="xpath">分级对象的路径 </param>
Line 558: /// <param name="o">被缓存的对象</param>
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 object
Line 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: else
Line 597: {
Line 598: //建立新元素和一个属性 for this perticular object
Line 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: /// <summary>
Line 617: /// 通过分级地址返回单值路径上被缓存的对象
Line 618: /// </summary>
Line 619: /// <param name="xpath">分级对象的路径</param>
Line 620: /// <returns>被缓存的对象</returns>
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: //如果分级地址存在,则返回,否则为NULL
Line 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: /// <summary>
Line 638: /// 返回当前路径的多值域部分
Line 639: /// </summary>
Line 640: /// <param name="xpath">分级对象的路径</param>
Line 641: /// <returns></returns>
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: /// <summary>
Line 650: /// 返回指定XML路径下的数据项
Line 651: /// </summary>
Line 652: /// <param name="xpath">分级对象的路径</param>
Line 653: /// <returns></returns>
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: /// <summary>
Line 668: /// 取得指定XML路径下的数据项
Line 669: /// </summary>
Line 670: /// <param name="xpath">分级对象的路径</param>
Line 671: /// <returns></returns>
Line 672: public virtual object RetrieveObject(string xpath)
Line 673: {
Line 674: try
Line 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: else
Line 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: else
Line 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: else
Line 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: else
Line 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: else
Line 747: {
Line 748: return cacheObject;
Line 749: }
Line 750: }
Line 751:
Line 752: //当缓存类型是int
Line 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: else
Line 760: {
Line 761: return cacheObject;
Line 762: }
Line 763: }
Line 764:
Line 765: //当缓存类型是SortedList
Line 766: // if (otype.IndexOf("SortedList") >= 0)
Line 767: // {
Line 768: //#if NET1
Line 769: // if(((SortedList)cacheObject).Count==0)
Line 770: //#else
Line 771: // if (((Discuz.Common.Generic.SortedList<int, object>)cacheObject).Count == 0)
Line 772: //#endif
Line 773: // {
Line 774: // return null;
Line 775: // }
Line 776: // else
Line 777: // {
Line 778: // return cacheObject;
Line 779: // }
Line 780: // }
Line 781:
Line 782: //当缓存类型是CollectionBase
Line 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: else
Line 790: {
Line 791: return cacheObject;
Line 792: }
Line 793: }
Line 794: }
Line 795:
Line 796: return cacheObject;
Line 797: }
Line 798: catch
Line 799: {
Line 800: return null;
Line 801: }
Line 802: }
Line 803:
Line 804:
Line 805: /// <summary>
Line 806: /// 返回一个当前路径下的通过AddObject()方法加入的对象列表
Line 807: /// </summary>
Line 808: /// <param name="xpath">分级地址</param>
Line 809: /// <returns>返回对象数组</returns>
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: /// <summary>
Line 828: /// 通过指定的路径删除缓存中的单值部分对象
Line 829: /// </summary>
Line 830: /// <param name="xpath">分级对象的路径</param>
Line 831: public virtual void RemoveSingleObject(string xpath)
Line 832: {
Line 833: try
Line 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: else
Line 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: catch
Line 860: { //如出错误表明当前路径不存在
Line 861: }
Line 862: }
Line 863:
Line 864: /// <summary>
Line 865: /// 通过指定的路径删除缓存中的多值部分对象
Line 866: /// </summary>
Line 867: /// <param name="xpath">分级对象的路径</param>
Line 868: public virtual void RemoveMultiObjects(string xpath)
Line 869: {
Line 870: try
Line 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: else
Line 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: catch
Line 896: { //如出错误表明当前路径不存在
Line 897: }
Line 898: }
Line 899:
Line 900:
Line 901: /// <summary>
Line 902: /// 通过指定的路径删除缓存中的对象
Line 903: /// </summary>
Line 904: /// <param name="xpath">分级对象的路径</param>
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: /// <summary>
Line 915: /// 通过指定的路径删除缓存中的对象
Line 916: /// </summary>
Line 917: /// <param name="xpath">分级对象的路径</param>
Line 918: /// <param name="writeconfig">是否写入文件</param>
Line 919: public virtual void RemoveObject(string xpath, bool writeconfig)
Line 920: {
Line 921: lock (lockHelper)
Line 922: {
Line 923: try
Line 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: else
Line 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: catch
Line 957: { //如出错误表明当前路径不存在
Line 958: }
Line 959:
Line 960: }
Line 961: }
Line 962:
Line 963: /// <summary>
Line 964: /// 对象树形分级对象节点
Line 965: /// </summary>
Line 966: /// <param name="xpath">分级路径 location</param>
Line 967: /// <returns></returns>
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: /// <summary>
Line 994: /// 整理 xpath 确保 '/'被删除 is removed
Line 995: /// </summary>
Line 996: /// <param name="xpath">分级地址</param>
Line 997: /// <returns></returns>
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: /// <summary>
Line 1016: /// 加载指定的缓存策略
Line 1017: /// </summary>
Line 1018: /// <param name="ics"></param>
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: /// <summary>
Line 1028: /// 加载默认的缓存策略
Line 1029: /// </summary>
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: /// <summary>
Line 1041: /// 缓存文件监视器类
Line 1042: /// </summary>
Line 1043: public class CachesFileMonitor
Line 1044: {
Line 1045: private static string path = "";//Utils.GetMapPath(BaseConfigs.GetForumPath + "cache/cache.config");
Line 1046:
Line 1047: /// <summary>
Line 1048: /// 程序刚加载时cache.config文件修改时间
Line 1049: /// </summary>
Line 1050: private static DateTime cachefileoldchange;
Line 1051:
Line 1052: /// <summary>
Line 1053: /// 最新general.config文件修改时间
Line 1054: /// </summary>
Line 1055: private static DateTime cachefilenewchange;
Line 1056:
Line 1057:
Line 1058:
Line 1059: private static object cachelockHelper = new object();
Line 1060:
Line 1061: /// <summary>
Line 1062: /// 静态构造函数
Line 1063: /// </summary>
Line 1064: static CachesFileMonitor()
Line 1065: {
Line 1066: if (!Utils.FileExists(path))
Line 1067: {
Line 1068: string content = "<?xml version=\"1.0\" standalone=\"yes\"?>\r\n";
Line 1069: content += "<cachetableremove>\r\n<table1 xpath=\"example\" removedatetime=\"2007-1-9 17:36:23\" />\r\n</cachetableremove>";
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: /// <summary>
Line 1082: /// 检查和移除缓存
Line 1083: /// </summary>
Line 1084: /// <param name="instance"></param>
Line 1085: /// <returns></returns>
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: try
Line 1105: {
Line 1106: removedatetime = Convert.ToDateTime(dr["removedatetime"].ToString().Trim());
Line 1107: }
Line 1108: catch
Line 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: /// <summary>
Line 1131: /// 更新或插入相应的缓存路径
Line 1132: /// </summary>
Line 1133: /// <param name="xpath"></param>
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:
|