public DynamicTopic DynamicTopicFor(string topic) { if (_Topics == null) _Topics = new Hashtable(); DynamicTopic answer = (DynamicTopic)(_Topics[topic]); if (answer != null) return answer; RelativeTopicName rel = new RelativeTopicName(topic); ArrayList alternatives = new ArrayList(); if (rel.Namespace != null) // if they left the namespace unspec'd { alternatives.Add(new AbsoluteTopicName(topic)); } else { alternatives.Add(new AbsoluteTopicName(topic, Name)); // always try this one first alternatives.AddRange(rel.AllAbsoluteTopicNamesFor(CurrentFederation.ContentBaseForNamespace(Name))); } foreach (AbsoluteTopicName tn in alternatives) { ContentBase cb = CurrentFederation.ContentBaseForTopic(tn); if (!cb.TopicExists(tn)) continue; answer = new DynamicTopic(CurrentFederation, tn); _Topics[topic] = answer; return answer; } return null; }
/// <summary> /// Answer a hash: keys are topic; values are an array of topic names for referenced topics (in this content base) /// </summary> /// <param name="filterToTopic">Specific topic for which reference information is desired (null gets info for all topics)</param> /// <param name="existingOnly">Specific whether to only return the referenced topics that actually exist</param> /// <returns></returns> public Hashtable AllReferencesByTopic(AbsoluteTopicName filterToTopic, bool existingOnly) { Hashtable relativesToRefs = new Hashtable(); Hashtable answer = new Hashtable(); IEnumerable topicList; if (filterToTopic == null) topicList = AllTopics(false); else { ArrayList list = new ArrayList(); list.Add(filterToTopic); topicList = list; } foreach (AbsoluteTopicName topic in topicList) { string current = Federation.Read(topic); MatchCollection wikiNames = Formatter.extractWikiNames.Matches(current); ArrayList processed = new ArrayList(); ArrayList allReferencedTopicsFromTopic = new ArrayList(); foreach (Match m in wikiNames) { string each = m.Groups["topic"].ToString(); if (processed.Contains(each)) { continue; // skip dup } processed.Add(each); RelativeTopicName relName = new RelativeTopicName(TopicName.StripEscapes(each)); // Now either calculate the full list of referenced names and cache it or get it from the cache ArrayList absoluteNames = (ArrayList)(relativesToRefs[relName]); if (absoluteNames == null) { absoluteNames = new ArrayList(); relativesToRefs[relName] = absoluteNames; // Start with the singulars in the various reachable namespaces, then add the plurals if (existingOnly) { absoluteNames.AddRange(AllAbsoluteTopicNamesThatExist(relName)); foreach (TopicName alternate in relName.AlternateForms) absoluteNames.AddRange(AllAbsoluteTopicNamesThatExist(alternate)); } else { absoluteNames.AddRange(relName.AllAbsoluteTopicNamesFor(this)); foreach (TopicName alternate in relName.AlternateForms) absoluteNames.AddRange(alternate.AllAbsoluteTopicNamesFor(this)); } } allReferencedTopicsFromTopic.AddRange(absoluteNames); } answer[topic] = allReferencedTopicsFromTopic; } return answer; }