Пример #1
0
 public SchemaValidator(Module targetModule, ValidationState context, TypeNode schemaType, SchemaAttDef[] attributes, ContentValidator validator){
   this.context = context;
   this.schemaType = schemaType;
   this.attributes = attributes;
   this.targetModule  = targetModule;
   if (attributes != null) {
     attrSpecified = new bool[attributes.Length];
   }
   this.validator = validator;
   if (this.validator != null)
     this.validator.InitValidation(context);
 }
Пример #2
0
    protected SchemaElementDecl(Module targetModule, TypeNode schemaType, TypeNode elementType, ErrorHandler errorHandler) {
      this.context = new ValidationState();
      this.context.ProcessContents = XmlSchemaContentProcessing.Strict;
      this.context.ErrorHandler = errorHandler;
      this.context.Name = schemaType.Name;
      this.targetModule = targetModule;

      this.schemaType = schemaType;
      TypeNode scheType = schemaType;
      if (scheType is TypeAlias) {
        TypeAlias alias = (TypeAlias)scheType;
        scheType = alias.AliasedType;
      }
      if (scheType.IsPrimitive || scheType == SystemTypes.String) return;
      ArrayList allElements = new ArrayList(); // for "all" content model.
      ArrayList attdefs = new ArrayList();

      this.builder = new ContentModelBuilder(XmlSchemaContentType.ElementOnly);
      this.builder.Start(); // start building.    
      
      if (schemaType.Template == SystemTypes.GenericList || 
        schemaType.Template == SystemTypes.GenericIEnumerable ||
        schemaType.Template == SystemTypes.GenericList ||
        schemaType.Template == SystemTypes.GenericIList ||
        Checker.IsList(schemaType)) {
        // then this is a collection which is modelled as a star group.
        CompileGenericList(elementType, 0, Int32.MaxValue, null);
        goto FinishUp;// finish building & compile it.
      } else if (schemaType.Template == SystemTypes.GenericNonEmptyIEnumerable) {
        CompileGenericList(schemaType, 1, Int32.MaxValue, null);
        goto FinishUp;// finish building & compile it.
      } else if (schemaType.Template == SystemTypes.GenericBoxed) {
        CompileGenericList(schemaType, 0, 1, null);
        goto FinishUp;// finish building & compile it.
      } else if (schemaType is TypeUnion) {
        CompileTypeUnion(schemaType as TypeUnion, null);
        goto FinishUp;// finish building & compile it.
      } else if (schemaType is TupleType) {
        CompileTuple(schemaType as TupleType, null);
        goto FinishUp;// finish building & compile it.
      } 

      builder.OpenGroup();

      // assemble all base types so we can walk them in parent-to-child order.
      ArrayList scheTypes = new ArrayList();
      while (scheType != null) {
        scheTypes.Add(scheType);
        scheType = scheType.BaseType;
      }

      // walk from top most base class to child class, since that's the 
      // order of the content model.
      for (int typeindex = scheTypes.Count-1; typeindex>=0; typeindex--) {
        scheType = (TypeNode)scheTypes[typeindex];
        // Now walk all our members, and look for custom attributes that indicate
        // whether those members are elements or attributes (the default is
        // to make it an element).
        MemberList members = scheType.Members;
        for (int i = 0, n = members == null ? 0 : members.Length; i < n; i++) {
          Member mem = members[i];
          if (mem == null) continue; // type resolution error.
          Field f = mem as Field;
          Property p = mem as Property;
          Identifier memName = mem.Name;

          if (f == null && p == null) continue;

          TypeNode memType = f != null ? f.Type : p.Type;
          if (memType == null) continue; // must be a type error.

          // Rule out members that are not public, static
          if ((f == null || f.IsStatic || !f.IsPublic) &&
              (p == null || p.IsStatic || !p.IsPublic))
            continue;
        
          if (p != null && p.Setter == null) {
            // Property has no setter, perhaps it is a collection in which case
            // we can "add" to the collection without constructing it, which is fine.
            if (!Checker.IsList(memType)) continue;
          }
            
          TypeNode ceType = Checker.GetCollectionElementType(memType);
          TypeNode originalElementType = ceType;

          AttributeList attrs = mem.Attributes;
          int m = attrs == null ? 0 : attrs.Length;        

          bool isList = (Checker.GetListInterface(memType) != null) || memType is ArrayType;
          if (isList) {
            // Calculate the real TypeUnion for the list element types 
            // from the list of XmlElementAttributes.
            TypeNodeList types = new TypeNodeList();
            for (int j = m-1; j >= 0; j--) {
              AttributeNode attr = attrs[j];
              if (attr == null) continue;
              TypeNode attrType = GetAttributeType(attr);
              if (attrType == null) continue;// must be a type error.
              if (attrType == Runtime.XmlElementAttributeClass) {
                TypeNode aType = GetAttrType(attr, 1, SchemaElementDecl.TypeId);
                if (aType != null) {
                  types.Add(aType);
                }
              }
            }
            if (types.Length > 1) {
              ceType = TypeUnion.For(types, this.targetModule);
            } else if (types.Length == 1) {
              ceType = types[0];
            }
          }

          // The attributes repeat the content structure for each field.
          bool handled = false;                   
          bool hasElementGroup = false;
          TypeNodeList elementTypes = new TypeNodeList();

          // Walk the attributes backwards because the outer contains (e.g. sequence)
          // is listed last in the IL.
          for (int j = m-1; j >= 0; j--) {
            AttributeNode attr = attrs[j];
            if (attr == null) continue;
            TypeNode attrType = GetAttributeType(attr);
            if (attrType == null) continue;// must be a type error.

            if (attrType == Runtime.XmlAttributeAttributeClass) 
            {
              // pick up the XML attribute name from the custom attribute, if any
              Identifier id = GetXmlName(mem.Name, attr);
              attdefs.Add(new SchemaAttDef(id, mem));
              handled = true;
              break;
            } 
            else if (attrType == Runtime.XmlElementAttributeClass) 
            { 
              // This is for element renaming and support for legacy XmlSerializer collections
              TypeNode aType = GetAttrType(attr, 1, SchemaElementDecl.TypeId);
              if (aType == null) 
                aType = ceType;
              else if (ceType != null && (memType is ArrayType) && ! aType.IsAssignableTo(originalElementType)) 
                context.HandleError(null, attr, Error.NoImplicitConversion, ErrorHandler.GetTypeNameFor(aType), ErrorHandler.GetTypeNameFor(originalElementType));

              memName = GetXmlName(memName, attr);
              
              if (isList) 
              {
                // eg:
                //    [XmlElement("f", typeof(int)),
                //    XmlElement("g", typeof(string))]
                //    public ArrayList children;
                // which is modelled as (f|g)*                      
                
                if (!hasElementGroup) {
                  builder.OpenGroup();
                  builder.AddNamedTerminal(memName, new Method(), aType);
                  hasElementGroup = true;
                } else {
                  builder.AddChoice(new Method(), ceType);
                  builder.AddNamedTerminal(memName, new Method(), aType);                  
                }
                handled = true;
              }
              else 
              {
                // then just drop through to adding this element to the allElements group.                
                ceType = aType;
              }
            }
            else if (attrType == Runtime.XmlIgnoreAttributeClass) {
              handled = true;
              break;
            } 
            else if (attrType == Runtime.XmlTextAttributeClass) {
              // this is a hack implementation of mixed content.
              builder.MixedMember = mem;
              handled = true;
            }
          }
          if (hasElementGroup) {
            builder.CloseGroup();
            builder.AddStar(mem, memType);
            hasElementGroup = false;
          }
          if (!handled) {
            if (mem.IsAnonymous) {
              TypeNode type = Unwrap(memType);
              if (type is TupleType) {
                CompileTuple(type as TupleType, mem);
              } else if (type.Template == SystemTypes.GenericList || 
                         type.Template == SystemTypes.GenericIList ||
                         type.Template == SystemTypes.GenericList ||
                         type.Template == SystemTypes.GenericIEnumerable) {
                CompileGenericList(type, 0, Int32.MaxValue, mem);
              } else if (type.Template == SystemTypes.GenericNonEmptyIEnumerable) {
                CompileGenericList(type,1, Int32.MaxValue, mem);
              } else if (type is TypeUnion) {
                CompileTypeUnion(type as TypeUnion, mem);
              } else if (type.Template == SystemTypes.GenericBoxed) {
                CompileGenericList(type, 0, 1, mem);
              } 
              else if (memType is TypeAlias) {
                TypeAlias alias = memType as TypeAlias;
                builder.AddNamedTerminal(alias.Name, mem, alias.AliasedType);
              }
              else {
                builder.AddNamedTerminal(Checker.GetDefaultElementName(type), mem, type);
              }
            } else {
              // Then we treat this as part of an all group instead.
              // bugbug: how do we pass the ceType information along?
              if (memType is TypeAlias) {
                TypeAlias alias = memType as TypeAlias;
                allElements.Add(new NamedNode(alias.Name, mem, alias.AliasedType));
              } else {
                allElements.Add(new NamedNode(memName, mem, memType));
              }              
            }
          }
        } // endfor
      }
      builder.CloseGroup();
      
FinishUp:
      validator = builder.Finish(context, true); // finish building & compile it.

      if (attdefs.Count>0) {
        attributes = (SchemaAttDef[])attdefs.ToArray(typeof(SchemaAttDef));
      }

      if (allElements.Count>0) {
        // todo: handle the case where there is a mix of fields and real content model?
        if (!(validator.ContentType == XmlSchemaContentType.Empty ||
          validator.ContentType == XmlSchemaContentType.TextOnly)) {
          NamedNode n = (NamedNode)allElements[0];
          this.context.HandleError(null, n.Member, Error.ContentModelNotSupported, ErrorHandler.GetTypeNameFor(schemaType));
        }
        AllElementsContentValidator allValidator = new AllElementsContentValidator(builder.MixedMember, allElements.Count, true);
        foreach (NamedNode node in allElements) {
          allValidator.AddElement(node, true);
        }
        validator = allValidator;
      }
    }
