| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- //------------------------------------------------------------------------------
- // <copyright file="ImportContext.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- // <owner current="true" primary="true">Microsoft</owner>
- //------------------------------------------------------------------------------
- namespace System.Xml.Serialization {
- using System;
- using System.IO;
- using System.Xml;
- using System.Xml.Schema;
- using System.Xml.Serialization;
- using System.Collections;
- using System.Collections.Specialized;
- #if !MONO_HYBRID_SYSTEM_XML
- public class ImportContext {
- bool shareTypes;
- SchemaObjectCache cache; // cached schema top-level items
- Hashtable mappings; // XmlSchema -> SerializableMapping, XmlSchemaSimpleType -> EnumMapping, XmlSchemaComplexType -> StructMapping
- Hashtable elements; // XmlSchemaElement -> ElementAccessor
- CodeIdentifiers typeIdentifiers;
- /// <include file='doc\ImportContext.uex' path='docs/doc[@for="ImportContext.ImportContext"]/*' />
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public ImportContext(CodeIdentifiers identifiers, bool shareTypes) {
- this.typeIdentifiers = identifiers;
- this.shareTypes = shareTypes;
- }
- internal ImportContext() : this(null, false) {}
- internal SchemaObjectCache Cache {
- get {
- if (cache == null)
- cache = new SchemaObjectCache();
- return cache;
- }
- }
- internal Hashtable Elements {
- get {
- if (elements == null)
- elements = new Hashtable();
- return elements;
- }
- }
- internal Hashtable Mappings {
- get {
- if (mappings == null)
- mappings = new Hashtable();
- return mappings;
- }
- }
- /// <include file='doc\ImportContext.uex' path='docs/doc[@for="ImportContext.TypeIdentifiers"]/*' />
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public CodeIdentifiers TypeIdentifiers {
- get {
- if (typeIdentifiers == null)
- typeIdentifiers = new CodeIdentifiers();
- return typeIdentifiers;
- }
- }
- /// <include file='doc\ImportContext.uex' path='docs/doc[@for="ImportContext.ShareTypes"]/*' />
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public bool ShareTypes {
- get { return shareTypes; }
- }
- /// <include file='doc\ImportContext.uex' path='docs/doc[@for="ImportContext.Warnings"]/*' />
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public StringCollection Warnings {
- get { return Cache.Warnings; }
- }
- }
- #endif
- internal class SchemaObjectCache {
- Hashtable graph;
- Hashtable hash;
- Hashtable objectCache;
- StringCollection warnings;
- //
- internal Hashtable looks = new Hashtable();
- Hashtable Graph {
- get {
- if (graph == null)
- graph = new Hashtable();
- return graph;
- }
- }
- Hashtable Hash {
- get {
- if (hash == null)
- hash = new Hashtable();
- return hash;
- }
- }
- Hashtable ObjectCache {
- get {
- if (objectCache == null)
- objectCache = new Hashtable();
- return objectCache;
- }
- }
- internal StringCollection Warnings {
- get {
- if (warnings == null)
- warnings = new StringCollection();
- return warnings;
- }
- }
-
- internal XmlSchemaObject AddItem(XmlSchemaObject item, XmlQualifiedName qname, XmlSchemas schemas) {
- if (item == null)
- return null;
- if (qname == null || qname.IsEmpty)
- return null;
- string key = item.GetType().Name + ":" + qname.ToString();
- ArrayList list = (ArrayList)ObjectCache[key];
- if (list == null) {
- list = new ArrayList();
- ObjectCache[key] = list;
- }
- for (int i = 0; i < list.Count; i++) {
- XmlSchemaObject cachedItem = (XmlSchemaObject)list[i];
- if (cachedItem == item)
- return cachedItem;
- if (Match(cachedItem, item, true)) {
- return cachedItem;
- }
- else {
- Warnings.Add(Res.GetString(Res.XmlMismatchSchemaObjects, item.GetType().Name, qname.Name, qname.Namespace));
- Warnings.Add("DEBUG:Cached item key:\r\n" + (string)looks[cachedItem] + "\r\nnew item key:\r\n" + (string)looks[item]);
- }
- }
- // no match found we need to insert the new type in the cache
- list.Add(item);
- return item;
- }
- internal bool Match(XmlSchemaObject o1, XmlSchemaObject o2, bool shareTypes) {
- if (o1 == o2)
- return true;
- if (o1.GetType() != o2.GetType())
- return false;
- if (Hash[o1] == null)
- Hash[o1] = GetHash(o1);
- int hash1 = (int)Hash[o1];
- int hash2 = GetHash(o2);
- if (hash1 != hash2)
- return false;
- if (shareTypes)
- return CompositeHash(o1, hash1) == CompositeHash(o2, hash2);
- return true;
- }
- private ArrayList GetDependencies(XmlSchemaObject o, ArrayList deps, Hashtable refs) {
- if (refs[o] == null) {
- refs[o] = o;
- deps.Add(o);
- ArrayList list = Graph[o] as ArrayList;
- if (list != null) {
- for (int i = 0; i < list.Count; i++) {
- GetDependencies((XmlSchemaObject)list[i], deps, refs);
- }
- }
- }
- return deps;
- }
- private int CompositeHash(XmlSchemaObject o, int hash) {
- ArrayList list = GetDependencies(o, new ArrayList(), new Hashtable());
- double tmp = 0;
- for (int i = 0; i < list.Count; i++) {
- object cachedHash = Hash[list[i]];
- if (cachedHash is int) {
- tmp += (int)cachedHash/list.Count;
- }
- }
- return (int)tmp;
- }
- internal void GenerateSchemaGraph(XmlSchemas schemas) {
- SchemaGraph graph = new SchemaGraph(Graph, schemas);
- ArrayList items = graph.GetItems();
- for (int i = 0; i < items.Count; i++) {
- GetHash((XmlSchemaObject)items[i]);
- }
- }
- private int GetHash(XmlSchemaObject o) {
- object hash = Hash[o];
- if (hash != null) {
- if (hash is XmlSchemaObject) {
- }
- else {
- return (int)hash;
- }
- }
- // new object, generate the hash
- string hashString = ToString(o, new SchemaObjectWriter());
- looks[o] = hashString;
- int code = hashString.GetHashCode();
- Hash[o] = code;
- return code;
- }
- string ToString(XmlSchemaObject o, SchemaObjectWriter writer) {
- return writer.WriteXmlSchemaObject(o);
- }
- }
- internal class SchemaGraph {
- ArrayList empty = new ArrayList();
- XmlSchemas schemas;
- Hashtable scope;
- int items;
- internal SchemaGraph(Hashtable scope, XmlSchemas schemas) {
- this.scope = scope;
- schemas.Compile(null, false);
- this.schemas = schemas;
- items = 0;
- foreach(XmlSchema s in schemas) {
- items += s.Items.Count;
- foreach (XmlSchemaObject item in s.Items) {
- Depends(item);
- }
- }
- }
- internal ArrayList GetItems() {
- return new ArrayList(scope.Keys);
- }
- internal void AddRef(ArrayList list, XmlSchemaObject o) {
- if (o == null)
- return;
- if (schemas.IsReference(o))
- return;
- if (o.Parent is XmlSchema) {
- string ns = ((XmlSchema)o.Parent).TargetNamespace;
- if (ns == XmlSchema.Namespace)
- return;
- if (list.Contains(o))
- return;
- list.Add(o);
- }
- }
- internal ArrayList Depends(XmlSchemaObject item) {
- if (item.Parent is XmlSchema) {
- if (scope[item] != null)
- return (ArrayList)scope[item];
- ArrayList refs = new ArrayList();
- Depends(item, refs);
- scope.Add(item, refs);
- return refs;
- }
- return empty;
- }
- internal void Depends(XmlSchemaObject item, ArrayList refs) {
- if (item == null || scope[item] != null)
- return;
- Type t = item.GetType();
- if (typeof(XmlSchemaType).IsAssignableFrom(t)) {
- XmlQualifiedName baseName = XmlQualifiedName.Empty;
- XmlSchemaType baseType = null;
- XmlSchemaParticle particle = null;
- XmlSchemaObjectCollection attributes = null;
- if (item is XmlSchemaComplexType) {
- XmlSchemaComplexType ct = (XmlSchemaComplexType)item;
- if (ct.ContentModel != null) {
- XmlSchemaContent content = ct.ContentModel.Content;
- if (content is XmlSchemaComplexContentRestriction) {
- baseName = ((XmlSchemaComplexContentRestriction)content).BaseTypeName;
- attributes = ((XmlSchemaComplexContentRestriction)content).Attributes;
- }
- else if (content is XmlSchemaSimpleContentRestriction) {
- XmlSchemaSimpleContentRestriction restriction = (XmlSchemaSimpleContentRestriction)content;
- if (restriction.BaseType != null)
- baseType = restriction.BaseType;
- else
- baseName = restriction.BaseTypeName;
- attributes = restriction.Attributes;
- }
- else if (content is XmlSchemaComplexContentExtension) {
- XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content;
- attributes = extension.Attributes;
- particle = extension.Particle;
- baseName = extension.BaseTypeName;
- }
- else if (content is XmlSchemaSimpleContentExtension) {
- XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension)content;
- attributes = extension.Attributes;
- baseName = extension.BaseTypeName;
- }
- }
- else {
- attributes = ct.Attributes;
- particle = ct.Particle;
- }
- if (particle is XmlSchemaGroupRef) {
- XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle;
- particle = ((XmlSchemaGroup)schemas.Find(refGroup.RefName, typeof(XmlSchemaGroup), false)).Particle;
- }
- else if (particle is XmlSchemaGroupBase) {
- particle = (XmlSchemaGroupBase)particle;
- }
- }
- else if (item is XmlSchemaSimpleType) {
- XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)item;
- XmlSchemaSimpleTypeContent content = simpleType.Content;
- if (content is XmlSchemaSimpleTypeRestriction) {
- baseType = ((XmlSchemaSimpleTypeRestriction)content).BaseType;
- baseName = ((XmlSchemaSimpleTypeRestriction)content).BaseTypeName;
- }
- else if (content is XmlSchemaSimpleTypeList) {
- XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)content;
- if (list.ItemTypeName != null && !list.ItemTypeName.IsEmpty)
- baseName = list.ItemTypeName;
- if (list.ItemType != null) {
- baseType = list.ItemType;
- }
- }
- else if (content is XmlSchemaSimpleTypeRestriction) {
- baseName = ((XmlSchemaSimpleTypeRestriction)content).BaseTypeName;
- }
- else if (t == typeof(XmlSchemaSimpleTypeUnion)) {
- XmlQualifiedName[] memberTypes = ((XmlSchemaSimpleTypeUnion)item).MemberTypes;
-
- if (memberTypes != null) {
- for (int i = 0; i < memberTypes.Length; i++) {
- XmlSchemaType type = (XmlSchemaType)schemas.Find(memberTypes[i], typeof(XmlSchemaType), false);
- AddRef(refs, type);
- }
- }
- }
- }
- if (baseType == null && !baseName.IsEmpty && baseName.Namespace != XmlSchema.Namespace)
- baseType = (XmlSchemaType)schemas.Find(baseName, typeof(XmlSchemaType), false);
- if (baseType != null) {
- AddRef(refs, baseType);
- }
- if (particle != null) {
- Depends(particle, refs);
- }
- if (attributes != null) {
- for (int i = 0; i < attributes.Count; i++) {
- Depends(attributes[i], refs);
- }
- }
- }
- else if (t == typeof(XmlSchemaElement)) {
- XmlSchemaElement el = (XmlSchemaElement)item;
- if (!el.SubstitutionGroup.IsEmpty) {
- if (el.SubstitutionGroup.Namespace != XmlSchema.Namespace) {
- XmlSchemaElement head = (XmlSchemaElement)schemas.Find(el.SubstitutionGroup, typeof(XmlSchemaElement), false);
- AddRef(refs, head);
- }
- }
- if (!el.RefName.IsEmpty) {
- el = (XmlSchemaElement)schemas.Find(el.RefName, typeof(XmlSchemaElement), false);
- AddRef(refs, el);
- }
- else if (!el.SchemaTypeName.IsEmpty) {
- XmlSchemaType type = (XmlSchemaType)schemas.Find(el.SchemaTypeName, typeof(XmlSchemaType), false);
- AddRef(refs, type);
- }
- else {
- Depends(el.SchemaType, refs);
- }
- }
- else if (t == typeof(XmlSchemaGroup)) {
- Depends(((XmlSchemaGroup)item).Particle);
- }
- else if (t == typeof(XmlSchemaGroupRef)) {
- XmlSchemaGroup group = (XmlSchemaGroup)schemas.Find(((XmlSchemaGroupRef)item).RefName, typeof(XmlSchemaGroup), false);
- AddRef(refs, group);
- }
- else if (typeof(XmlSchemaGroupBase).IsAssignableFrom(t)) {
- foreach (XmlSchemaObject o in ((XmlSchemaGroupBase)item).Items) {
- Depends(o, refs);
- }
- }
- else if (t == typeof(XmlSchemaAttributeGroupRef)) {
- XmlSchemaAttributeGroup group = (XmlSchemaAttributeGroup)schemas.Find(((XmlSchemaAttributeGroupRef)item).RefName, typeof(XmlSchemaAttributeGroup), false);
- AddRef(refs, group);
- }
- else if (t == typeof(XmlSchemaAttributeGroup)) {
- foreach (XmlSchemaObject o in ((XmlSchemaAttributeGroup)item).Attributes) {
- Depends(o, refs);
- }
- }
- else if (t == typeof(XmlSchemaAttribute)) {
- XmlSchemaAttribute at = (XmlSchemaAttribute)item;
- if (!at.RefName.IsEmpty) {
- at = (XmlSchemaAttribute)schemas.Find(at.RefName, typeof(XmlSchemaAttribute), false);
- AddRef(refs, at);
- }
- else if (!at.SchemaTypeName.IsEmpty) {
- XmlSchemaType type = (XmlSchemaType)schemas.Find(at.SchemaTypeName, typeof(XmlSchemaType), false);
- AddRef(refs, type);
- }
- else {
- Depends(at.SchemaType, refs);
- }
- }
- if (typeof(XmlSchemaAnnotated).IsAssignableFrom(t)) {
- XmlAttribute[] attrs = (XmlAttribute[])((XmlSchemaAnnotated)item).UnhandledAttributes;
- if (attrs != null) {
- for (int i = 0; i < attrs.Length; i++) {
- XmlAttribute attribute = attrs[i];
- if (attribute.LocalName == Wsdl.ArrayType && attribute.NamespaceURI == Wsdl.Namespace) {
- string dims;
- XmlQualifiedName qname = TypeScope.ParseWsdlArrayType(attribute.Value, out dims, item);
- XmlSchemaType type = (XmlSchemaType)schemas.Find(qname, typeof(XmlSchemaType), false);
- AddRef(refs, type);
- }
- }
- }
- }
- }
- }
- }
|