/Source/AIGA/src/Alchemi.Core/AIMLbot2.3/AIMLbot/AIMLbot/AIMLTagHandlers/condition.cs

https://github.com/abhishek-kumar/AIGA · C# · 232 lines · 128 code · 8 blank · 96 comment · 53 complexity · 7d84cf7c6b52d884909a8e70a001c150 MD5 · raw file

  1. using System;
  2. using System.Xml;
  3. using System.Text;
  4. using System.Text.RegularExpressions;
  5. namespace AIMLbot.AIMLTagHandlers
  6. {
  7. /// <summary>
  8. /// The condition element instructs the AIML interpreter to return specified contents depending
  9. /// upon the results of matching a predicate against a pattern.
  10. ///
  11. /// NB: The condition element has three different types. The three different types specified
  12. /// here are distinguished by an xsi:type attribute, which permits a validating XML Schema
  13. /// processor to validate them. Two of the types may contain li elements, of which there are
  14. /// three different types, whose validity is determined by the type of enclosing condition. In
  15. /// practice, an AIML interpreter may allow the omission of the xsi:type attribute and may instead
  16. /// heuristically determine which type of condition (and hence li) is in use.
  17. ///
  18. /// Block Condition
  19. /// ---------------
  20. ///
  21. /// The blockCondition type of condition has a required attribute "name", which specifies an AIML
  22. /// predicate, and a required attribute "value", which contains a simple pattern expression.
  23. ///
  24. /// If the contents of the value attribute match the value of the predicate specified by name, then
  25. /// the AIML interpreter should return the contents of the condition. If not, the empty string ""
  26. /// should be returned.
  27. ///
  28. /// Single-predicate Condition
  29. /// --------------------------
  30. ///
  31. /// The singlePredicateCondition type of condition has a required attribute "name", which specifies
  32. /// an AIML predicate. This form of condition must contain at least one li element. Zero or more of
  33. /// these li elements may be of the valueOnlyListItem type. Zero or one of these li elements may be
  34. /// of the defaultListItem type.
  35. ///
  36. /// The singlePredicateCondition type of condition is processed as follows:
  37. ///
  38. /// Reading each contained li in order:
  39. ///
  40. /// 1. If the li is a valueOnlyListItem type, then compare the contents of the value attribute of
  41. /// the li with the value of the predicate specified by the name attribute of the enclosing
  42. /// condition.
  43. /// a. If they match, then return the contents of the li and stop processing this condition.
  44. /// b. If they do not match, continue processing the condition.
  45. /// 2. If the li is a defaultListItem type, then return the contents of the li and stop processing
  46. /// this condition.
  47. ///
  48. /// Multi-predicate Condition
  49. /// -------------------------
  50. ///
  51. /// The multiPredicateCondition type of condition has no attributes. This form of condition must
  52. /// contain at least one li element. Zero or more of these li elements may be of the
  53. /// nameValueListItem type. Zero or one of these li elements may be of the defaultListItem type.
  54. ///
  55. /// The multiPredicateCondition type of condition is processed as follows:
  56. ///
  57. /// Reading each contained li in order:
  58. ///
  59. /// 1. If the li is a nameValueListItem type, then compare the contents of the value attribute of
  60. /// the li with the value of the predicate specified by the name attribute of the li.
  61. /// a. If they match, then return the contents of the li and stop processing this condition.
  62. /// b. If they do not match, continue processing the condition.
  63. /// 2. If the li is a defaultListItem type, then return the contents of the li and stop processing
  64. /// this condition.
  65. ///
  66. /// ****************
  67. ///
  68. /// Condition List Items
  69. ///
  70. /// As described above, two types of condition may contain li elements. There are three types of
  71. /// li elements. The type of li element allowed in a given condition depends upon the type of that
  72. /// condition, as described above.
  73. ///
  74. /// Default List Items
  75. /// ------------------
  76. ///
  77. /// An li element of the type defaultListItem has no attributes. It may contain any AIML template
  78. /// elements.
  79. ///
  80. /// Value-only List Items
  81. /// ---------------------
  82. ///
  83. /// An li element of the type valueOnlyListItem has a required attribute value, which must contain
  84. /// a simple pattern expression. The element may contain any AIML template elements.
  85. ///
  86. /// Name and Value List Items
  87. /// -------------------------
  88. ///
  89. /// An li element of the type nameValueListItem has a required attribute name, which specifies an
  90. /// AIML predicate, and a required attribute value, which contains a simple pattern expression. The
  91. /// element may contain any AIML template elements.
  92. /// </summary>
  93. public class condition : AIMLbot.Utils.AIMLTagHandler
  94. {
  95. /// <summary>
  96. /// Ctor
  97. /// </summary>
  98. /// <param name="bot">The bot involved in this request</param>
  99. /// <param name="user">The user making the request</param>
  100. /// <param name="query">The query that originated this node</param>
  101. /// <param name="request">The request inputted into the system</param>
  102. /// <param name="result">The result to be passed to the user</param>
  103. /// <param name="templateNode">The node to be processed</param>
  104. public condition(AIMLbot.Bot bot,
  105. AIMLbot.User user,
  106. AIMLbot.Utils.SubQuery query,
  107. AIMLbot.Request request,
  108. AIMLbot.Result result,
  109. XmlNode templateNode)
  110. : base(bot, user, query, request, result, templateNode)
  111. {
  112. }
  113. protected override string ProcessChange()
  114. {
  115. if (this.templateNode.Name.ToLower() == "condition")
  116. {
  117. // heuristically work out the type of condition being processed
  118. if (this.templateNode.Attributes.Count == 2) // block
  119. {
  120. string name = "";
  121. string value = "";
  122. if (this.templateNode.Attributes[0].Name == "name")
  123. {
  124. name = this.templateNode.Attributes[0].Value;
  125. }
  126. else if (this.templateNode.Attributes[0].Name == "value")
  127. {
  128. value = this.templateNode.Attributes[0].Value;
  129. }
  130. if (this.templateNode.Attributes[1].Name == "name")
  131. {
  132. name = this.templateNode.Attributes[1].Value;
  133. }
  134. else if (this.templateNode.Attributes[1].Name == "value")
  135. {
  136. value = this.templateNode.Attributes[1].Value;
  137. }
  138. if ((name.Length > 0) & (value.Length > 0))
  139. {
  140. string actualValue = this.user.Predicates.grabSetting(name);
  141. Regex matcher = new Regex(value.Replace(" ", "\\s").Replace("*", "[\\sA-Z0-9]+"), RegexOptions.IgnoreCase);
  142. if (matcher.IsMatch(actualValue))
  143. {
  144. return this.templateNode.InnerText;
  145. }
  146. }
  147. }
  148. else if (this.templateNode.Attributes.Count == 1) // single predicate
  149. {
  150. if (this.templateNode.Attributes[0].Name == "name")
  151. {
  152. string name = this.templateNode.Attributes[0].Value;
  153. foreach (XmlNode childLINode in this.templateNode.ChildNodes)
  154. {
  155. if (childLINode.Name.ToLower() == "li")
  156. {
  157. if (childLINode.Attributes.Count == 1)
  158. {
  159. if (childLINode.Attributes[0].Name.ToLower() == "value")
  160. {
  161. string actualValue = this.user.Predicates.grabSetting(name);
  162. Regex matcher = new Regex(childLINode.Attributes[0].Value.Replace(" ", "\\s").Replace("*", "[\\sA-Z0-9]+"), RegexOptions.IgnoreCase);
  163. if (matcher.IsMatch(actualValue))
  164. {
  165. return childLINode.InnerText;
  166. }
  167. }
  168. }
  169. else if (childLINode.Attributes.Count == 0)
  170. {
  171. return childLINode.InnerText;
  172. }
  173. }
  174. }
  175. }
  176. }
  177. else if (this.templateNode.Attributes.Count == 0) // multi-predicate
  178. {
  179. foreach (XmlNode childLINode in this.templateNode.ChildNodes)
  180. {
  181. if (childLINode.Name.ToLower() == "li")
  182. {
  183. if (childLINode.Attributes.Count == 2)
  184. {
  185. string name = "";
  186. string value = "";
  187. if (childLINode.Attributes[0].Name == "name")
  188. {
  189. name = childLINode.Attributes[0].Value;
  190. }
  191. else if (childLINode.Attributes[0].Name == "value")
  192. {
  193. value = childLINode.Attributes[0].Value;
  194. }
  195. if (childLINode.Attributes[1].Name == "name")
  196. {
  197. name = childLINode.Attributes[1].Value;
  198. }
  199. else if (childLINode.Attributes[1].Name == "value")
  200. {
  201. value = childLINode.Attributes[1].Value;
  202. }
  203. if ((name.Length > 0) & (value.Length > 0))
  204. {
  205. string actualValue = this.user.Predicates.grabSetting(name);
  206. Regex matcher = new Regex(value.Replace(" ", "\\s").Replace("*","[\\sA-Z0-9]+"), RegexOptions.IgnoreCase);
  207. if (matcher.IsMatch(actualValue))
  208. {
  209. return childLINode.InnerText;
  210. }
  211. }
  212. }
  213. else if (childLINode.Attributes.Count == 0)
  214. {
  215. return childLINode.InnerText;
  216. }
  217. }
  218. }
  219. }
  220. }
  221. return string.Empty;
  222. }
  223. }
  224. }