Пример #3
0
 public override int ValidateExpression(ValidationState context, ContentValidator subExpr) {
   ParticleContentValidator subval = subExpr as ParticleContentValidator;
   if (subval != null) {
     ContentNode node = this.contentRoot.LeftChild;
     ContentNode root = subval.contentRoot.LeftChild;
     if (context.CurrentNode != null) {
       node = context.CurrentNode;
       if (node.Parent is SequenceNode) {
         // then we are in the middle of a content model and we have to try and match
         // the next expected thing
         node = ((SequenceNode)context.CurrentNode.Parent).RightChild;
       }
     } 
     // walk to left most leaf node (which is the next expected thing).
     while (node is InternalNode) {
       node = ((InternalNode)node).LeftChild;
     }
     // Now see if the expression matches this node or one of the parent nodes 
     // (like perhaps a StarNode and so on).
     while (node != null) {
       if (node.Matches(root)) {            
         // "match" all the terminal nodes in "root" so that we advance the
         // state machine accordingly.
         AdvanceState(root, context);
         context.CurrentNode = node;
         return 1;
       } 
       node = node.Parent;
     }
     return -1;
   }
   if (contentRoot.LeftChild is WildcardNode) {
     context.CurrentNode = contentRoot.LeftChild;
     return 1;
   }
   return -1;
 }
Пример #4
0
 public override int ValidateExpression(ValidationState context, ContentValidator subExpr) {
   return -1;
 }
Пример #5
0
 public virtual int ValidateExpression(ValidationState context, ContentValidator subExpr) {
   return -1;
 }