The Labs \ Source Viewer \ SSCLI \ System.Xml.Schema \ NamespaceListV1Compat

  1. //------------------------------------------------------------------------------
  2. // <copyright file="NamespaceList.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. // <owner current="true" primary="true">priyal</owner>
  15. //------------------------------------------------------------------------------
  16. namespace System.Xml.Schema
  17. {
  18.     using System.Collections;
  19.     using System.Text;
  20.     using System.Diagnostics;
  21.    
  22.     internal class NamespaceList
  23.     {
  24.         public enum ListType
  25.         {
  26.             Any,
  27.             Other,
  28.             Set
  29.         }
  30.        
  31.         private ListType type = ListType.Any;
  32.         private Hashtable set = null;
  33.         private string targetNamespace;
  34.        
  35.         public NamespaceList()
  36.         {
  37.         }
  38.        
  39.         public NamespaceList(string namespaces, string targetNamespace)
  40.         {
  41.             Debug.Assert(targetNamespace != null);
  42.             this.targetNamespace = targetNamespace;
  43.             namespaces = namespaces.Trim();
  44.             if (namespaces == "##any" || namespaces.Length == 0) {
  45.                 type = ListType.Any;
  46.             }
  47.             else if (namespaces == "##other") {
  48.                 type = ListType.Other;
  49.             }
  50.             else {
  51.                 type = ListType.Set;
  52.                 set = new Hashtable();
  53.                 foreach (string ns in XmlConvert.SplitString(namespaces)) {
  54.                     if (ns == "##local") {
  55.                         set[string.Empty] = string.Empty;
  56.                     }
  57.                     else if (ns == "##targetNamespace") {
  58.                         set[targetNamespace] = targetNamespace;
  59.                     }
  60.                     else {
  61.                         XmlConvert.ToUri(ns);
  62.                         // can throw
  63.                         set[ns] = ns;
  64.                     }
  65.                 }
  66.             }
  67.         }
  68.        
  69.         public NamespaceList Clone()
  70.         {
  71.             NamespaceList nsl = (NamespaceList)MemberwiseClone();
  72.             if (type == ListType.Set) {
  73.                 Debug.Assert(set != null);
  74.                 nsl.set = (Hashtable)(set.Clone());
  75.             }
  76.             return nsl;
  77.         }
  78.        
  79.         public ListType Type {
  80.             get { return type; }
  81.         }
  82.        
  83.         public string Excluded {
  84.             get { return targetNamespace; }
  85.         }
  86.        
  87.         public ICollection Enumerate {
  88.             get {
  89.                 switch (type) {
  90.                     case ListType.Set:
  91.                         return set.Keys;
  92.                     case ListType.Other:
  93.                     case ListType.Any:
  94.                     default:
  95.                         throw new InvalidOperationException();
  96.                         break;
  97.                 }
  98.             }
  99.         }
  100.        
  101.         public virtual bool Allows(string ns)
  102.         {
  103.             switch (type) {
  104.                 case ListType.Any:
  105.                     return true;
  106.                 case ListType.Other:
  107.                     return ns != targetNamespace && ns.Length != 0;
  108.                 case ListType.Set:
  109.                     return set[ns] != null;
  110.             }
  111.             Debug.Assert(false);
  112.             return false;
  113.         }
  114.        
  115.         public bool Allows(XmlQualifiedName qname)
  116.         {
  117.             return Allows(qname.Namespace);
  118.         }
  119.        
  120.         public override string ToString()
  121.         {
  122.             switch (type) {
  123.                 case ListType.Any:
  124.                     return "##any";
  125.                 case ListType.Other:
  126.                     return "##other";
  127.                 case ListType.Set:
  128.                     StringBuilder sb = new StringBuilder();
  129.                     bool first = true;
  130.                     foreach (string s in set.Keys) {
  131.                         if (first) {
  132.                             first = false;
  133.                         }
  134.                         else {
  135.                             sb.Append(" ");
  136.                         }
  137.                         if (s == targetNamespace) {
  138.                             sb.Append("##targetNamespace");
  139.                         }
  140.                         else if (s.Length == 0) {
  141.                             sb.Append("##local");
  142.                         }
  143.                         else {
  144.                             sb.Append(s);
  145.                         }
  146.                     }
  147.                     return sb.ToString();
  148.             }
  149.             Debug.Assert(false);
  150.             return string.Empty;
  151.         }
  152.        
  153.         public static bool IsSubset(NamespaceList sub, NamespaceList super)
  154.         {
  155.             if (super.type == ListType.Any) {
  156.                 return true;
  157.             }
  158.             else if (sub.type == ListType.Other && super.type == ListType.Other) {
  159.                 return super.targetNamespace == sub.targetNamespace;
  160.             }
  161.             else if (sub.type == ListType.Set) {
  162.                 if (super.type == ListType.Other) {
  163.                     return !sub.set.Contains(super.targetNamespace);
  164.                 }
  165.                 else {
  166.                     Debug.Assert(super.type == ListType.Set);
  167.                     foreach (string ns in sub.set.Keys) {
  168.                         if (!super.set.Contains(ns)) {
  169.                             return false;
  170.                         }
  171.                     }
  172.                     return true;
  173.                 }
  174.             }
  175.             return false;
  176.         }
  177.        
  178.        
  179.         public static NamespaceList Union(NamespaceList o1, NamespaceList o2, bool v1Compat)
  180.         {
  181.             NamespaceList nslist = null;
  182.             Debug.Assert(o1 != o2);
  183.             if (o1.type == ListType.Any) {
  184.                 //clause 2 - o1 is Any
  185.                 nslist = new NamespaceList();
  186.             }
  187.             else if (o2.type == ListType.Any) {
  188.                 //clause 2 - o2 is Any
  189.                 nslist = new NamespaceList();
  190.             }
  191.             else if (o1.type == ListType.Set && o2.type == ListType.Set) {
  192.                 //clause 3 , both are sets
  193.                 nslist = o1.Clone();
  194.                 foreach (string ns in o2.set.Keys) {
  195.                     nslist.set[ns] = ns;
  196.                 }
  197.             }
  198.             else if (o1.type == ListType.Other && o2.type == ListType.Other) {
  199.                 //clause 4, both are negations
  200.                 if (o1.targetNamespace == o2.targetNamespace) {
  201.                     //negation of same value
  202.                     nslist = o1.Clone();
  203.                 }
  204.                 else {
  205.                     nslist = new NamespaceList("##other", string.Empty);
  206.                     //clause 4, negations of different values, result is not(absent)
  207.                 }
  208.             }
  209.             else if (o1.type == ListType.Set && o2.type == ListType.Other) {
  210.                 if (v1Compat) {
  211.                     if (o1.set.Contains(o2.targetNamespace)) {
  212.                         nslist = new NamespaceList();
  213.                     }
  214.                     else {
  215.                         //This was not there originally in V1, added for consistency since its not breaking
  216.                         nslist = o2.Clone();
  217.                     }
  218.                 }
  219.                 else {
  220.                     if (o2.targetNamespace != string.Empty) {
  221.                         //clause 5, o1 is set S, o2 is not(tns)
  222.                         nslist = o1.CompareSetToOther(o2);
  223.                     }
  224.                     else if (o1.set.Contains(string.Empty)) {
  225.                         //clause 6.1 - set S includes absent, o2 is not(absent)
  226.                         nslist = new NamespaceList();
  227.                     }
  228.                     else {
  229.                         //clause 6.2 - set S does not include absent, result is not(absent)
  230.                         nslist = new NamespaceList("##other", string.Empty);
  231.                     }
  232.                 }
  233.             }
  234.             else if (o2.type == ListType.Set && o1.type == ListType.Other) {
  235.                 if (v1Compat) {
  236.                     if (o2.set.Contains(o2.targetNamespace)) {
  237.                         nslist = new NamespaceList();
  238.                     }
  239.                     else {
  240.                         nslist = o1.Clone();
  241.                     }
  242.                 }
  243.                 else {
  244.                     //New rules
  245.                     if (o1.targetNamespace != string.Empty) {
  246.                         //clause 5, o1 is set S, o2 is not(tns)
  247.                         nslist = o2.CompareSetToOther(o1);
  248.                     }
  249.                     else if (o2.set.Contains(string.Empty)) {
  250.                         //clause 6.1 - set S includes absent, o2 is not(absent)
  251.                         nslist = new NamespaceList();
  252.                     }
  253.                     else {
  254.                         //clause 6.2 - set S does not include absent, result is not(absent)
  255.                         nslist = new NamespaceList("##other", string.Empty);
  256.                     }
  257.                 }
  258.             }
  259.             return nslist;
  260.         }
  261.        
  262.         private NamespaceList CompareSetToOther(NamespaceList other)
  263.         {
  264.             //clause 5.1
  265.             NamespaceList nslist = null;
  266.             if (this.set.Contains(other.targetNamespace)) {
  267.                 //S contains negated ns
  268.                 if (this.set.Contains(string.Empty)) {
  269.                     // AND S contains absent
  270.                     nslist = new NamespaceList();
  271.                     //any is the result
  272.                 }
  273.                 else {
  274.                     //clause 5.2
  275.                     nslist = new NamespaceList("##other", string.Empty);
  276.                 }
  277.             }
  278.             else if (this.set.Contains(string.Empty)) {
  279.                 //clause 5.3 - Not expressible
  280.                 nslist = null;
  281.             }
  282.             else {
  283.                 //clause 5.4 - Set S does not contain negated ns or absent
  284.                 nslist = other.Clone();
  285.             }
  286.             return nslist;
  287.         }
  288.        
  289.         public static NamespaceList Intersection(NamespaceList o1, NamespaceList o2, bool v1Compat)
  290.         {
  291.             NamespaceList nslist = null;
  292.             Debug.Assert(o1 != o2);
  293.             //clause 1
  294.             if (o1.type == ListType.Any) {
  295.                 //clause 2 - o1 is any
  296.                 nslist = o2.Clone();
  297.             }
  298.             else if (o2.type == ListType.Any) {
  299.                 //clause 2 - o2 is any
  300.                 nslist = o1.Clone();
  301.             }
  302.             else if (o1.type == ListType.Set && o2.type == ListType.Other) {
  303.                 //Clause 3 o2 is other
  304.                 nslist = o1.Clone();
  305.                 nslist.RemoveNamespace(o2.targetNamespace);
  306.                 if (!v1Compat) {
  307.                     nslist.RemoveNamespace(string.Empty);
  308.                     //remove ##local
  309.                 }
  310.             }
  311.             else if (o1.type == ListType.Other && o2.type == ListType.Set) {
  312.                 //Clause 3 o1 is other
  313.                 nslist = o2.Clone();
  314.                 nslist.RemoveNamespace(o1.targetNamespace);
  315.                 if (!v1Compat) {
  316.                     nslist.RemoveNamespace(string.Empty);
  317.                     //remove ##local
  318.                 }
  319.             }
  320.             else if (o1.type == ListType.Set && o2.type == ListType.Set) {
  321.                 //clause 4
  322.                 nslist = o1.Clone();
  323.                 nslist = new NamespaceList();
  324.                 nslist.type = ListType.Set;
  325.                 nslist.set = new Hashtable();
  326.                 foreach (string ns in o1.set.Keys) {
  327.                     if (o2.set.Contains(ns)) {
  328.                         nslist.set.Add(ns, ns);
  329.                     }
  330.                 }
  331.             }
  332.             else if (o1.type == ListType.Other && o2.type == ListType.Other) {
  333.                 if (o1.targetNamespace == o2.targetNamespace) {
  334.                     //negation of same namespace name
  335.                     nslist = o1.Clone();
  336.                     return nslist;
  337.                 }
  338.                 if (!v1Compat) {
  339.                     if (o1.targetNamespace == string.Empty) {
  340.                         // clause 6 - o1 is negation of absent
  341.                         nslist = o2.Clone();
  342.                     }
  343.                     else if (o2.targetNamespace == string.Empty) {
  344.                         //clause 6 - o1 is negation of absent
  345.                         nslist = o1.Clone();
  346.                     }
  347.                 }
  348.                 //if it comes here, its not expressible //clause 5
  349.             }
  350.             return nslist;
  351.         }
  352.        
  353.         private void RemoveNamespace(string tns)
  354.         {
  355.             if (this.set[tns] != null) {
  356.                 this.set.Remove(tns);
  357.             }
  358.         }
  359.        
  360.         public bool IsEmpty()
  361.         {
  362.             return ((type == ListType.Set) && ((set == null) || set.Count == 0));
  363.         }
  364.        
  365.     }
  366.    
  367.     internal class NamespaceListV1Compat : NamespaceList
  368.     {
  369.         public NamespaceListV1Compat(string namespaces, string targetNamespace) : base(namespaces, targetNamespace)
  370.         {
  371.         }
  372.        
  373.         public override bool Allows(string ns)
  374.         {
  375.             if (this.Type == ListType.Other) {
  376.                 return ns != Excluded;
  377.             }
  378.             else {
  379.                 return base.Allows(ns);
  380.             }
  381.         }
  382.     }
  383. }

Developer Fusion