Yet another. Init the gobject type system.
[beagle.git] / Util / SemWeb / XPathSemWebNavigator.cs
blob369570dbc342d62da5c7aa65c4b8343e366497c3
1 using System;
2 using System.Collections;
3 using System.Xml;
4 using System.Xml.Xsl;
5 using System.Xml.XPath;
7 using SemWeb;
9 namespace SemWeb.Util {
10 public class XPathSemWebNavigator : XPathNavigator {
11 Store model;
12 NamespaceManager nsmgr;
13 NSWrap nswrap;
15 ArrayList stack = new ArrayList();
16 Position current;
18 private static Entity ExpandEntitiesOfType = new Entity(null);
20 Entity rdfType = NS.RDF+"type";
22 private class Position {
23 public int Index;
24 public bool FirstChild, LastChild;
26 public Entity Predicate;
27 public Resource Object;
29 public Position[] Children;
32 private class NSWrap : XsltContext {
33 NamespaceManager nsmgr;
35 public NSWrap(NamespaceManager nsmgr) : base(new NameTable()) { this.nsmgr = nsmgr; }
37 public override bool HasNamespace (string prefix) {
38 return LookupNamespace(prefix) != null;
41 public override string LookupNamespace (string prefix) {
42 return nsmgr.GetNamespace(prefix);
44 public override string LookupPrefix (string uri) {
45 return nsmgr.GetPrefix(uri);
48 // These don't really do anything (yet?).
50 public override bool Whitespace {
51 get { return false; }
54 public override int CompareDocument (string baseUri, string nextbaseUri) {
55 return baseUri.CompareTo(nextbaseUri);
58 public override bool PreserveWhitespace (System.Xml.XPath.XPathNavigator node) {
59 return false;
62 public override IXsltContextFunction ResolveFunction (string prefix, string name, System.Xml.XPath.XPathResultType[] ArgTypes) {
63 return null;
66 public override IXsltContextVariable ResolveVariable (string prefix, string name) {
67 return null;
71 public XPathSemWebNavigator(Store model, NamespaceManager namespaces) : this(ExpandEntitiesOfType, model, namespaces, null) { }
73 public XPathSemWebNavigator(Entity root, Store model, NamespaceManager namespaces) : this(root, model, namespaces, null) { }
75 private XPathSemWebNavigator(Entity root, Store model, NamespaceManager namespaces, string exapandThisPredicate) {
76 this.model = model;
78 if (!(namespaces is SemWeb.IO.AutoPrefixNamespaceManager))
79 namespaces = new SemWeb.IO.AutoPrefixNamespaceManager(namespaces);
80 this.nsmgr = namespaces;
81 nswrap = new NSWrap(nsmgr);
83 Position start = new Position();
84 start.FirstChild = true;
85 start.LastChild = true;
86 start.Predicate = root; // a trick to make sure the URI info for the root reflects the root
87 start.Object = root;
88 if (exapandThisPredicate != null)
89 Expand(start, exapandThisPredicate);
90 current = start;
93 private XPathSemWebNavigator(XPathSemWebNavigator clone) {
94 MoveTo(clone);
97 private void Expand(Position p) {
98 Expand(p, null);
101 private void Expand(Position p, string expandOnlyThisPredicate) {
102 if (!(p.Object is Entity)) {
103 p.Children = new Position[0];
104 return;
107 ArrayList children = new ArrayList();
108 int ctr = 0;
110 if (p.Object == ExpandEntitiesOfType) {
111 if (expandOnlyThisPredicate == null) {
112 // Get a list of entities and their types.
113 foreach (Statement s in model.Select(new Statement(null, rdfType, null))) {
114 if (!(s.Object is Entity)) continue;
115 Position c = new Position();
116 c.Index = ctr++;
117 c.Predicate = (Entity)s.Object;
118 c.Object = s.Subject;
119 children.Add(c);
121 } else {
122 foreach (Entity e in model.GetEntitiesOfType(expandOnlyThisPredicate)) {
123 Position c = new Position();
124 c.Predicate = expandOnlyThisPredicate;
125 c.Index = ctr++;
126 c.Object = e;
127 children.Add(c);
130 } else {
132 if (expandOnlyThisPredicate == null || !expandOnlyThisPredicate.StartsWith("!")) {
133 Statement q = new Statement(
134 (Entity)p.Object,
135 expandOnlyThisPredicate == null ? (Entity)null : (Entity)expandOnlyThisPredicate,
136 null);
138 foreach (Statement s in model.Select(q)) {
139 Position c = new Position();
140 c.Index = ctr++;
141 c.Predicate = s.Predicate;
142 c.Object = s.Object;
143 children.Add(c);
147 if (expandOnlyThisPredicate == null || expandOnlyThisPredicate.StartsWith("!")) {
148 Statement q = new Statement(
149 null,
150 expandOnlyThisPredicate == null ? (Entity)null : (Entity)expandOnlyThisPredicate.Substring(1),
151 p.Object);
153 foreach (Statement s in model.Select(q)) {
154 Position c = new Position();
155 c.Index = ctr++;
156 c.Predicate = "!" + s.Predicate;
157 c.Object = s.Subject;
158 children.Add(c);
164 p.Children = (Position[])children.ToArray(typeof(Position));
166 if (p.Children.Length > 0) {
167 p.Children[0].FirstChild = true;
168 p.Children[p.Children.Length-1].LastChild = true;
172 public override string BaseURI { get { return ""; } }
174 public override bool HasAttributes { get { return false; } }
176 public override bool HasChildren { get { return true; } }
178 public override bool IsEmptyElement { get { return false; } }
180 public override string LocalName {
181 get {
182 string p, l;
183 if (current.Predicate == ExpandEntitiesOfType)
184 return "root";
185 if (current.Predicate.Uri == null)
186 return "anonymous";
187 if (nsmgr.Normalize(current.Predicate.Uri, out p, out l))
188 return l;
189 throw new InvalidOperationException("The local name of " + current.Predicate.Uri + " could not be determined.");
193 public override string Name {
194 get {
195 if (current.Predicate == ExpandEntitiesOfType)
196 return "root";
197 if (current.Predicate.Uri == null)
198 return "anonymous";
199 return nsmgr.Normalize(current.Predicate.Uri);
203 public override string NamespaceURI {
204 get {
205 string p, l;
206 if (current.Predicate.Uri == null)
207 return "anonymous";
208 if (nsmgr.Normalize(current.Predicate.Uri, out p, out l))
209 return nsmgr.GetNamespace(p);
210 throw new InvalidOperationException("The namespace URI of " + current.Predicate.Uri + " could not be determined.");
214 public override XmlNameTable NameTable {
215 get {
216 return null;
220 public override XPathNodeType NodeType {
221 get {
222 if (stack.Count == 0)
223 return XPathNodeType.Root;
224 return XPathNodeType.Element;
228 public override string Prefix {
229 get {
230 string p, l;
231 if (nsmgr.Normalize(current.Predicate.Uri, out p, out l))
232 return p;
233 throw new InvalidOperationException("The prefix of " + current.Predicate.Uri + " could not be determined.");
237 public override string Value {
238 get {
239 if (current.Predicate == ExpandEntitiesOfType)
240 return "root";
241 if (current.Object is Literal)
242 return ((Literal)current.Object).Value;
243 if (current.Object.Uri == null)
244 return "";
245 return current.Object.Uri;
249 public override string XmlLang { get { return ""; } }
251 public override XPathNavigator Clone () {
252 return new XPathSemWebNavigator(this);
255 //public virtual XmlNodeOrder ComparePosition (XPathNavigator nav)
257 public override string GetAttribute (string localName, string namespaceURI) {
258 return "";
261 public override string GetNamespace (string name) {
262 return nsmgr.GetNamespace(name);
265 public override bool IsSamePosition (XPathNavigator other) {
266 if (!(other is XPathSemWebNavigator)) return false;
267 XPathSemWebNavigator o = (XPathSemWebNavigator)other;
268 return (o.current == current);
271 public override bool MoveTo (XPathNavigator other) {
272 XPathSemWebNavigator clone = other as XPathSemWebNavigator;
273 if (clone == null) return false;
274 this.model = clone.model;
275 this.nsmgr = clone.nsmgr;
276 this.nswrap = clone.nswrap;
277 this.stack = (ArrayList)clone.stack.Clone();
278 this.current = clone.current;
279 return true;
282 public override bool MoveToAttribute (string localName, string namespaceURI) { return false; }
284 public override bool MoveToNamespace (string name) { return false; }
286 public override bool MoveToFirst () {
287 return MoveToFirstChild();
290 public override void MoveToRoot () {
291 if (stack.Count == 0) return;
292 current = (Position)stack[0];
293 stack.Clear();
296 public override bool MoveToFirstAttribute () { return false; }
298 public override bool MoveToFirstChild () {
299 if (current.Children == null) Expand(current);
300 if (current.Children.Length == 0) return false;
301 stack.Add(current);
302 current = current.Children[0];
303 return true;
306 public override bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope) { return false; }
308 public override bool MoveToId (string id) { return false; }
310 public override bool MoveToNext () {
311 if (current.LastChild) return false;
312 current = ((Position)stack[stack.Count-1]).Children[current.Index+1];
313 return true;
316 public override bool MoveToNextAttribute () { return false; }
318 public override bool MoveToNextNamespace (XPathNamespaceScope namespaceScope) { return false; }
320 public override bool MoveToParent () {
321 if (stack.Count == 0) return false;
322 current = (Position)stack[stack.Count-1];
323 stack.RemoveAt(stack.Count-1);
324 return true;
327 public override bool MoveToPrevious () {
328 if (current.FirstChild) return false;
329 current = ((Position)stack[stack.Count-1]).Children[current.Index-1];
330 return true;
333 public override XPathNodeIterator SelectChildren (string name, string namespaceURI) {
334 if (current.Object is Literal) throw new InvalidOperationException("The navigator is positioned on a literal element.");
335 return new XPathSemWebNavigator((Entity)current.Object, model, nsmgr, namespaceURI + name).SelectChildren(XPathNodeType.All);
338 public override XPathNodeIterator Select (XPathExpression expr) {
339 expr.SetContext(nswrap);
340 return base.Select(expr);
343 public override object Evaluate (XPathExpression expr) {
344 expr.SetContext(nswrap);
345 return base.Evaluate(expr);
348 public override object Evaluate (XPathExpression expr, XPathNodeIterator context) {
349 expr.SetContext(nswrap);
350 return base.Evaluate(expr, context);