/// <summary> /// This is overridden to save the updated cache information and dispose of target information /// </summary> /// <param name="disposing">Pass true to dispose of the managed and unmanaged resources or false to just /// dispose of the unmanaged resources.</param> protected override void Dispose(bool disposing) { if (disposing && this.UrlResolver != null && !this.UrlResolver.IsDisposed) { this.UpdateUrlCache(); this.UrlResolver.Dispose(); this.UrlResolver = null; } if (targets != null) { targets.Dispose(); foreach (var td in sharedTargets.Values.ToList()) { if (td.IsDisposed) { sharedTargets.Remove(td.DictionaryId); } } } base.Dispose(disposing); }
//===================================================================== /// <inheritdoc /> public override void Initialize(XPathNavigator configuration) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } string attrValue, id; targets = new TargetTypeDictionary(); resolver = new LinkTextResolver(targets); // Get the shared instances dictionary. Create it if it doesn't exist. if (BuildComponentCore.Data.ContainsKey(SharedReferenceTargetsId)) { sharedTargets = BuildComponentCore.Data[SharedReferenceTargetsId] as Dictionary <string, TargetDictionary>; } if (sharedTargets == null) { BuildComponentCore.Data[SharedReferenceTargetsId] = sharedTargets = new Dictionary <string, TargetDictionary>(); } // base-url is an xpath expression applied against the current document to pick up the save location of the // document. If specified, local links will be made relative to the base-url. string baseUrlValue = configuration.GetAttribute("base-url", String.Empty); if (!String.IsNullOrWhiteSpace(baseUrlValue)) { baseUrl = XPathExpression.Compile(baseUrlValue); } // hrefFormat is a string format that is used to format the value of local href attributes. The // default is "{0}.htm" if not specified. hrefFormat = (string)configuration.Evaluate("string(hrefFormat/@value)"); if (String.IsNullOrWhiteSpace(hrefFormat)) { hrefFormat = "{0}.htm"; } // The container XPath can be replaced; this is useful string containerValue = configuration.GetAttribute("container", String.Empty); if (!String.IsNullOrWhiteSpace(containerValue)) { XmlTargetDictionaryUtilities.ContainerExpression = containerValue; } XPathNodeIterator targetsNodes = configuration.Select("targets"); #if DEBUG this.WriteMessage(MessageLevel.Diagnostic, "Loading reference link target info"); DateTime startLoad = DateTime.Now; #endif foreach (XPathNavigator targetsNode in targetsNodes) { // Get target type attrValue = targetsNode.GetAttribute("type", String.Empty); if (String.IsNullOrWhiteSpace(attrValue)) { this.WriteMessage(MessageLevel.Error, "Each targets element must have a type attribute " + "that specifies which type of links to create"); } if (!Enum.TryParse <ReferenceLinkType>(attrValue, true, out ReferenceLinkType type)) { this.WriteMessage(MessageLevel.Error, "'{0}' is not a supported reference link type", attrValue); } // Check for shared instance by ID. If not there, create it and add it. id = targetsNode.GetAttribute("id", String.Empty); if (!sharedTargets.TryGetValue(id, out TargetDictionary newTargets)) { this.WriteMessage(MessageLevel.Info, "Loading {0} reference link type targets", type); newTargets = this.CreateTargetDictionary(targetsNode); sharedTargets[newTargets.DictionaryId] = newTargets; } targets.Add(type, newTargets); } #if DEBUG TimeSpan loadTime = (DateTime.Now - startLoad); this.WriteMessage(MessageLevel.Diagnostic, "Load time: {0} seconds", loadTime.TotalSeconds); // Dump targets for comparison to other versions // targets.DumpTargetDictionary(Path.GetFullPath("TargetDictionary.xml")); // Serialization test // targets.SerializeDictionary(Directory.GetCurrentDirectory()); #endif // Getting the count from a database cache can be expensive so only report it if it will be seen if (this.BuildAssembler.VerbosityLevel == MessageLevel.Info) { this.WriteMessage(MessageLevel.Info, "{0} total reference link targets", targets.Count); } if (targets.NeedsMemberIdUrlResolver) { this.WriteMessage(MessageLevel.Info, "Creating member ID URL resolver"); this.UrlResolver = this.CreateMemberIdResolver(configuration); string localeValue = (string)configuration.Evaluate("string(locale/@value)"); if (this.UrlResolver != null && !String.IsNullOrWhiteSpace(localeValue)) { this.UrlResolver.Locale = localeValue; } } linkTarget = (string)configuration.Evaluate("string(linkTarget/@value)"); if (String.IsNullOrWhiteSpace(linkTarget)) { linkTarget = "_blank"; } }