2003-10-21 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / Mono.Xml.Schema / XsdKeyTable.cs
1 //
2 // Mono.Xml.Schema.XsdKeyTable.cs
3 //
4 // Author:
5 //      Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
6 //
7 //      (C)2003 Atsushi Enomoto
8 //
9 using System;\r
10 using System.Collections;\r
11 using System.Collections.Specialized;\r
12 using System.Xml;\r
13 using System.Xml.Schema;\r
14 \r
15 namespace Mono.Xml.Schema\r
16 {\r
17         // Created per constraining element.\r
18         public class XsdKeyTable\r
19         {\r
20                 /*\r
21                 private ArrayList entries = new ArrayList ();\r
22                 private ArrayList finishedEntries = new ArrayList ();\r
23                 private XsdKeyEntry [] cachedEntries;\r
24                 private XsdKeyEntry [] cachedFinishedEntries;\r
25                 */\r
26 \r
27                 private XsdIdentitySelector selector;\r
28                 private XmlSchemaIdentityConstraint source;\r
29                 private XmlQualifiedName qname;\r
30                 private XmlQualifiedName refKeyName;\r
31 \r
32                 public ArrayList Entries = new ArrayList ();\r
33                 public ArrayList FinishedEntries = new ArrayList ();\r
34 \r
35                 public int StartDepth;\r
36                 public XsdKeyTable ReferencedKey;\r
37 \r
38                 public XsdKeyTable (XmlSchemaIdentityConstraint source, XmlReader reader)\r
39                 {\r
40                         Reset (source, reader);\r
41                 }\r
42 \r
43                 /*\r
44                 public XsdKeyEntry [] Entries {\r
45                         get {\r
46                                 if (cachedEntries == null)\r
47                                         cachedEntries = entries.ToArray (typeof (XsdKeyEntry)) as XsdKeyEntry [];\r
48                                 return cachedEntries;\r
49                         }\r
50                 }\r
51 \r
52                 public XsdKeyEntry [] FinishedEntries {\r
53                         get {\r
54                                 if (cachedFinishedEntries == null)\r
55                                         cachedFinishedEntries = finishedEntries.ToArray (typeof (XsdKeyEntry)) as XsdKeyEntry [];\r
56                                 return cachedFinishedEntries;\r
57                         }\r
58                 }\r
59                 */\r
60 \r
61                 public XmlQualifiedName QualifiedName {\r
62                         get { return qname; }\r
63                 }\r
64 \r
65                 public XmlQualifiedName RefKeyName {\r
66                         get { return refKeyName; }\r
67                 }\r
68 \r
69                 public XmlSchemaIdentityConstraint SourceSchemaIdentity {\r
70                         get { return source; }\r
71                 }\r
72 \r
73                 public XsdIdentitySelector Selector {\r
74                         get { return selector; }\r
75                 }\r
76 \r
77                 public void Reset (XmlSchemaIdentityConstraint source, XmlReader reader)\r
78                 {\r
79                         this.source = source;\r
80                         this.selector = source.CompiledSelector;\r
81                         this.qname = source.QualifiedName;\r
82                         XmlSchemaKeyref kr = source as XmlSchemaKeyref;\r
83                         if (kr != null)\r
84                                 this.refKeyName = kr.Refer;\r
85                         StartDepth = 0;\r
86                 }\r
87 \r
88                 // In this method, attributes are ignored.\r
89                 public XsdIdentityPath SelectorMatches (ArrayList qnameStack, XmlReader reader)\r
90                 {\r
91                         foreach (XsdIdentityPath path in Selector.Paths) {\r
92                                 // Only "." hits.\r
93                                 if (reader.Depth == this.StartDepth) {\r
94                                         if (path.OrderedSteps.Length == 0)\r
95                                                 return path;\r
96                                         else\r
97                                                 continue;\r
98                                 }\r
99                                 // It does not hit as yet (too shallow to hit).\r
100                                 if (reader.Depth - this.StartDepth < path.OrderedSteps.Length - 1)\r
101                                         continue;\r
102 \r
103                                 int iter = path.OrderedSteps.Length;\r
104                                 if (path.OrderedSteps [iter-1].IsAttribute)\r
105                                         iter--;\r
106 \r
107                                 if (path.Descendants && reader.Depth < this.StartDepth + iter)\r
108                                         continue;\r
109                                 else if (!path.Descendants && reader.Depth != this.StartDepth + iter)\r
110                                         continue;\r
111 \r
112                                 iter--;\r
113 \r
114                                 XsdIdentityStep step;\r
115                                 for (int x = 0; x <= iter; x++, iter--) {\r
116                                         step = path.OrderedSteps [iter - x];\r
117                                         if (step.IsAnyName)\r
118                                                 continue;\r
119                                         XmlQualifiedName qname = (XmlQualifiedName) qnameStack [qnameStack.Count - x - 1];\r
120                                         if (step.NsName != null && qname.Namespace == step.NsName)\r
121                                                 continue;\r
122                                         if (step.Name == qname.Name && step.Namespace == qname.Namespace)\r
123                                                 continue;\r
124                                         else\r
125                                                 break;\r
126                                 }\r
127                                 if (iter >= 0)  // i.e. did not match against the path.\r
128                                         continue;\r
129                                 return path;\r
130                         }\r
131                         return null;\r
132                 }\r
133         }\r
134 }\r