XPathMessageContext.cs 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  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.ServiceModel.Description;
  12. using System.ServiceModel.XamlIntegration;
  13. using System.Xml;
  14. using System.Xml.XPath;
  15. using System.Xml.Xsl;
  16. [TypeConverter(typeof(XPathMessageContextTypeConverter))]
  17. public class XPathMessageContext : XsltContext
  18. {
  19. // Namespace URIs
  20. internal const string S11NS = Message11Strings.Namespace;
  21. internal const string S12NS = Message12Strings.Namespace;
  22. internal const string Wsa200408NS = Addressing200408Strings.Namespace;
  23. internal const string Wsa10NS = Addressing10Strings.Namespace;
  24. internal const string WsaNoneNS = AddressingNoneStrings.Namespace;
  25. internal const string TempUriNS = NamingHelper.DefaultNamespace;
  26. internal const string SerializationNS = EndpointAddressProcessor.SerNs;
  27. internal const string IndigoNS = "http://schemas.microsoft.com/serviceModel/2004/05/xpathfunctions";
  28. // Namespace prefixes
  29. internal const string S11P = "s11";
  30. internal const string S12P = "s12";
  31. internal const string Wsa200408P = "wsaAugust2004";
  32. internal const string Wsa10P = "wsa10";
  33. internal const string TempUriP = "tempuri";
  34. internal const string SerializationP = "ser";
  35. internal const string IndigoP = "sm";
  36. internal static Dictionary<string, string> defaultNamespaces;
  37. // Element names
  38. internal const string EnvelopeE = MessageStrings.Envelope;
  39. internal const string HeaderE = MessageStrings.Header;
  40. internal const string BodyE = MessageStrings.Body;
  41. internal const string ActionE = AddressingStrings.Action;
  42. internal const string ToE = AddressingStrings.To;
  43. internal const string MessageIDE = AddressingStrings.MessageId;
  44. internal const string RelatesToE = AddressingStrings.RelatesTo;
  45. internal const string ReplyToE = AddressingStrings.ReplyTo;
  46. internal const string FromE = AddressingStrings.From;
  47. internal const string FaultToE = AddressingStrings.FaultTo;
  48. // Attribute names
  49. internal static string Actor11A = EnvelopeVersion.Soap11.Actor;
  50. internal static string Actor12A = EnvelopeVersion.Soap12.Actor;
  51. internal const string MandatoryA = MessageStrings.MustUnderstand;
  52. // Functions with no arguments
  53. internal static readonly XPathMessageFunction HeaderFun = new XPathMessageFunctionHeader();
  54. internal static readonly XPathMessageFunction BodyFun = new XPathMessageFunctionBody();
  55. internal static readonly XPathMessageFunction SoapUriFun = new XPathMessageFunctionSoapUri();
  56. internal static readonly XPathMessageFunction MessageIDFun = new XPathMessageFunctionMessageID();
  57. internal static readonly XPathMessageFunction RelatesToFun = new XPathMessageFunctionRelatesTo();
  58. internal static readonly XPathMessageFunction ReplyToFun = new XPathMessageFunctionReplyTo();
  59. internal static readonly XPathMessageFunction FromFun = new XPathMessageFunctionFrom();
  60. internal static readonly XPathMessageFunction FaultToFun = new XPathMessageFunctionFaultTo();
  61. internal static readonly XPathMessageFunction ToFun = new XPathMessageFunctionTo();
  62. internal static readonly XPathMessageFunction ActionFun = new XPathMessageFunctionAction();
  63. internal static readonly XPathMessageFunction DateNowFun = new XPathMessageFunctionDateNow();
  64. // Functions with arguments
  65. internal static readonly XPathMessageFunction HeadersWithActorFun = new XPathMessageFunctionHeadersWithActor();
  66. internal static readonly XPathMessageFunction ActorFun = new XPathMessageFunctionActor();
  67. internal static readonly XPathMessageFunction IsMandatoryFun = new XPathMessageFunctionIsMandatory();
  68. internal static readonly XPathMessageFunction IsActorNextFun = new XPathMessageFunctionIsActorNext();
  69. internal static readonly XPathMessageFunction IsActorUltRecFun = new XPathMessageFunctionIsActorUltimateReceiver();
  70. internal static readonly XPathMessageFunction DateFun = new XPathMessageFunctionDateStr();
  71. internal static readonly XPathMessageFunction SpanFun = new XPathMessageFunctionSpanStr();
  72. internal static readonly XPathMessageFunction CorrelationDataFun = new XPathMessageFunctionCorrelationData();
  73. // Function signatures
  74. static Function[] functions;
  75. static XPathMessageContext()
  76. {
  77. functions = new Function[]
  78. {
  79. new Function(IndigoNS, "header", HeaderFun),
  80. new Function(IndigoNS, "body", BodyFun),
  81. new Function(IndigoNS, "soap-uri", SoapUriFun),
  82. new Function(IndigoNS, "headers-with-actor", HeadersWithActorFun),
  83. new Function(IndigoNS, "actor", ActorFun),
  84. new Function(IndigoNS, "is-mandatory", IsMandatoryFun),
  85. new Function(IndigoNS, "is-actor-next", IsActorNextFun),
  86. new Function(IndigoNS, "is-actor-ultimate-receiver", IsActorUltRecFun),
  87. new Function(IndigoNS, "messageId", MessageIDFun),
  88. new Function(IndigoNS, "relatesTo", RelatesToFun),
  89. new Function(IndigoNS, "replyTo", ReplyToFun),
  90. new Function(IndigoNS, "from", FromFun),
  91. new Function(IndigoNS, "faultTo", FaultToFun),
  92. new Function(IndigoNS, "to", ToFun),
  93. new Function(IndigoNS, "action", ActionFun),
  94. new Function(IndigoNS, "date-time", DateFun),
  95. new Function(IndigoNS, "duration", SpanFun),
  96. new Function(IndigoNS, "utc-now", DateNowFun),
  97. new Function(IndigoNS, "correlation-data", CorrelationDataFun)
  98. };
  99. defaultNamespaces = new Dictionary<string, string>()
  100. {
  101. { S11P, S11NS },
  102. { S12P, S12NS },
  103. { Wsa10P, Wsa10NS },
  104. { Wsa200408P, Wsa200408NS },
  105. { TempUriP, TempUriNS },
  106. { SerializationP, SerializationNS },
  107. { IndigoP, IndigoNS }
  108. };
  109. }
  110. public XPathMessageContext()
  111. : this(new NameTable())
  112. {
  113. }
  114. public XPathMessageContext(NameTable table)
  115. : base(ArgValidator(table))
  116. {
  117. foreach (var ns in defaultNamespaces)
  118. {
  119. this.AddNamespace(ns.Key, ns.Value);
  120. }
  121. }
  122. static NameTable ArgValidator(NameTable table)
  123. {
  124. if (table == null)
  125. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("table");
  126. return table;
  127. }
  128. public override bool Whitespace
  129. {
  130. get
  131. {
  132. return false;
  133. }
  134. }
  135. public override int CompareDocument(string baseUri, string nextBaseUri)
  136. {
  137. return 0;
  138. }
  139. public override bool PreserveWhitespace(XPathNavigator node)
  140. {
  141. return false;
  142. }
  143. public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] argTypes)
  144. {
  145. if (argTypes == null)
  146. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("argTypes");
  147. // PERF, [....], factor ns if all same
  148. string ns = LookupNamespace(prefix);
  149. for (int i = 0; i < functions.Length; ++i)
  150. {
  151. if (functions[i].name == name && functions[i].ns == ns)
  152. {
  153. IXsltContextFunction fun = functions[i].function;
  154. if (argTypes.Length <= fun.Maxargs && argTypes.Length >= fun.Minargs)
  155. {
  156. // Typechecking is done in the compiler.
  157. return fun;
  158. }
  159. }
  160. }
  161. return null;
  162. }
  163. public override IXsltContextVariable ResolveVariable(string prefix, string name)
  164. {
  165. return null;
  166. }
  167. internal struct Function
  168. {
  169. internal string ns;
  170. internal string name;
  171. internal IXsltContextFunction function;
  172. internal Function(string ns, string name, IXsltContextFunction function)
  173. {
  174. this.ns = ns;
  175. this.name = name;
  176. this.function = function;
  177. }
  178. }
  179. }
  180. internal abstract class XPathMessageFunction : IXsltContextFunction
  181. {
  182. internal readonly static DateTime ZeroDate = new DateTime(1, 1, 1, 0, 0, 0, DateTimeKind.Utc);
  183. internal readonly static XmlNamespaceManager Namespaces = new XmlNamespaceManager(new NameTable());
  184. XPathResultType[] argTypes;
  185. int maxArgs;
  186. int minArgs;
  187. XPathResultType retType;
  188. static XPathMessageFunction()
  189. {
  190. Namespaces.AddNamespace(XPathMessageContext.S11P, XPathMessageContext.S11NS);
  191. Namespaces.AddNamespace(XPathMessageContext.S12P, XPathMessageContext.S12NS);
  192. }
  193. protected XPathMessageFunction(XPathResultType[] argTypes, int max, int min, XPathResultType retType)
  194. {
  195. this.argTypes = argTypes;
  196. this.maxArgs = max;
  197. this.minArgs = min;
  198. this.retType = retType;
  199. }
  200. public XPathResultType[] ArgTypes
  201. {
  202. get
  203. {
  204. return this.argTypes;
  205. }
  206. }
  207. public int Maxargs
  208. {
  209. get
  210. {
  211. return this.maxArgs;
  212. }
  213. }
  214. public int Minargs
  215. {
  216. get
  217. {
  218. return this.minArgs;
  219. }
  220. }
  221. public XPathResultType ReturnType
  222. {
  223. get
  224. {
  225. return this.retType;
  226. }
  227. }
  228. public abstract object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext);
  229. internal abstract void InvokeInternal(ProcessingContext context, int argCount);
  230. // Must save/clone navigator before passing to these functions
  231. internal static bool MoveToAddressingHeader(XPathNavigator nav, string name)
  232. {
  233. if (!MoveToHeader(nav))
  234. return false;
  235. if (!nav.MoveToFirstChild())
  236. {
  237. return false;
  238. }
  239. do
  240. {
  241. if (nav.LocalName == name && (nav.NamespaceURI == XPathMessageContext.Wsa10NS || nav.NamespaceURI == XPathMessageContext.Wsa200408NS || nav.NamespaceURI == XPathMessageContext.WsaNoneNS))
  242. {
  243. return true;
  244. }
  245. } while (nav.MoveToNext());
  246. return false;
  247. }
  248. internal static bool MoveToChild(XPathNavigator nav, string name, string ns)
  249. {
  250. if (!nav.MoveToFirstChild())
  251. {
  252. return false;
  253. }
  254. do
  255. {
  256. if (nav.LocalName == name && nav.NamespaceURI == ns)
  257. {
  258. return true;
  259. }
  260. } while (nav.MoveToNext());
  261. return false;
  262. }
  263. internal static bool MoveToAddressingHeaderSibling(XPathNavigator nav, string name)
  264. {
  265. while (nav.MoveToNext())
  266. {
  267. if (nav.LocalName == name && (nav.NamespaceURI == XPathMessageContext.Wsa10NS || nav.NamespaceURI == XPathMessageContext.Wsa200408NS))
  268. {
  269. return true;
  270. }
  271. }
  272. return false;
  273. }
  274. internal static bool MoveToSibling(XPathNavigator nav, string name, string ns)
  275. {
  276. while (nav.MoveToNext())
  277. {
  278. if (nav.LocalName == name && nav.NamespaceURI == ns)
  279. {
  280. return true;
  281. }
  282. }
  283. return false;
  284. }
  285. internal static bool MoveToHeader(XPathNavigator nav)
  286. {
  287. nav.MoveToRoot();
  288. if (!nav.MoveToFirstChild())
  289. {
  290. return false;
  291. }
  292. string ns = nav.NamespaceURI;
  293. if (nav.LocalName != XPathMessageContext.EnvelopeE || (ns != XPathMessageContext.S11NS && ns != XPathMessageContext.S12NS))
  294. {
  295. return false;
  296. }
  297. if (!nav.MoveToFirstChild())
  298. {
  299. return false;
  300. }
  301. do
  302. {
  303. if (nav.LocalName == XPathMessageContext.HeaderE && nav.NamespaceURI == ns)
  304. {
  305. return true;
  306. }
  307. } while (nav.MoveToNext());
  308. return false;
  309. }
  310. internal static bool MoveToBody(XPathNavigator nav)
  311. {
  312. nav.MoveToRoot();
  313. if (!nav.MoveToFirstChild())
  314. {
  315. return false;
  316. }
  317. string ns = nav.NamespaceURI;
  318. if (nav.LocalName != XPathMessageContext.EnvelopeE || (ns != XPathMessageContext.S11NS && ns != XPathMessageContext.S12NS))
  319. {
  320. return false;
  321. }
  322. if (!nav.MoveToFirstChild())
  323. {
  324. return false;
  325. }
  326. do
  327. {
  328. if (nav.LocalName == XPathMessageContext.BodyE && nav.NamespaceURI == ns)
  329. {
  330. return true;
  331. }
  332. } while (nav.MoveToNext());
  333. return false;
  334. }
  335. internal static string ToString(object o)
  336. {
  337. if (o is bool)
  338. {
  339. return QueryValueModel.String((bool)o);
  340. }
  341. else if (o is string)
  342. {
  343. return (string)o;
  344. }
  345. else if (o is double)
  346. {
  347. return QueryValueModel.String((double)o);
  348. }
  349. else if (o is XPathNodeIterator)
  350. {
  351. XPathNodeIterator iter = (XPathNodeIterator)o;
  352. iter.MoveNext();
  353. return iter.Current.Value;
  354. }
  355. else
  356. {
  357. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.QueryFunctionStringArg)));
  358. }
  359. }
  360. internal static double ConvertDate(DateTime date)
  361. {
  362. if (date.Kind != DateTimeKind.Utc)
  363. {
  364. date = date.ToUniversalTime();
  365. }
  366. return (date - ZeroDate).TotalDays;
  367. }
  368. }
  369. internal class XPathMessageFunctionCallOpcode : Opcode
  370. {
  371. XPathMessageFunction function;
  372. int argCount;
  373. internal XPathMessageFunctionCallOpcode(XPathMessageFunction fun, int argCount)
  374. : base(OpcodeID.XsltInternalFunction)
  375. {
  376. this.function = fun;
  377. this.argCount = argCount;
  378. }
  379. internal XPathResultType ReturnType
  380. {
  381. get
  382. {
  383. return this.function.ReturnType;
  384. }
  385. }
  386. internal int ArgCount
  387. {
  388. get
  389. {
  390. return this.argCount;
  391. }
  392. }
  393. internal override bool Equals(Opcode op)
  394. {
  395. if (base.Equals(op))
  396. {
  397. XPathMessageFunctionCallOpcode fun = op as XPathMessageFunctionCallOpcode;
  398. if (fun != null)
  399. {
  400. // Assumption is that they're static on XPathMessageContext
  401. return this.function == fun.function;
  402. }
  403. }
  404. return false;
  405. }
  406. internal override Opcode Eval(ProcessingContext context)
  407. {
  408. function.InvokeInternal(context, this.argCount);
  409. return this.next;
  410. }
  411. #if DEBUG_FILTER
  412. public override string ToString()
  413. {
  414. return string.Format("{0} XPathMessageFunction", base.ToString());
  415. }
  416. #endif
  417. }
  418. #if NO
  419. // These classes are left around in case we decide to implement our own variables or any new functions.
  420. internal abstract class XPathMessageVariable : IXsltContextVariable
  421. {
  422. protected XPathMessageVariable()
  423. {
  424. }
  425. public abstract bool IsLocal { get; }
  426. public abstract bool IsParam { get; }
  427. public abstract XPathResultType VariableType { get; }
  428. public abstract object Evaluate(XsltContext xsltContext);
  429. internal void EvaluateInternal(ProcessingContext context)
  430. {
  431. context.PushFrame();
  432. int count = context.IterationCount;
  433. if(count > 0)
  434. {
  435. ValuePush(context, count);
  436. }
  437. }
  438. protected abstract void ValuePush(ProcessingContext context, int count);
  439. }
  440. internal class PushXPathMessageVariableOpcode : Opcode
  441. {
  442. XPathMessageVariable variable;
  443. internal PushXPathMessageVariableOpcode(XPathMessageVariable var)
  444. : base(OpcodeID.PushXsltVariable)
  445. {
  446. this.variable = var;
  447. }
  448. internal override bool Equals(Opcode op)
  449. {
  450. if (base.Equals(op))
  451. {
  452. PushXPathMessageVariableOpcode var = op as PushXPathMessageVariableOpcode;
  453. if(var != null)
  454. {
  455. return this.variable == var.variable;
  456. }
  457. }
  458. return false;
  459. }
  460. internal override Opcode Eval(ProcessingContext context)
  461. {
  462. this.variable.EvaluateInternal(context);
  463. return this.next;
  464. }
  465. #if DEBUG_FILTER
  466. public override string ToString()
  467. {
  468. return string.Format("{0} XPathMessageVariable: {1}", base.ToString(), this.variable.ToString());
  469. }
  470. #endif
  471. }
  472. internal class XPathMessageFunctionQuick : IXsltContextFunction
  473. {
  474. static XPathNavigator navigator;
  475. XmlNamespaceManager context;
  476. XPathExpression expr;
  477. XPathResultType retType;
  478. static XPathMessageFunctionQuick()
  479. {
  480. XmlDocument doc = new XmlDocument();
  481. navigator = doc.CreateNavigator();
  482. }
  483. public XPathMessageFunctionQuick(string xpath)
  484. {
  485. this.context = new XPathMessageContext();
  486. this.expr = navigator.Compile(xpath);
  487. this.expr.SetContext(context);
  488. this.retType = this.expr.ReturnType;
  489. }
  490. public XPathResultType[] ArgTypes
  491. {
  492. get
  493. {
  494. return new XPathResultType[] {};
  495. }
  496. }
  497. public int Maxargs
  498. {
  499. get
  500. {
  501. return 0;
  502. }
  503. }
  504. public int Minargs
  505. {
  506. get
  507. {
  508. return 0;
  509. }
  510. }
  511. public XPathResultType ReturnType
  512. {
  513. get
  514. {
  515. return this.retType;
  516. }
  517. }
  518. public object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  519. {
  520. return docContext.Evaluate(this.expr);
  521. }
  522. }
  523. #endif
  524. internal class XPathMessageFunctionAction : XPathMessageFunction
  525. {
  526. public XPathMessageFunctionAction()
  527. : base(new XPathResultType[0], 0, 0, XPathResultType.String)
  528. {
  529. }
  530. internal override void InvokeInternal(ProcessingContext context, int argCount)
  531. {
  532. context.PushFrame();
  533. int count = context.IterationCount;
  534. if (count > 0)
  535. {
  536. string act = context.Processor.Action;
  537. if (act == null)
  538. {
  539. Message msg = context.Processor.ContextMessage;
  540. if (msg == null)
  541. {
  542. SeekableXPathNavigator nav = context.Processor.ContextNode;
  543. long p = nav.CurrentPosition;
  544. act = ExtractFromNavigator(nav);
  545. nav.CurrentPosition = p;
  546. }
  547. else
  548. {
  549. act = msg.Headers.Action;
  550. }
  551. context.Processor.Action = act;
  552. }
  553. if (act == null)
  554. {
  555. act = string.Empty;
  556. context.Processor.Action = act;
  557. }
  558. if (count == 1)
  559. {
  560. context.Push(act);
  561. }
  562. else
  563. {
  564. context.Push(act, count);
  565. }
  566. }
  567. }
  568. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  569. {
  570. SeekableMessageNavigator nav = docContext as SeekableMessageNavigator;
  571. if (nav != null)
  572. {
  573. string act = nav.Message.Headers.Action;
  574. if (act == null)
  575. return string.Empty;
  576. return act;
  577. }
  578. return ExtractFromNavigator(docContext.Clone());
  579. }
  580. internal static string ExtractFromNavigator(XPathNavigator nav)
  581. {
  582. if (!MoveToAddressingHeader(nav, XPathMessageContext.ActionE))
  583. {
  584. return string.Empty;
  585. }
  586. return nav.Value;
  587. }
  588. }
  589. internal class XPathMessageFunctionTo : XPathMessageFunction
  590. {
  591. public XPathMessageFunctionTo()
  592. : base(new XPathResultType[0], 0, 0, XPathResultType.String)
  593. {
  594. }
  595. internal override void InvokeInternal(ProcessingContext context, int argCount)
  596. {
  597. context.PushFrame();
  598. int count = context.IterationCount;
  599. if (count > 0)
  600. {
  601. string to = context.Processor.ToHeader;
  602. if (to == null)
  603. {
  604. Message msg = context.Processor.ContextMessage;
  605. if (msg == null)
  606. {
  607. SeekableXPathNavigator nav = context.Processor.ContextNode;
  608. long p = nav.CurrentPosition;
  609. to = ExtractFromNavigator(nav);
  610. nav.CurrentPosition = p;
  611. }
  612. else
  613. {
  614. Uri tempTo = msg.Headers.To;
  615. if (tempTo == null)
  616. to = msg.Version.Addressing.Anonymous;
  617. else
  618. to = tempTo.AbsoluteUri;
  619. }
  620. context.Processor.ToHeader = to;
  621. }
  622. context.Push(to, count);
  623. }
  624. }
  625. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  626. {
  627. SeekableMessageNavigator nav = docContext as SeekableMessageNavigator;
  628. if (nav != null)
  629. {
  630. Uri to = nav.Message.Headers.To;
  631. if (to == null)
  632. return string.Empty;
  633. return to.ToString();
  634. }
  635. return ExtractFromNavigator(docContext.Clone());
  636. }
  637. static string ExtractFromNavigator(XPathNavigator nav)
  638. {
  639. if (!MoveToAddressingHeader(nav, XPathMessageContext.ToE))
  640. {
  641. return string.Empty;
  642. }
  643. return nav.Value;
  644. }
  645. }
  646. internal class XPathMessageFunctionMessageID : XPathMessageFunction
  647. {
  648. public XPathMessageFunctionMessageID()
  649. : base(new XPathResultType[0], 0, 0, XPathResultType.String)
  650. {
  651. }
  652. internal override void InvokeInternal(ProcessingContext context, int argCount)
  653. {
  654. context.PushFrame();
  655. int count = context.IterationCount;
  656. if (count > 0)
  657. {
  658. string id = context.Processor.MessageId;
  659. if (id == null)
  660. {
  661. Message msg = context.Processor.ContextMessage;
  662. if (msg == null)
  663. {
  664. SeekableXPathNavigator nav = context.Processor.ContextNode;
  665. long p = nav.CurrentPosition;
  666. id = ExtractFromNavigator(nav);
  667. nav.CurrentPosition = p;
  668. }
  669. else
  670. {
  671. UniqueId uid = msg.Headers.MessageId;
  672. if (uid == null)
  673. id = string.Empty;
  674. else
  675. id = uid.ToString();
  676. }
  677. context.Processor.MessageId = id;
  678. }
  679. context.Push(id, count);
  680. }
  681. }
  682. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  683. {
  684. SeekableMessageNavigator nav = docContext as SeekableMessageNavigator;
  685. if (nav != null)
  686. {
  687. UniqueId id = nav.Message.Headers.MessageId;
  688. if (id == null)
  689. return string.Empty;
  690. return id.ToString();
  691. }
  692. return ExtractFromNavigator(docContext.Clone());
  693. }
  694. static string ExtractFromNavigator(XPathNavigator nav)
  695. {
  696. if (!MoveToAddressingHeader(nav, XPathMessageContext.MessageIDE))
  697. {
  698. return string.Empty;
  699. }
  700. return nav.Value;
  701. }
  702. }
  703. internal class XPathMessageFunctionHeader : XPathMessageFunction
  704. {
  705. XPathExpression expr;
  706. public XPathMessageFunctionHeader()
  707. : base(new XPathResultType[0], 0, 0, XPathResultType.NodeSet)
  708. {
  709. }
  710. internal override void InvokeInternal(ProcessingContext context, int argCount)
  711. {
  712. int count = context.IterationCount;
  713. context.PushSequenceFrame();
  714. if (count > 0)
  715. {
  716. NodeSequence seq = context.CreateSequence();
  717. seq.StartNodeset();
  718. SeekableXPathNavigator nav = context.Processor.ContextNode;
  719. long p = nav.CurrentPosition;
  720. if (MoveToHeader(nav))
  721. {
  722. seq.Add(nav);
  723. }
  724. nav.CurrentPosition = p;
  725. seq.StopNodeset();
  726. context.PushSequence(seq);
  727. for (int i = 1; i < count; ++i)
  728. {
  729. context.PushSequence(seq);
  730. }
  731. }
  732. }
  733. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  734. {
  735. if (this.expr == null)
  736. {
  737. XPathExpression e = docContext.Compile("(/s11:Envelope/s11:Header | /s12:Envelope/s12:Header)[1]");
  738. e.SetContext(Namespaces);
  739. this.expr = e;
  740. }
  741. return docContext.Evaluate(this.expr);
  742. }
  743. }
  744. internal class XPathMessageFunctionBody : XPathMessageFunction
  745. {
  746. XPathExpression expr;
  747. public XPathMessageFunctionBody()
  748. : base(new XPathResultType[0], 0, 0, XPathResultType.NodeSet)
  749. {
  750. }
  751. internal override void InvokeInternal(ProcessingContext context, int argCount)
  752. {
  753. int count = context.IterationCount;
  754. context.PushSequenceFrame();
  755. if (count > 0)
  756. {
  757. NodeSequence seq = context.CreateSequence();
  758. seq.StartNodeset();
  759. SeekableXPathNavigator nav = context.Processor.ContextNode;
  760. long p = nav.CurrentPosition;
  761. if (MoveToBody(nav))
  762. {
  763. seq.Add(nav);
  764. }
  765. nav.CurrentPosition = p;
  766. seq.StopNodeset();
  767. context.PushSequence(seq);
  768. for (int i = 1; i < count; ++i)
  769. {
  770. seq.refCount++;
  771. context.PushSequence(seq);
  772. }
  773. }
  774. }
  775. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  776. {
  777. if (this.expr == null)
  778. {
  779. XPathExpression e = docContext.Compile("(/s11:Envelope/s11:Body | /s12:Envelope/s12:Body)[1]");
  780. e.SetContext(Namespaces);
  781. this.expr = e;
  782. }
  783. return docContext.Evaluate(this.expr);
  784. }
  785. }
  786. internal class XPathMessageFunctionSoapUri : XPathMessageFunction
  787. {
  788. public XPathMessageFunctionSoapUri()
  789. : base(new XPathResultType[0], 0, 0, XPathResultType.String)
  790. {
  791. }
  792. internal override void InvokeInternal(ProcessingContext context, int argCount)
  793. {
  794. context.PushFrame();
  795. int count = context.IterationCount;
  796. if (count > 0)
  797. {
  798. string soap = context.Processor.SoapUri;
  799. if (soap == null)
  800. {
  801. Message msg = context.Processor.ContextMessage;
  802. if (msg == null)
  803. {
  804. SeekableXPathNavigator nav = context.Processor.ContextNode;
  805. long p = nav.CurrentPosition;
  806. soap = ExtractFromNavigator(nav);
  807. nav.CurrentPosition = p;
  808. }
  809. else
  810. {
  811. soap = msg.Version.Envelope.Namespace;
  812. }
  813. context.Processor.SoapUri = soap;
  814. }
  815. context.Push(soap, count);
  816. }
  817. }
  818. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  819. {
  820. SeekableMessageNavigator nav = docContext as SeekableMessageNavigator;
  821. if (nav != null)
  822. {
  823. return nav.Message.Version.Envelope.Namespace;
  824. }
  825. return ExtractFromNavigator(docContext.Clone());
  826. }
  827. internal static string ExtractFromNavigator(XPathNavigator nav)
  828. {
  829. nav.MoveToRoot();
  830. if (nav.MoveToFirstChild())
  831. {
  832. string ns = nav.NamespaceURI;
  833. if (nav.LocalName != XPathMessageContext.EnvelopeE || (ns != XPathMessageContext.S11NS && ns != XPathMessageContext.S12NS))
  834. {
  835. return string.Empty;
  836. }
  837. else
  838. {
  839. return ns;
  840. }
  841. }
  842. else
  843. {
  844. return string.Empty;
  845. }
  846. }
  847. }
  848. internal class XPathMessageFunctionActor : XPathMessageFunction
  849. {
  850. internal XPathMessageFunctionActor()
  851. : base(new XPathResultType[] { XPathResultType.NodeSet }, 1, 1, XPathResultType.String)
  852. {
  853. }
  854. internal override void InvokeInternal(ProcessingContext context, int argCount)
  855. {
  856. StackFrame seqArg = context.TopArg;
  857. while (seqArg.basePtr <= seqArg.endPtr)
  858. {
  859. string actor = string.Empty;
  860. NodeSequence seq = context.PeekSequence(seqArg.basePtr);
  861. if (seq.Count > 0)
  862. {
  863. SeekableXPathNavigator nav = seq[0].Node.Node;
  864. long p = nav.CurrentPosition;
  865. nav.CurrentPosition = seq[0].Node.Position;
  866. actor = ExtractFromNavigator(nav);
  867. nav.CurrentPosition = p;
  868. }
  869. context.SetValue(context, seqArg.basePtr, actor);
  870. seqArg.basePtr++;
  871. }
  872. }
  873. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  874. {
  875. XPathNodeIterator iter = (XPathNodeIterator)args[0];
  876. if (!iter.MoveNext())
  877. {
  878. return string.Empty;
  879. }
  880. return ExtractFromNavigator(iter.Current.Clone());
  881. }
  882. internal static string ExtractFromNavigator(XPathNavigator nav)
  883. {
  884. string actor11 = nav.GetAttribute(XPathMessageContext.Actor11A, XPathMessageContext.S11NS);
  885. string actor12 = nav.GetAttribute(XPathMessageContext.Actor12A, XPathMessageContext.S12NS);
  886. nav.MoveToRoot();
  887. nav.MoveToFirstChild();
  888. if (nav.LocalName == XPathMessageContext.EnvelopeE && nav.NamespaceURI == XPathMessageContext.S11NS)
  889. {
  890. return actor11;
  891. }
  892. else if (nav.LocalName == XPathMessageContext.EnvelopeE && nav.NamespaceURI == XPathMessageContext.S12NS)
  893. {
  894. return actor12;
  895. }
  896. return string.Empty;
  897. }
  898. }
  899. internal class XPathMessageFunctionIsMandatory : XPathMessageFunction
  900. {
  901. internal XPathMessageFunctionIsMandatory()
  902. : base(new XPathResultType[] { XPathResultType.NodeSet }, 1, 1, XPathResultType.Boolean)
  903. {
  904. }
  905. internal override void InvokeInternal(ProcessingContext context, int argCount)
  906. {
  907. StackFrame seqArg = context.TopArg;
  908. while (seqArg.basePtr <= seqArg.endPtr)
  909. {
  910. bool mandatory = false;
  911. NodeSequence seq = context.PeekSequence(seqArg.basePtr);
  912. if (seq.Count > 0)
  913. {
  914. SeekableXPathNavigator nav = seq[0].Node.Node;
  915. long p = nav.CurrentPosition;
  916. nav.CurrentPosition = seq[0].Node.Position;
  917. mandatory = ExtractFromNavigator(nav);
  918. nav.CurrentPosition = p;
  919. }
  920. context.SetValue(context, seqArg.basePtr, mandatory);
  921. seqArg.basePtr++;
  922. }
  923. }
  924. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  925. {
  926. XPathNodeIterator iter = (XPathNodeIterator)args[0];
  927. if (!iter.MoveNext())
  928. {
  929. return false;
  930. }
  931. return ExtractFromNavigator(iter.Current.Clone());
  932. }
  933. internal static bool ExtractFromNavigator(XPathNavigator nav)
  934. {
  935. string mand11 = nav.GetAttribute(XPathMessageContext.MandatoryA, XPathMessageContext.S11NS);
  936. string mand12 = nav.GetAttribute(XPathMessageContext.MandatoryA, XPathMessageContext.S12NS);
  937. nav.MoveToRoot();
  938. nav.MoveToFirstChild();
  939. if (nav.LocalName == XPathMessageContext.EnvelopeE && nav.NamespaceURI == XPathMessageContext.S11NS)
  940. {
  941. return mand11 == "1";
  942. }
  943. else if (nav.LocalName == XPathMessageContext.EnvelopeE && nav.NamespaceURI == XPathMessageContext.S12NS)
  944. {
  945. return mand12 == "true";
  946. }
  947. return false;
  948. }
  949. }
  950. internal class XPathMessageFunctionIsActorNext : XPathMessageFunction
  951. {
  952. static string S11Next = EnvelopeVersion.Soap11.NextDestinationActorValue;
  953. static string S12Next = EnvelopeVersion.Soap12.NextDestinationActorValue;
  954. internal XPathMessageFunctionIsActorNext()
  955. : base(new XPathResultType[] { XPathResultType.NodeSet }, 1, 1, XPathResultType.Boolean)
  956. {
  957. }
  958. internal override void InvokeInternal(ProcessingContext context, int argCount)
  959. {
  960. StackFrame seqArg = context.TopArg;
  961. while (seqArg.basePtr <= seqArg.endPtr)
  962. {
  963. bool next = false;
  964. NodeSequence seq = context.PeekSequence(seqArg.basePtr);
  965. if (seq.Count > 0)
  966. {
  967. SeekableXPathNavigator nav = seq[0].Node.Node;
  968. long p = nav.CurrentPosition;
  969. nav.CurrentPosition = seq[0].Node.Position;
  970. next = ExtractFromNavigator(nav);
  971. nav.CurrentPosition = p;
  972. }
  973. context.SetValue(context, seqArg.basePtr, next);
  974. seqArg.basePtr++;
  975. }
  976. }
  977. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator nav)
  978. {
  979. XPathNodeIterator iter = (XPathNodeIterator)args[0];
  980. if (!iter.MoveNext())
  981. {
  982. return false;
  983. }
  984. return ExtractFromNavigator(iter.Current.Clone());
  985. }
  986. internal static bool ExtractFromNavigator(XPathNavigator nav)
  987. {
  988. string actor = XPathMessageFunctionActor.ExtractFromNavigator(nav);
  989. if (actor.Length == 0)
  990. {
  991. return false;
  992. }
  993. nav.MoveToRoot();
  994. if (!nav.MoveToFirstChild())
  995. {
  996. return false;
  997. }
  998. if (nav.LocalName == XPathMessageContext.EnvelopeE)
  999. {
  1000. if (nav.NamespaceURI == XPathMessageContext.S11NS)
  1001. {
  1002. return actor == S11Next;
  1003. }
  1004. else if (nav.NamespaceURI == XPathMessageContext.S12NS)
  1005. {
  1006. return actor == S12Next;
  1007. }
  1008. }
  1009. return false;
  1010. }
  1011. }
  1012. internal class XPathMessageFunctionIsActorUltimateReceiver : XPathMessageFunction
  1013. {
  1014. static string S11UltRec = EnvelopeVersion.Soap11.UltimateDestinationActor;
  1015. static string S12UltRec = EnvelopeVersion.Soap12.UltimateDestinationActor;
  1016. internal XPathMessageFunctionIsActorUltimateReceiver()
  1017. : base(new XPathResultType[] { XPathResultType.NodeSet }, 1, 1, XPathResultType.Boolean)
  1018. {
  1019. }
  1020. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1021. {
  1022. StackFrame seqArg = context.TopArg;
  1023. while (seqArg.basePtr <= seqArg.endPtr)
  1024. {
  1025. bool ult = false;
  1026. NodeSequence seq = context.PeekSequence(seqArg.basePtr);
  1027. if (seq.Count > 0)
  1028. {
  1029. SeekableXPathNavigator nav = seq[0].Node.Node;
  1030. long p = nav.CurrentPosition;
  1031. nav.CurrentPosition = seq[0].Node.Position;
  1032. ult = ExtractFromNavigator(nav);
  1033. nav.CurrentPosition = p;
  1034. }
  1035. context.SetValue(context, seqArg.basePtr, ult);
  1036. seqArg.basePtr++;
  1037. }
  1038. }
  1039. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator nav)
  1040. {
  1041. XPathNodeIterator iter = (XPathNodeIterator)args[0];
  1042. if (!iter.MoveNext())
  1043. {
  1044. return false;
  1045. }
  1046. return ExtractFromNavigator(iter.Current.Clone());
  1047. }
  1048. internal static bool ExtractFromNavigator(XPathNavigator nav)
  1049. {
  1050. string actor = XPathMessageFunctionActor.ExtractFromNavigator(nav);
  1051. nav.MoveToRoot();
  1052. if (!nav.MoveToFirstChild())
  1053. {
  1054. return false;
  1055. }
  1056. if (nav.LocalName == XPathMessageContext.EnvelopeE)
  1057. {
  1058. if (nav.NamespaceURI == XPathMessageContext.S11NS)
  1059. {
  1060. return actor == S11UltRec;
  1061. }
  1062. else if (nav.NamespaceURI == XPathMessageContext.S12NS)
  1063. {
  1064. return actor == S12UltRec;
  1065. }
  1066. }
  1067. return false;
  1068. }
  1069. }
  1070. internal class XPathMessageFunctionHeadersWithActor : XPathMessageFunction
  1071. {
  1072. internal XPathMessageFunctionHeadersWithActor()
  1073. : base(new XPathResultType[] { XPathResultType.String }, 1, 1, XPathResultType.NodeSet)
  1074. {
  1075. }
  1076. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1077. {
  1078. StackFrame actorArg = context.TopArg;
  1079. SeekableXPathNavigator nav = context.Processor.ContextNode;
  1080. long p = nav.CurrentPosition;
  1081. while (actorArg.basePtr <= actorArg.endPtr)
  1082. {
  1083. string actor = context.PeekString(actorArg.basePtr);
  1084. NodeSequence seq = context.CreateSequence();
  1085. if (MoveToHeader(nav) && nav.MoveToFirstChild())
  1086. {
  1087. do
  1088. {
  1089. // PERF, [....], this will be faster if I cache the envelope namespace to do the
  1090. // actor lookup by hand
  1091. long pos = nav.CurrentPosition;
  1092. string navActor = XPathMessageFunctionActor.ExtractFromNavigator(nav);
  1093. nav.CurrentPosition = pos;
  1094. if (navActor == actor)
  1095. {
  1096. seq.Add(nav);
  1097. }
  1098. } while (nav.MoveToNext());
  1099. }
  1100. context.SetValue(context, actorArg.basePtr, seq);
  1101. actorArg.basePtr++;
  1102. }
  1103. nav.CurrentPosition = p;
  1104. }
  1105. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1106. {
  1107. string actor = ToString(args[0]);
  1108. string e = string.Format(CultureInfo.InvariantCulture, "/s11:Envelope/s11:Header/*[@s11:actor='{0}'] | /s12:Envelope/s12:Header/*[@s12:role='{1}']", actor, actor);
  1109. XPathExpression expr = docContext.Compile(e);
  1110. expr.SetContext(xsltContext);
  1111. return docContext.Evaluate(expr);
  1112. #if NO
  1113. // PERF, [....], I drafted this implementation before we found out that a bug in the Fx implementation would
  1114. // prevent us from constructing an XPathNodeIterator that they would accept. I'm keeping it
  1115. // around in the hope that I will be able to use it by M5.4. If not, it will be deleted.
  1116. XPathNavigator basicNav = docContext.Clone();
  1117. SeekableXPathNavigator nav = basicNav as SeekableXPathNavigator;
  1118. if(nav == null)
  1119. {
  1120. nav = new GenericSeekableNavigator(basicNav);
  1121. }
  1122. string actor = (string)args[0];
  1123. NodeSequence seq = new NodeSequence();
  1124. XPathNodeIterator result = new NodeSequenceIterator(seq);
  1125. nav.MoveToRoot();
  1126. if(!nav.MoveToFirstChild())
  1127. {
  1128. return result;
  1129. }
  1130. if(nav.LocalName != "Envelope")
  1131. {
  1132. return result;
  1133. }
  1134. if(nav.NamespaceURI == XPathMessageContext.S11NS)
  1135. {
  1136. // Move to Header
  1137. if(nav.MoveToFirstChild() && nav.LocalName == "Header" && nav.NamespaceURI == XPathMessageContext.S11NS)
  1138. {
  1139. // Move to first Header block
  1140. if(nav.MoveToFirstChild())
  1141. {
  1142. // Iterate over header blocks
  1143. do
  1144. {
  1145. if(nav.MoveToAttribute("actor", XPathMessageContext.S11NS))
  1146. {
  1147. if(nav.Value == actor)
  1148. {
  1149. seq.Add(nav);
  1150. }
  1151. nav.MoveToParent();
  1152. }
  1153. } while(nav.MoveToNext());
  1154. }
  1155. }
  1156. }
  1157. else if(nav.NamespaceURI == XPathMessageContext.S12NS)
  1158. {
  1159. // Move to Header
  1160. if(nav.MoveToFirstChild() && nav.LocalName == "Header" && nav.NamespaceURI == XPathMessageContext.S12NS)
  1161. {
  1162. // Move to first Header block
  1163. if(nav.MoveToFirstChild())
  1164. {
  1165. // Iterate over header blocks
  1166. do
  1167. {
  1168. if(nav.MoveToAttribute("role", XPathMessageContext.S12NS))
  1169. {
  1170. if(nav.Value == actor)
  1171. {
  1172. seq.Add(nav);
  1173. }
  1174. nav.MoveToParent();
  1175. }
  1176. } while(nav.MoveToNext());
  1177. }
  1178. }
  1179. }
  1180. return result;
  1181. #endif
  1182. }
  1183. }
  1184. internal class XPathMessageFunctionRelatesTo : XPathMessageFunction
  1185. {
  1186. XPathExpression expr;
  1187. internal XPathMessageFunctionRelatesTo()
  1188. : base(new XPathResultType[] { }, 0, 0, XPathResultType.NodeSet)
  1189. {
  1190. }
  1191. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1192. {
  1193. int count = context.IterationCount;
  1194. context.PushSequenceFrame();
  1195. if (count > 0)
  1196. {
  1197. NodeSequence seq = context.CreateSequence();
  1198. seq.StartNodeset();
  1199. SeekableXPathNavigator nav = context.Processor.ContextNode;
  1200. long p = nav.CurrentPosition;
  1201. if (MoveToAddressingHeader(nav, XPathMessageContext.RelatesToE))
  1202. {
  1203. seq.Add(nav);
  1204. while (MoveToAddressingHeaderSibling(nav, XPathMessageContext.RelatesToE))
  1205. {
  1206. seq.Add(nav);
  1207. }
  1208. }
  1209. seq.StopNodeset();
  1210. context.PushSequence(seq);
  1211. for (int i = 1; i < count; ++i)
  1212. {
  1213. seq.refCount++;
  1214. context.PushSequence(seq);
  1215. }
  1216. nav.CurrentPosition = p;
  1217. }
  1218. }
  1219. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1220. {
  1221. if (this.expr == null)
  1222. {
  1223. XPathExpression e = docContext.Compile("sm:header()/wsa10:RelatesTo | sm:header()/wsaAugust2004:RelatesTo");
  1224. e.SetContext(new XPathMessageContext());
  1225. this.expr = e;
  1226. }
  1227. return docContext.Evaluate(this.expr);
  1228. }
  1229. }
  1230. internal class XPathMessageFunctionReplyTo : XPathMessageFunction
  1231. {
  1232. XPathExpression expr;
  1233. internal XPathMessageFunctionReplyTo()
  1234. : base(new XPathResultType[] { }, 0, 0, XPathResultType.NodeSet)
  1235. {
  1236. }
  1237. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1238. {
  1239. int count = context.IterationCount;
  1240. context.PushSequenceFrame();
  1241. if (count > 0)
  1242. {
  1243. NodeSequence seq = context.CreateSequence();
  1244. seq.StartNodeset();
  1245. SeekableXPathNavigator nav = context.Processor.ContextNode;
  1246. long p = nav.CurrentPosition;
  1247. if (MoveToAddressingHeader(nav, XPathMessageContext.ReplyToE))
  1248. {
  1249. seq.Add(nav);
  1250. }
  1251. seq.StopNodeset();
  1252. context.PushSequence(seq);
  1253. for (int i = 1; i < count; ++i)
  1254. {
  1255. seq.refCount++;
  1256. context.PushSequence(seq);
  1257. }
  1258. nav.CurrentPosition = p;
  1259. }
  1260. }
  1261. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1262. {
  1263. if (this.expr == null)
  1264. {
  1265. XPathExpression e = docContext.Compile("(sm:header()/wsa10:ReplyTo | sm:header()/wsaAugust2004:ReplyTo)[1]");
  1266. e.SetContext(new XPathMessageContext());
  1267. this.expr = e;
  1268. }
  1269. return docContext.Evaluate(this.expr);
  1270. }
  1271. }
  1272. internal class XPathMessageFunctionFrom : XPathMessageFunction
  1273. {
  1274. XPathExpression expr;
  1275. internal XPathMessageFunctionFrom()
  1276. : base(new XPathResultType[] { }, 0, 0, XPathResultType.NodeSet)
  1277. {
  1278. }
  1279. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1280. {
  1281. int count = context.IterationCount;
  1282. context.PushSequenceFrame();
  1283. if (count > 0)
  1284. {
  1285. NodeSequence seq = context.CreateSequence();
  1286. seq.StartNodeset();
  1287. SeekableXPathNavigator nav = context.Processor.ContextNode;
  1288. long p = nav.CurrentPosition;
  1289. if (MoveToAddressingHeader(nav, XPathMessageContext.FromE))
  1290. {
  1291. seq.Add(nav);
  1292. }
  1293. seq.StopNodeset();
  1294. context.PushSequence(seq);
  1295. for (int i = 1; i < count; ++i)
  1296. {
  1297. seq.refCount++;
  1298. context.PushSequence(seq);
  1299. }
  1300. nav.CurrentPosition = p;
  1301. }
  1302. }
  1303. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1304. {
  1305. if (this.expr == null)
  1306. {
  1307. XPathExpression e = docContext.Compile("(sm:header()/wsa10:From | sm:header()/wsaAugust2004:From)[1]");
  1308. e.SetContext(new XPathMessageContext());
  1309. this.expr = e;
  1310. }
  1311. return docContext.Evaluate(this.expr);
  1312. }
  1313. }
  1314. internal class XPathMessageFunctionFaultTo : XPathMessageFunction
  1315. {
  1316. XPathExpression expr;
  1317. internal XPathMessageFunctionFaultTo()
  1318. : base(new XPathResultType[] { }, 0, 0, XPathResultType.NodeSet)
  1319. {
  1320. }
  1321. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1322. {
  1323. int count = context.IterationCount;
  1324. context.PushSequenceFrame();
  1325. if (count > 0)
  1326. {
  1327. NodeSequence seq = context.CreateSequence();
  1328. seq.StartNodeset();
  1329. SeekableXPathNavigator nav = context.Processor.ContextNode;
  1330. long p = nav.CurrentPosition;
  1331. if (MoveToAddressingHeader(nav, XPathMessageContext.FaultToE))
  1332. {
  1333. seq.Add(nav);
  1334. }
  1335. seq.StopNodeset();
  1336. context.PushSequence(seq);
  1337. for (int i = 1; i < count; ++i)
  1338. {
  1339. seq.refCount++;
  1340. context.PushSequence(seq);
  1341. }
  1342. nav.CurrentPosition = p;
  1343. }
  1344. }
  1345. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1346. {
  1347. if (this.expr == null)
  1348. {
  1349. XPathExpression e = docContext.Compile("(sm:header()/wsa10:FaultTo | sm:header()/wsaAugust2004:FaultTo)[1]");
  1350. e.SetContext(new XPathMessageContext());
  1351. this.expr = e;
  1352. }
  1353. return docContext.Evaluate(this.expr);
  1354. }
  1355. }
  1356. internal class XPathMessageFunctionDateStr : XPathMessageFunction
  1357. {
  1358. internal XPathMessageFunctionDateStr()
  1359. : base(new XPathResultType[1] { XPathResultType.String }, 1, 1, XPathResultType.Number)
  1360. {
  1361. }
  1362. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1363. {
  1364. StackFrame dateArg = context.TopArg;
  1365. while (dateArg.basePtr <= dateArg.endPtr)
  1366. {
  1367. string dateStr = context.PeekString(dateArg.basePtr);
  1368. context.SetValue(context, dateArg.basePtr, Convert(dateStr));
  1369. dateArg.basePtr++;
  1370. }
  1371. }
  1372. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1373. {
  1374. return Convert(ToString(args[0]));
  1375. }
  1376. internal static double Convert(string dateStr)
  1377. {
  1378. try
  1379. {
  1380. return ConvertDate(DateTime.Parse(dateStr, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.RoundtripKind));
  1381. }
  1382. catch (FormatException)
  1383. {
  1384. return double.NaN;
  1385. }
  1386. }
  1387. }
  1388. internal class XPathMessageFunctionCorrelationData : XPathMessageFunction
  1389. {
  1390. static XPathResultType[] argTypes = new XPathResultType[1] { XPathResultType.String };
  1391. public XPathMessageFunctionCorrelationData()
  1392. : base(argTypes, 1, 1, XPathResultType.String)
  1393. {
  1394. }
  1395. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1396. {
  1397. StackFrame nameArg = context.TopArg;
  1398. Message message = context.Processor.ContextMessage;
  1399. CorrelationDataMessageProperty data = null;
  1400. CorrelationDataMessageProperty.TryGet(message, out data);
  1401. while (nameArg.basePtr <= nameArg.endPtr)
  1402. {
  1403. string value;
  1404. if (data == null || !data.TryGetValue(context.PeekString(nameArg.basePtr), out value))
  1405. {
  1406. value = string.Empty;
  1407. }
  1408. context.SetValue(context, nameArg.basePtr, value);
  1409. nameArg.basePtr++;
  1410. }
  1411. }
  1412. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1413. {
  1414. SeekableMessageNavigator nav = docContext as SeekableMessageNavigator;
  1415. if (nav != null)
  1416. {
  1417. Message message = nav.Message;
  1418. CorrelationDataMessageProperty data;
  1419. string value;
  1420. if (!CorrelationDataMessageProperty.TryGet(message, out data) ||
  1421. !data.TryGetValue((string)args[0], out value))
  1422. {
  1423. value = string.Empty;
  1424. }
  1425. return value;
  1426. }
  1427. else
  1428. {
  1429. return string.Empty;
  1430. }
  1431. }
  1432. }
  1433. internal class XPathMessageFunctionDateNow : XPathMessageFunction
  1434. {
  1435. internal XPathMessageFunctionDateNow()
  1436. : base(new XPathResultType[0], 0, 0, XPathResultType.Number)
  1437. {
  1438. }
  1439. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1440. {
  1441. context.PushFrame();
  1442. int count = context.IterationCount;
  1443. if (count > 0)
  1444. {
  1445. context.Push(ConvertDate(DateTime.Now), count);
  1446. }
  1447. }
  1448. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1449. {
  1450. return ConvertDate(DateTime.UtcNow);
  1451. }
  1452. }
  1453. internal class XPathMessageFunctionSpanStr : XPathMessageFunction
  1454. {
  1455. internal XPathMessageFunctionSpanStr()
  1456. : base(new XPathResultType[1] { XPathResultType.String }, 1, 1, XPathResultType.Number)
  1457. {
  1458. }
  1459. internal override void InvokeInternal(ProcessingContext context, int argCount)
  1460. {
  1461. StackFrame spanArg = context.TopArg;
  1462. while (spanArg.basePtr <= spanArg.endPtr)
  1463. {
  1464. string spanStr = context.PeekString(spanArg.basePtr);
  1465. context.SetValue(context, spanArg.basePtr, Convert(spanStr));
  1466. spanArg.basePtr++;
  1467. }
  1468. }
  1469. public override object Invoke(XsltContext xsltContext, object[] args, XPathNavigator docContext)
  1470. {
  1471. return Convert(ToString(args[0]));
  1472. }
  1473. internal static double Convert(string spanStr)
  1474. {
  1475. try
  1476. {
  1477. return TimeSpan.Parse(spanStr, CultureInfo.InvariantCulture).TotalDays;
  1478. }
  1479. catch (FormatException)
  1480. {
  1481. return double.NaN;
  1482. }
  1483. catch (OverflowException)
  1484. {
  1485. return double.NaN;
  1486. }
  1487. }
  1488. }
  1489. }