301 lines
9.5 KiB
C#
301 lines
9.5 KiB
C#
|
//------------------------------------------------------------------------------
|
||
|
// <copyright file="Shape.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
// <owner current="true" primary="true">derekdb</owner>
|
||
|
//------------------------------------------------------------------------------
|
||
|
#if ENABLEDATABINDING
|
||
|
using System;
|
||
|
using System.Xml;
|
||
|
using System.Xml.Schema;
|
||
|
using System.Xml.XPath;
|
||
|
using System.Collections;
|
||
|
using System.Diagnostics;
|
||
|
using System.ComponentModel;
|
||
|
using System.Text;
|
||
|
|
||
|
namespace System.Xml.XPath.DataBinding
|
||
|
{
|
||
|
internal enum BindingType {
|
||
|
Text,
|
||
|
Element,
|
||
|
Attribute,
|
||
|
ElementNested,
|
||
|
Repeat,
|
||
|
Sequence,
|
||
|
Choice,
|
||
|
All
|
||
|
}
|
||
|
|
||
|
internal sealed class Shape
|
||
|
{
|
||
|
string name;
|
||
|
BindingType bindingType;
|
||
|
ArrayList particles; // XmlSchemaElement or XmlSchemaAttribute
|
||
|
ArrayList subShapes;
|
||
|
Shape nestedShape;
|
||
|
PropertyDescriptor[] propertyDescriptors;
|
||
|
XmlSchemaElement containerDecl;
|
||
|
|
||
|
static object[] emptyIList = new object[0];
|
||
|
|
||
|
public Shape(string name, BindingType bindingType)
|
||
|
{
|
||
|
this.name = name;
|
||
|
this.bindingType = bindingType;
|
||
|
}
|
||
|
|
||
|
public string Name {
|
||
|
get { return this.name; }
|
||
|
set { this.name = value; }
|
||
|
}
|
||
|
|
||
|
public BindingType BindingType {
|
||
|
get { return this.bindingType; }
|
||
|
set { this.bindingType = value; }
|
||
|
}
|
||
|
|
||
|
public XmlSchemaElement ContainerDecl {
|
||
|
get { return this.containerDecl; }
|
||
|
set { this.containerDecl = value; }
|
||
|
}
|
||
|
|
||
|
public bool IsNestedTable {
|
||
|
get {
|
||
|
switch (this.BindingType) {
|
||
|
case BindingType.ElementNested:
|
||
|
case BindingType.Repeat:
|
||
|
case BindingType.Sequence:
|
||
|
case BindingType.Choice:
|
||
|
case BindingType.All:
|
||
|
return true;
|
||
|
|
||
|
default:
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool IsGroup {
|
||
|
get {
|
||
|
switch (this.BindingType) {
|
||
|
case BindingType.Sequence:
|
||
|
case BindingType.Choice:
|
||
|
case BindingType.All:
|
||
|
return true;
|
||
|
default:
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public XmlSchemaType SchemaType {
|
||
|
get {
|
||
|
switch (this.bindingType) {
|
||
|
case BindingType.Text:
|
||
|
case BindingType.Element:
|
||
|
case BindingType.ElementNested: {
|
||
|
Debug.Assert(this.particles.Count == 1);
|
||
|
XmlSchemaElement xse = (XmlSchemaElement)this.particles[0];
|
||
|
return xse.ElementSchemaType;
|
||
|
}
|
||
|
|
||
|
case BindingType.Attribute: {
|
||
|
Debug.Assert(this.particles.Count == 1);
|
||
|
XmlSchemaAttribute xsa = (XmlSchemaAttribute)this.particles[0];
|
||
|
return xsa.AttributeSchemaType;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public XmlSchemaElement XmlSchemaElement {
|
||
|
get {
|
||
|
switch (this.bindingType) {
|
||
|
case BindingType.Text:
|
||
|
case BindingType.Element:
|
||
|
case BindingType.ElementNested: {
|
||
|
Debug.Assert(this.particles.Count == 1);
|
||
|
return (XmlSchemaElement)this.particles[0];
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return this.containerDecl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public IList Particles {
|
||
|
get {
|
||
|
if (null == this.particles)
|
||
|
return emptyIList;
|
||
|
return this.particles;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public IList SubShapes {
|
||
|
get {
|
||
|
if (null == this.subShapes)
|
||
|
return emptyIList;
|
||
|
return this.subShapes;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Shape SubShape(int i) {
|
||
|
return (Shape)SubShapes[i];
|
||
|
}
|
||
|
|
||
|
public Shape NestedShape {
|
||
|
get {
|
||
|
//Debug.Assert(this.bindingType == BindingType.ElementNested);
|
||
|
return this.nestedShape;
|
||
|
}
|
||
|
set {
|
||
|
this.nestedShape = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public XmlQualifiedName AttributeName {
|
||
|
get {
|
||
|
Debug.Assert(this.bindingType == BindingType.Attribute);
|
||
|
XmlSchemaAttribute xsa = (XmlSchemaAttribute)this.particles[0];
|
||
|
return xsa.QualifiedName;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Clear() {
|
||
|
if (this.subShapes != null) {
|
||
|
this.subShapes.Clear();
|
||
|
this.subShapes = null;
|
||
|
}
|
||
|
if (this.particles != null) {
|
||
|
this.particles.Clear();
|
||
|
this.particles = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void AddParticle(XmlSchemaElement elem) {
|
||
|
if (null == this.particles)
|
||
|
this.particles = new ArrayList();
|
||
|
Debug.Assert(this.bindingType != BindingType.Attribute);
|
||
|
this.particles.Add(elem);
|
||
|
}
|
||
|
|
||
|
public void AddParticle(XmlSchemaAttribute elem) {
|
||
|
Debug.Assert(this.bindingType == BindingType.Attribute);
|
||
|
Debug.Assert(this.particles == null);
|
||
|
this.particles = new ArrayList();
|
||
|
this.particles.Add(elem);
|
||
|
}
|
||
|
|
||
|
public void AddSubShape(Shape shape) {
|
||
|
if (null == this.subShapes)
|
||
|
this.subShapes = new ArrayList();
|
||
|
this.subShapes.Add(shape);
|
||
|
foreach (object p in shape.Particles) {
|
||
|
XmlSchemaElement xse = p as XmlSchemaElement;
|
||
|
if (null != xse)
|
||
|
AddParticle(xse);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void AddAttrShapeAt(Shape shape, int pos) {
|
||
|
if (null == this.subShapes)
|
||
|
this.subShapes = new ArrayList();
|
||
|
this.subShapes.Insert(pos, shape);
|
||
|
}
|
||
|
|
||
|
public string[] SubShapeNames() {
|
||
|
string[] names = new string[SubShapes.Count];
|
||
|
for (int i=0; i<SubShapes.Count; i++)
|
||
|
names[i] = this.SubShape(i).Name;
|
||
|
return names;
|
||
|
}
|
||
|
|
||
|
public PropertyDescriptor[] PropertyDescriptors {
|
||
|
get {
|
||
|
if (null == this.propertyDescriptors) {
|
||
|
PropertyDescriptor[] descs;
|
||
|
switch (this.BindingType) {
|
||
|
case BindingType.Element:
|
||
|
case BindingType.Text:
|
||
|
case BindingType.Attribute:
|
||
|
case BindingType.Repeat:
|
||
|
descs = new PropertyDescriptor[1];
|
||
|
descs[0] = new XPathNodeViewPropertyDescriptor(this);
|
||
|
break;
|
||
|
|
||
|
case BindingType.ElementNested:
|
||
|
descs = this.nestedShape.PropertyDescriptors;
|
||
|
break;
|
||
|
|
||
|
case BindingType.Sequence:
|
||
|
case BindingType.Choice:
|
||
|
case BindingType.All:
|
||
|
descs = new PropertyDescriptor[SubShapes.Count];
|
||
|
for (int i=0; i < descs.Length; i++) {
|
||
|
descs[i] = new XPathNodeViewPropertyDescriptor(this, this.SubShape(i), i);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
throw new NotSupportedException();
|
||
|
}
|
||
|
this.propertyDescriptors = descs;
|
||
|
}
|
||
|
return this.propertyDescriptors;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public int FindNamedSubShape(string name) {
|
||
|
for (int i=0; i<SubShapes.Count; i++) {
|
||
|
Shape shape = SubShape(i);
|
||
|
if (shape.Name == name)
|
||
|
return i;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
public int FindMatchingSubShape(object particle) {
|
||
|
for (int i=0; i<SubShapes.Count; i++) {
|
||
|
Shape shape = SubShape(i);
|
||
|
if (shape.IsParticleMatch(particle))
|
||
|
return i;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
public bool IsParticleMatch(object particle) {
|
||
|
for (int i=0; i<this.particles.Count; i++) {
|
||
|
if (particle == this.particles[i])
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
#if DEBUG
|
||
|
public string DebugDump() {
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
DebugDump(sb,"");
|
||
|
return sb.ToString();
|
||
|
}
|
||
|
void DebugDump(StringBuilder sb, String indent) {
|
||
|
sb.AppendFormat("{0}{1} '{2}'", indent, this.BindingType.ToString(), this.Name);
|
||
|
if (this.subShapes != null) {
|
||
|
sb.AppendLine(" {");
|
||
|
string subindent = String.Concat(indent, " ");
|
||
|
foreach (Shape s in this.SubShapes) {
|
||
|
s.DebugDump(sb, subindent);
|
||
|
}
|
||
|
sb.Append(indent);
|
||
|
sb.Append('}');
|
||
|
}
|
||
|
sb.AppendLine();
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
#endif
|