/branches/2.0/XObjects/Src/API/FsmXObjects.cs

# · C# · 148 lines · 123 code · 21 blank · 4 comment · 42 complexity · 7da5f70c9ec820b2f16797b5f4ac5304 MD5 · raw file

  1. //Copyright (c) Microsoft Corporation. All rights reserved.
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Xml;
  6. using System.Xml.Schema;
  7. using System.Xml.Linq;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Threading;
  11. using System.Diagnostics;
  12. using System.Reflection;
  13. using Xml.Schema.Linq.CodeGen;
  14. using System.Text;
  15. //Defines interfaces involving FSM executions
  16. namespace Xml.Schema.Linq {
  17. public partial class XTypedElement {
  18. [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  19. private int currentState;
  20. [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  21. internal FSM ValidationStates {
  22. get {
  23. IXMetaData metaData = this as IXMetaData;
  24. Debug.Assert(metaData != null);
  25. return metaData.GetValidationStates();
  26. }
  27. }
  28. FSM IXMetaData.GetValidationStates() {
  29. return null;
  30. }
  31. internal void StartFsm() {
  32. if (this.ValidationStates != null) currentState = ValidationStates.Start;
  33. }
  34. internal int FsmMakeTransition(int prevState, XName inputSymbol, out XName matchingName, out WildCard matchingWildCard) {
  35. Transitions currTrans = ValidationStates.Trans[prevState];
  36. return currTrans.GetNextState(inputSymbol, out matchingName, out matchingWildCard);
  37. }
  38. internal XElement ExecuteFSM(IEnumerator<XElement> enumerator, XName requestingXName, WildCard requestingWildCard) {
  39. XElement currElem = null;
  40. WildCard matchingWildCard = null;
  41. XName matchingName = null;
  42. while(enumerator.MoveNext()){
  43. currElem = enumerator.Current;
  44. currentState = FsmMakeTransition(currentState, currElem.Name, out matchingName, out matchingWildCard);
  45. if (currentState!= FSM.InvalidState) {
  46. if ( (requestingXName != null) && (matchingName != null)) {
  47. if (requestingXName.Equals(currElem.Name)) return currElem;
  48. }
  49. else if ( (requestingWildCard != null) && (matchingWildCard != null) ){//requesting for ANY
  50. if (requestingWildCard.Allows(currElem.Name)) //Make sure current element is allowed by requesting ANY property
  51. return currElem;
  52. }
  53. }
  54. else {//Get stuck. No recovery attempt is provided for now.
  55. return null;
  56. }
  57. }
  58. //No matching elements/wildcards are found
  59. return null;
  60. }
  61. internal XElement ExecuteFSMSubGroup(IEnumerator<XElement> enumerator, XName[] namesInList) {
  62. Debug.Assert(namesInList != null);
  63. XElement currElem = null;
  64. WildCard matchingWildCard = null;
  65. XName matchingName = null;
  66. while(enumerator.MoveNext()){
  67. currElem = enumerator.Current;
  68. currentState = FsmMakeTransition(currentState, currElem.Name, out matchingName, out matchingWildCard);
  69. if (currentState!= FSM.InvalidState) {
  70. if ( matchingName != null)
  71. for(int i =0; i < namesInList.Length; i++) {
  72. if (namesInList.GetValue(i).Equals(currElem.Name)) return currElem;
  73. }
  74. }
  75. else {//Get stuck. No recovery attempt is provided for now.
  76. return null;
  77. }
  78. }
  79. //No matching elements/wildcards are found
  80. return null;
  81. }
  82. private void FSMSetElement(XName name, object value, bool addToExisting, XmlSchemaDatatype datatype) {
  83. XElement parentElement = this.GetUntyped();
  84. CheckXsiNil(parentElement);
  85. if (value == null) { //Delete existing node
  86. DeleteChild(name);
  87. }
  88. else if (datatype != null) { //Simple typed element
  89. XElement pos = this.GetElement(name);//Find out the matching element
  90. if (pos == null) { //happens for incomplete content, or choice
  91. parentElement.Add(new XElement(name, XTypedServices.GetXmlString(value, datatype, parentElement)));
  92. }
  93. else if (addToExisting) {
  94. pos.AddAfterSelf(new XElement(name, XTypedServices.GetXmlString(value, datatype, pos)));
  95. }
  96. else { //Update value in place
  97. pos.Value = XTypedServices.GetXmlString(value, datatype, pos);
  98. }
  99. }
  100. else { //Setting XTypedElement
  101. XTypedElement xObj = value as XTypedElement;
  102. XElement newElement = XTypedServices.GetXElement(xObj, name);
  103. XElement pos = this.GetElement(name);//Find the matching element
  104. if (pos == null) {//happens for incomplete content, or choice
  105. parentElement.Add(newElement);
  106. }
  107. else {
  108. pos.AddAfterSelf(newElement);
  109. if (!addToExisting) {
  110. pos.Remove();
  111. }
  112. }
  113. }
  114. }
  115. protected IEnumerable<XElement> GetWildCards(WildCard requestingWildCard) {
  116. IEnumerator<XElement> enumerator = this.GetUntyped().Elements().GetEnumerator();
  117. XElement elem = null;
  118. StartFsm();
  119. do {
  120. elem = ExecuteFSM(enumerator, null, requestingWildCard);
  121. if (elem != null) yield return elem;
  122. else yield break;
  123. }
  124. while(elem != null);
  125. }
  126. }
  127. }