(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Mono.Xml.Ext / Mono.Xml.XPath2 / SequenceType.cs
blobdadaeb8b8f089b0e60e4f0f25769ebb824b8a773
1 //
2 // SequenceType.cs - represents XPath 2.0 item type
3 //
4 // Author:
5 // Atsushi Enomoto <atsushi@ximian.com>
6 //
7 //
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #if NET_2_0
31 using System;
32 using System.Collections;
33 using System.Globalization;
34 using System.Xml;
35 using System.Xml.Schema;
36 using System.Xml.Query;
37 using System.Xml.XPath;
38 using Mono.Xml;
40 namespace Mono.Xml.XPath2
42 public class SequenceType
44 static SequenceType singleItem = new SequenceType (ItemType.AnyItem, Occurence.One);
45 static SequenceType singleAnyAtomic = new SequenceType (ItemType.AnyAtomicType, Occurence.One);
47 internal static SequenceType AnyType {
48 get { return Create (InternalPool.XsAnyType, Occurence.ZeroOrMore); }
50 internal static SequenceType SingleItem {
51 get { return singleItem; }
53 internal static SequenceType SingleAnyAtomic {
54 get { return singleAnyAtomic; }
57 internal static SequenceType Node {
58 get { return Create (XmlTypeCode.Node, Occurence.One); }
60 internal static SequenceType Document {
61 get { return Create (XmlTypeCode.Document, Occurence.One); }
63 internal static SequenceType Element {
64 get { return Create (XmlTypeCode.Element, Occurence.One); }
66 internal static SequenceType Attribute {
67 get { return Create (XmlTypeCode.Attribute, Occurence.One); }
69 internal static SequenceType Namespace {
70 get { return Create (XmlTypeCode.Namespace, Occurence.One); }
72 internal static SequenceType Text {
73 get { return Create (XmlTypeCode.Text, Occurence.One); }
75 internal static SequenceType XmlPI {
76 get { return Create (XmlTypeCode.ProcessingInstruction, Occurence.One); }
78 internal static SequenceType Comment {
79 get { return Create (XmlTypeCode.Comment, Occurence.One); }
82 internal static SequenceType AtomicString {
83 get { return Create (InternalPool.XsString, Occurence.One); }
85 internal static SequenceType Boolean {
86 get { return Create (InternalPool.XsBoolean, Occurence.One); }
88 internal static SequenceType Decimal {
89 get { return Create (InternalPool.XsDecimal, Occurence.One); }
91 internal static SequenceType Integer {
92 get { return Create (InternalPool.XsInteger, Occurence.One); }
94 internal static SequenceType Int {
95 get { return Create (InternalPool.XsInt, Occurence.One); }
97 internal static SequenceType Short {
98 get { return Create (InternalPool.XsShort, Occurence.One); }
100 internal static SequenceType UnsignedInt {
101 get { return Create (InternalPool.XsUnsignedInt, Occurence.One); }
103 internal static SequenceType UnsignedShort {
104 get { return Create (InternalPool.XsUnsignedShort, Occurence.One); }
106 internal static SequenceType Double {
107 get { return Create (InternalPool.XsDouble, Occurence.One); }
109 internal static SequenceType Single {
110 get { return Create (InternalPool.XsFloat, Occurence.One); }
112 internal static SequenceType DateTime {
113 get { return Create (InternalPool.XsDateTime, Occurence.One); }
115 internal static SequenceType QName {
116 get { return Create (InternalPool.XsQName, Occurence.One); }
119 internal static SequenceType IntegerList {
120 get { return Create (XmlTypeCode.Integer, Occurence.ZeroOrMore); }
124 static Hashtable standardTypes = new Hashtable ();
126 internal static SequenceType Create (Type cliType)
128 // typed Array
129 if (cliType.IsArray)
130 return Create (InternalPool.XmlTypeCodeFromRuntimeType (cliType.GetElementType (), true), Occurence.ZeroOrMore);
131 // if (cliType.GetInterface ("System.Collections.IEnumerable") != null)
132 // return Create (XmlTypeCode.Item, Occurence.ZeroOrMore);
133 if (cliType == typeof (XmlQualifiedName))
134 return QName;
135 if (cliType == typeof (XPathNavigator) || cliType.IsSubclassOf (typeof (XPathNavigator)))
136 return Node;
137 if (cliType == typeof (XPathAtomicValue))
138 return SingleAnyAtomic;
139 if (cliType == typeof (XPathItem))
140 return SingleItem;
141 // FIXME: handle Nullable type
142 return Create (InternalPool.XmlTypeCodeFromRuntimeType (cliType, true), Occurence.One);
145 internal static SequenceType Create (XmlTypeCode typeCode, Occurence occurence)
147 switch (typeCode) {
148 case XmlTypeCode.Item:
149 case XmlTypeCode.AnyAtomicType:
150 case XmlTypeCode.Node:
151 case XmlTypeCode.Document:
152 case XmlTypeCode.Element:
153 case XmlTypeCode.Attribute:
154 case XmlTypeCode.ProcessingInstruction:
155 case XmlTypeCode.Comment:
156 case XmlTypeCode.Namespace:
157 case XmlTypeCode.Text:
158 return new SequenceType (new ItemType (typeCode), occurence);
159 default:
160 return Create (XmlSchemaType.GetBuiltInSimpleType (typeCode), occurence);
164 internal static SequenceType Create (XmlSchemaType schemaType, Occurence occurence)
166 switch (schemaType.QualifiedName.Namespace) {
167 case XmlSchema.Namespace:
168 case InternalPool.XdtNamespace:
169 break;
170 default:
171 return new SequenceType (schemaType, occurence);
174 Hashtable cacheForType = standardTypes [schemaType] as Hashtable;
175 if (cacheForType == null) {
176 cacheForType = new Hashtable ();
177 standardTypes [schemaType] = cacheForType;
178 } else {
179 SequenceType type = cacheForType [occurence] as SequenceType;
180 if (type != null)
181 return type;
183 SequenceType t = new SequenceType (schemaType, occurence);
184 cacheForType [occurence] = t;
185 return t;
188 [MonoTODO]
189 internal static SequenceType ComputeCommonBase (SequenceType t1, SequenceType t2)
191 // FIXME: implement
192 // throw new NotImplementedException ();
193 return SequenceType.AnyType;
196 internal static bool IsNumeric (XmlTypeCode code)
198 switch (code) {
199 case XmlTypeCode.Decimal:
200 case XmlTypeCode.Float:
201 case XmlTypeCode.Double:
202 case XmlTypeCode.Integer:
203 case XmlTypeCode.NonPositiveInteger:
204 case XmlTypeCode.NegativeInteger:
205 case XmlTypeCode.Long:
206 case XmlTypeCode.Int:
207 case XmlTypeCode.Short:
208 case XmlTypeCode.Byte:
209 case XmlTypeCode.NonNegativeInteger:
210 case XmlTypeCode.UnsignedLong:
211 case XmlTypeCode.UnsignedInt:
212 case XmlTypeCode.UnsignedShort:
213 case XmlTypeCode.UnsignedByte:
214 case XmlTypeCode.PositiveInteger:
215 return true;
217 return false;
220 // Instance members
222 private SequenceType (XmlSchemaType schemaType, Occurence occurence)
224 this.schemaType = schemaType;
225 this.itemType = ItemType.AnyItem;
226 this.occurence = occurence;
229 internal SequenceType (ItemType itemType, Occurence occurence)
231 this.schemaType = InternalPool.XsAnyType;
232 this.itemType = itemType;
233 this.occurence = occurence;
236 XmlSchemaType schemaType;
237 Occurence occurence;
238 ItemType itemType;
240 public XmlSchemaType SchemaType {
241 get { return schemaType; }
244 public ItemType ItemType {
245 get { return itemType; }
248 public Occurence Occurence {
249 get { return occurence; }
252 internal bool Matches (XPathSequence iter)
254 throw new NotImplementedException ();
257 [MonoTODO]
258 internal bool CanConvertTo (SequenceType other)
260 // FIXME: implement precisely
261 return this == other;
262 // throw new NotImplementedException ();
265 internal bool CanConvert (XPathSequence iter)
267 bool occured = false;
268 bool onlyOnce = (occurence == Occurence.One || occurence == Occurence.Optional);
269 bool required = (occurence == Occurence.One || occurence == Occurence.OneOrMore);
270 foreach (XPathItem item in iter) {
271 if (occured && onlyOnce)
272 return false;
273 if (!CanConvert (item))
274 return false;
276 return occured || !required;
279 public bool CanConvert (XPathItem item)
281 throw new NotImplementedException ();
284 public bool IsInstance (XPathItem item)
286 throw new NotImplementedException ();
289 public XPathItem Convert (XPathItem item)
291 throw new NotImplementedException ();
294 public object ToRuntimeType (XPathSequence seq)
296 // FIXME: handle ZeroOrMore|OneOrMore
297 switch (occurence) {
298 case Occurence.One:
299 case Occurence.Optional:
300 if (!seq.MoveNext ())
301 return null;
302 XPathItem item = seq.Current;
303 // FIXME: should check and reject two or
304 // more items??
305 return item.TypedValue;
307 ArrayList al = new ArrayList ();
308 while (seq.MoveNext ())
309 al.Add (seq.Current.TypedValue);
310 return al.ToArray (InternalPool.RuntimeTypeFromXmlTypeCode (schemaType.TypeCode));
311 // return seq;
315 public enum Occurence
317 One,
318 Optional,
319 ZeroOrMore,
320 OneOrMore,
323 #region NodeTest
325 public enum XPathAxisType
327 Child,
328 Descendant,
329 Attribute,
330 Self,
331 DescendantOrSelf,
332 FollowingSibling,
333 Following,
334 Parent,
335 Ancestor,
336 PrecedingSibling,
337 Preceding,
338 AncestorOrSelf,
339 Namespace // only applicable under XPath 2.0, not XQuery 1.0
342 public class XPathAxis
344 // FIXME: add more parameters to distinguish them
345 private XPathAxis (XPathAxisType axisType)
347 this.axisType = axisType;
348 switch (axisType) {
349 case XPathAxisType.Parent:
350 case XPathAxisType.Ancestor:
351 case XPathAxisType.AncestorOrSelf:
352 case XPathAxisType.Preceding:
353 case XPathAxisType.PrecedingSibling:
354 this.reverse = true;
355 break;
359 bool reverse;
360 XPathAxisType axisType;
362 public bool ReverseAxis {
363 get { return reverse; }
366 public XPathAxisType AxisType {
367 get { return axisType; }
370 static XPathAxis child, descendant, attribute, self,
371 descendantOrSelf, followingSibling, following,
372 parent, ancestor, precedingSibling, preceding,
373 ancestorOrSelf;
375 static XPathAxis ()
377 child = new XPathAxis (XPathAxisType.Child);
378 descendant = new XPathAxis (XPathAxisType.Descendant);
379 attribute = new XPathAxis (XPathAxisType.Attribute);
380 self = new XPathAxis (XPathAxisType.Self);
381 descendantOrSelf = new XPathAxis (XPathAxisType.DescendantOrSelf);
382 followingSibling = new XPathAxis (XPathAxisType.FollowingSibling);
383 following = new XPathAxis (XPathAxisType.Following);
384 parent = new XPathAxis (XPathAxisType.Parent);
385 ancestor = new XPathAxis (XPathAxisType.Ancestor);
386 precedingSibling = new XPathAxis (XPathAxisType.PrecedingSibling);
387 preceding = new XPathAxis (XPathAxisType.Preceding);
388 ancestorOrSelf = new XPathAxis (XPathAxisType.AncestorOrSelf);
391 public static XPathAxis Child {
392 get { return child; }
395 public static XPathAxis Descendant {
396 get { return descendant; }
399 public static XPathAxis Attribute {
400 get { return attribute; }
403 public static XPathAxis Self {
404 get { return self; }
407 public static XPathAxis DescendantOrSelf {
408 get { return descendantOrSelf; }
411 public static XPathAxis FollowingSibling {
412 get { return followingSibling; }
415 public static XPathAxis Following {
416 get { return following; }
419 public static XPathAxis Parent {
420 get { return parent; }
423 public static XPathAxis Ancestor {
424 get { return ancestor; }
427 public static XPathAxis PrecedingSibling {
428 get { return precedingSibling; }
431 public static XPathAxis Preceding {
432 get { return preceding; }
435 public static XPathAxis AncestorOrSelf {
436 get { return ancestorOrSelf; }
440 // ItemType
441 public class ItemType
443 static ItemType anyItem = new ItemType (XmlTypeCode.Item);
444 static ItemType anyAtomicType = new ItemType (XmlTypeCode.AnyAtomicType);
446 public static ItemType AnyItem {
447 get { return anyItem; }
450 public static ItemType AnyAtomicType {
451 get { return anyAtomicType; }
454 XmlTypeCode typeCode;
456 public ItemType (XmlTypeCode typeCode)
458 this.typeCode = typeCode;
461 public XmlTypeCode TypeCode {
462 get { return typeCode; }
465 internal virtual void CheckReference (XQueryASTCompiler compiler)
470 // KindTest
472 public class KindTest : ItemType
474 public KindTest (XmlTypeCode type)
475 : base (type)
479 internal virtual void Compile (XQueryASTCompiler compiler)
483 public virtual bool Matches (XPathItem item)
485 XPathNavigator nav = item as XPathNavigator;
486 if (nav == null)
487 return false;
488 // FIXME: is it true? ('untyped' means 'matches with any type' ?
489 if (item.XmlType == null)
490 return true;
491 if (item.XmlType.TypeCode != TypeCode)
492 return false;
493 return true;
497 public class DocumentTest : KindTest
499 ElementTest content;
501 public DocumentTest (ElementTest content)
502 : base (XmlTypeCode.Document)
504 this.content = content;
507 public ElementTest Content {
508 get { return content; }
511 internal override void CheckReference (XQueryASTCompiler compiler)
513 content.CheckReference (compiler);
516 internal override void Compile (XQueryASTCompiler compiler)
520 public override bool Matches (XPathItem item)
522 XPathNavigator nav = item as XPathNavigator;
523 if (nav == null)
524 return false;
526 if (item.XmlType.TypeCode != XmlTypeCode.Document)
527 return false;
529 if (Content == null)
530 return true;
532 nav = nav.Clone ();
533 nav.MoveToFirstChild ();
534 while (nav.NodeType != XPathNodeType.Element)
535 if (!nav.MoveToNext ())
536 return false;
537 return Content.Matches (nav);
541 public class ElementTest : KindTest
543 XmlQualifiedName name;
544 XmlQualifiedName typeName;
545 XmlSchemaType schemaType;
546 bool nillable;
548 public ElementTest (XmlQualifiedName name)
549 : base (XmlTypeCode.Element)
551 this.name = name;
554 public ElementTest (XmlQualifiedName name, XmlQualifiedName type, bool nillable)
555 : base (XmlTypeCode.Element)
557 this.name = name;
558 this.typeName = type;
559 this.nillable = nillable;
562 public XmlQualifiedName Name {
563 get { return name; }
566 public XmlQualifiedName TypeName {
567 get { return typeName; }
570 public XmlSchemaType SchemaType {
571 get {
572 return schemaType;
576 public bool Nillable {
577 get { return nillable; }
580 internal override void CheckReference (XQueryASTCompiler compiler)
582 compiler.CheckSchemaTypeName (typeName);
585 internal override void Compile (XQueryASTCompiler compiler)
587 schemaType = compiler.ResolveSchemaType (TypeName);
588 if (schemaType == null)
589 throw new XmlQueryCompileException ("Specified schema type was not found.");
592 public override bool Matches (XPathItem item)
594 XPathNavigator nav = item as XPathNavigator;
595 if (nav == null)
596 return false;
598 if (item.XmlType.TypeCode != XmlTypeCode.Element)
599 return false;
601 if (Name != XmlQualifiedName.Empty)
602 if (nav.LocalName != Name.Name || nav.NamespaceURI != Name.Namespace)
603 return false;
605 // FIXME: it won't be XQueryConvert.CanConvert(), but other strict-matching evaluation
606 if (SchemaType != null && !XQueryConvert.CanConvert (item, SchemaType))
607 return false;
608 // FIXME: check nillable
610 return true;
614 public class AttributeTest : KindTest
616 static AttributeTest anyAttribute;
618 static AttributeTest ()
620 anyAttribute = new AttributeTest (XmlQualifiedName.Empty);
623 public static AttributeTest AnyAttribute {
624 get { return anyAttribute; }
627 public AttributeTest (XmlQualifiedName name)
628 : base (XmlTypeCode.Attribute)
630 this.name = name;
633 public AttributeTest (XmlQualifiedName name, XmlQualifiedName typeName)
634 : base (XmlTypeCode.Attribute)
636 this.name = name;
637 this.typeName = typeName;
640 XmlQualifiedName name;
641 XmlQualifiedName typeName;
642 XmlSchemaType schemaType;
644 public XmlQualifiedName Name {
645 get { return name; }
648 public XmlQualifiedName TypeName {
649 get { return typeName; }
652 public XmlSchemaType SchemaType {
653 get { return schemaType; }
656 internal override void CheckReference (XQueryASTCompiler compiler)
658 compiler.CheckSchemaTypeName (typeName);
661 internal override void Compile (XQueryASTCompiler compiler)
663 schemaType = compiler.ResolveSchemaType (TypeName);
664 if (schemaType == null)
665 throw new XmlQueryCompileException ("Specified schema type was not found.");
668 public override bool Matches (XPathItem item)
670 XPathNavigator nav = item as XPathNavigator;
671 if (nav == null)
672 return false;
674 if (item.XmlType.TypeCode != XmlTypeCode.Attribute)
675 return false;
677 if (Name != XmlQualifiedName.Empty)
678 if (nav.LocalName != Name.Name || nav.NamespaceURI != Name.Namespace)
679 return false;
681 // FIXME: it won't be XQueryConvert.CanConvert(), but other strict-matching evaluation
682 if (SchemaType != null && !XQueryConvert.CanConvert (item, SchemaType))
683 return false;
685 return true;
689 public class XmlPITest : KindTest
691 string name;
693 public XmlPITest (string nameTest)
694 : base (XmlTypeCode.ProcessingInstruction)
696 this.name = nameTest;
699 public string Name {
700 get { return name; }
703 internal override void CheckReference (XQueryASTCompiler compiler)
707 internal override void Compile (XQueryASTCompiler compiler)
711 public override bool Matches (XPathItem item)
713 XPathNavigator nav = item as XPathNavigator;
714 if (nav == null)
715 return false;
717 if (item.XmlType.TypeCode != XmlTypeCode.ProcessingInstruction)
718 return false;
719 if (Name != String.Empty && nav.LocalName != Name)
720 return false;
721 return true;
725 #endregion
728 #endif