XPathMessageQuery.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.ComponentModel;
  9. using System.Globalization;
  10. using System.ServiceModel.Channels;
  11. using System.Text;
  12. using System.Windows.Markup;
  13. using System.Xml;
  14. using System.Xml.Xsl;
  15. using System.ServiceModel.Dispatcher;
  16. [ContentProperty("Expression")]
  17. public class XPathMessageQuery : MessageQuery
  18. {
  19. string expression;
  20. XPathQueryMatcher matcher;
  21. XmlNamespaceManager namespaces;
  22. bool needCompile;
  23. object thisLock;
  24. public XPathMessageQuery() :
  25. this(string.Empty, (XmlNamespaceManager)new XPathMessageContext())
  26. {
  27. }
  28. public XPathMessageQuery(string expression)
  29. : this(expression, (XmlNamespaceManager)new XPathMessageContext())
  30. {
  31. }
  32. public XPathMessageQuery(string expression, XsltContext context)
  33. : this(expression, (XmlNamespaceManager)context)
  34. {
  35. }
  36. public XPathMessageQuery(string expression, XmlNamespaceManager namespaces)
  37. {
  38. if (expression == null)
  39. {
  40. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("expression");
  41. }
  42. this.expression = expression;
  43. this.namespaces = namespaces;
  44. this.needCompile = true;
  45. this.thisLock = new Object();
  46. }
  47. [DefaultValue("")]
  48. public string Expression
  49. {
  50. get
  51. {
  52. return this.expression;
  53. }
  54. set
  55. {
  56. if (value == null)
  57. {
  58. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
  59. }
  60. this.expression = value;
  61. this.needCompile = true;
  62. }
  63. }
  64. [DefaultValue(null)]
  65. public XmlNamespaceManager Namespaces
  66. {
  67. get
  68. {
  69. return this.namespaces;
  70. }
  71. set
  72. {
  73. this.namespaces = value;
  74. this.needCompile = true;
  75. }
  76. }
  77. public override MessageQueryCollection CreateMessageQueryCollection()
  78. {
  79. return new XPathMessageQueryCollection();
  80. }
  81. public override TResult Evaluate<TResult>(Message message)
  82. {
  83. if (message == null)
  84. {
  85. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
  86. }
  87. if (typeof(TResult) == typeof(XPathResult) ||
  88. typeof(TResult) == typeof(string) ||
  89. typeof(TResult) == typeof(bool) ||
  90. typeof(TResult) == typeof(object))
  91. {
  92. this.EnsureCompile();
  93. QueryResult<TResult> queryResult = this.matcher.Evaluate<TResult>(message, false);
  94. return queryResult.GetSingleResult();
  95. }
  96. else
  97. {
  98. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TResult",
  99. SR.GetString(SR.UnsupportedMessageQueryResultType, typeof(TResult)));
  100. }
  101. }
  102. public override TResult Evaluate<TResult>(MessageBuffer buffer)
  103. {
  104. if (buffer == null)
  105. {
  106. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer");
  107. }
  108. this.EnsureCompile();
  109. if (typeof(TResult) == typeof(XPathResult) ||
  110. typeof(TResult) == typeof(string) ||
  111. typeof(TResult) == typeof(bool) ||
  112. typeof(TResult) == typeof(object))
  113. {
  114. this.EnsureCompile();
  115. QueryResult<TResult> queryResult = this.matcher.Evaluate<TResult>(buffer);
  116. return queryResult.GetSingleResult();
  117. }
  118. else
  119. {
  120. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TResult",
  121. SR.GetString(SR.UnsupportedMessageQueryResultType, typeof(TResult)));
  122. }
  123. }
  124. void EnsureCompile()
  125. {
  126. if (this.needCompile)
  127. {
  128. lock (thisLock)
  129. {
  130. if (this.needCompile)
  131. {
  132. this.matcher = new XPathQueryMatcher(false);
  133. this.matcher.Compile(this.expression, this.namespaces);
  134. this.needCompile = false;
  135. }
  136. }
  137. }
  138. }
  139. }
  140. }