d82d7ad716297adde4e4f3906eb02ee560c21399
[mono.git] / mcs / class / referencesource / System.Data.SqlXml / System / Xml / Xsl / XmlQualifiedNameTest.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XmlQualifiedNameTest.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
7
8 using System;
9 using System.Xml;
10 using System.Xml.Schema;
11 using System.Collections.Generic;
12 using System.Diagnostics;
13 using System.Text;
14
15 namespace System.Xml.Xsl {
16
17     /// <summary>
18     /// XmlQualifiedName extends XmlQualifiedName to support wildcards and adds nametest functionality
19     /// Following are the examples:
20     ///     {A}:B     XmlQualifiedNameTest.New("B", "A")        Match QName with namespace A        and local name B
21     ///     *         XmlQualifiedNameTest.New(null, null)      Match any QName
22     ///     {A}:*     XmlQualifiedNameTest.New(null, "A")       Match QName with namespace A        and any local name
23     ///               XmlQualifiedNameTest.New("A", false)
24     ///     *:B       XmlQualifiedNameTest.New("B", null)       Match QName with any namespace      and local name B
25     ///     ~{A}:*    XmlQualifiedNameTest.New("B", "A")        Match QName with namespace not A    and any local name
26     ///     {~A}:B    only as a result of the intersection      Match QName with namespace not A    and local name B
27     /// </summary>
28     internal class XmlQualifiedNameTest : XmlQualifiedName {
29         bool exclude;
30         const string wildcard = "*";
31         static XmlQualifiedNameTest wc = XmlQualifiedNameTest.New(wildcard, wildcard);
32
33         /// <summary>
34         /// Full wildcard
35         /// </summary>
36         public static XmlQualifiedNameTest Wildcard {
37             get { return wc; }
38         }
39
40         /// <summary>
41         /// Constructor
42         /// </summary>
43         private XmlQualifiedNameTest(string name, string ns, bool exclude) : base (name, ns) {
44             this.exclude = exclude;
45         }
46
47         /// <summary>
48         /// Construct new from name and namespace. Returns singleton Wildcard in case full wildcard
49         /// </summary>
50         public static XmlQualifiedNameTest New(string name, string ns) {
51             if (ns == null && name == null) {
52                 return Wildcard;
53             }
54             else {
55                 return new XmlQualifiedNameTest(name == null ? wildcard : name, ns == null ? wildcard : ns, false);
56             }
57         }
58
59         /// <summary>
60         /// True if matches any name and any namespace
61         /// </summary>
62         public bool IsWildcard {
63             get { return (object)this == (object)Wildcard; }
64         }
65
66         /// <summary>
67         /// True if matches any name
68         /// </summary>
69         public bool IsNameWildcard {
70             get { return (object)this.Name == (object)wildcard; }
71         }
72
73         /// <summary>
74         /// True if matches any namespace
75         /// </summary>
76         public bool IsNamespaceWildcard {
77             get { return (object)this.Namespace == (object)wildcard; }
78         }
79
80         private bool IsNameSubsetOf(XmlQualifiedNameTest other) {
81             return other.IsNameWildcard || this.Name == other.Name;
82         }
83
84         // 
85         private bool IsNamespaceSubsetOf(XmlQualifiedNameTest other) {
86             return other.IsNamespaceWildcard
87                 || (this.exclude == other.exclude && this.Namespace == other.Namespace)
88                 || (other.exclude && !this.exclude && this.Namespace != other.Namespace);
89         }
90
91         /// <summary>
92         /// True if this matches every QName other does
93         /// </summary>
94         public bool IsSubsetOf(XmlQualifiedNameTest other) {
95             return IsNameSubsetOf(other) && IsNamespaceSubsetOf(other);
96         }
97
98         /// <summary>
99         /// Return true if the result of intersection with other is not empty
100         /// </summary>
101         public bool HasIntersection(XmlQualifiedNameTest other) {
102             return (IsNamespaceSubsetOf(other) || other.IsNamespaceSubsetOf(this)) && (IsNameSubsetOf(other) || other.IsNameSubsetOf(this));
103         }
104
105         /// <summary>
106         /// String representation
107         /// </summary>
108         public override string ToString() {
109             if ((object)this == (object)Wildcard) {
110                 return "*";
111             }
112             else {
113                 if (this.Namespace.Length == 0) {
114                     return this.Name;
115                 }
116                 else if ((object)this.Namespace == (object)wildcard) {
117                     return "*:" + this.Name;
118                 }
119                 else if (this.exclude) {
120                     return  "{~" + this.Namespace + "}:" + this.Name;
121                 }
122                 else {
123                     return  "{" + this.Namespace + "}:" + this.Name;
124                 }
125             }
126         }
127
128         #if SchemaTypeImport
129         /// <summary>
130         /// Construct new from XmlQualifiedName. Returns singleton Wildcard in case full wildcard
131         /// </summary>
132         public static XmlQualifiedNameTest New(XmlQualifiedName name) {
133             if (name.IsEmpty) {
134                 return Wildcard;
135             }
136             else {
137                 return new XmlQualifiedNameTest(name.Name, name.Namespace, false);
138             }
139         }
140
141         /// <summary>
142         /// Construct new "exclusion" name test
143         /// </summary>
144         public static XmlQualifiedNameTest New(string ns, bool exclude) {
145             Debug.Assert(ns != null);
146             return new XmlQualifiedNameTest(wildcard, ns, exclude);
147         }
148
149         /// <summary>
150         /// Return the result of intersection with other
151         /// </summary>
152         public XmlQualifiedNameTest Intersect(XmlQualifiedNameTest other) {
153             // Namespace
154             // this\other   ~y                          *               y
155             //        ~x    x=y ? this|other : null     this            x!=y ? other : null
156             //         *    other                       this|other      other
157             //         x    x!=y ? this : null          this            x=y ? this|other : null
158             XmlQualifiedNameTest namespaceFrom = IsNamespaceSubsetOf(other) ? this : other.IsNamespaceSubsetOf(this) ? other : null;
159             XmlQualifiedNameTest nameFrom = IsNameSubsetOf(other) ? this : other.IsNameSubsetOf(this) ? other : null;
160
161             if ((object)namespaceFrom == (object)nameFrom) {
162                 return namespaceFrom;
163             }
164             else if (namespaceFrom == null || nameFrom == null) {
165                 return null;
166             }
167             else {
168                 return new XmlQualifiedNameTest(nameFrom.Name, namespaceFrom.Namespace, namespaceFrom.ExcludeNamespace);
169             }
170         }
171
172         /// <summary>
173         /// True if neither name nor namespace is a wildcard
174         /// </summary>
175         public bool IsSingleName {
176             get { return (object)this.Name != (object)wildcard && (object)this.Namespace != (object)wildcard  && this.exclude == false; }
177         }
178
179         /// <summary>
180         /// True if matches any namespace other then this.Namespace
181         /// </summary>
182         public bool ExcludeNamespace {
183             get { return this.exclude; }
184         }
185         #endif
186     }
187 }