home *** CD-ROM | disk | FTP | other *** search
/ Cre@te Online 2000 December / Cre@teOnline CD05.iso / MacSoft / XML ConsoleMax.sea / XML ConsoleMax / Required / esc.jar / com / extensibility / validation / Validator.class (.txt) < prev    next >
Encoding:
Java Class File  |  2000-06-30  |  12.6 KB  |  415 lines

  1. package com.extensibility.validation;
  2.  
  3. import com.extensibility.dom.AttrOwnerCache;
  4. import com.extensibility.dom.DOMUtilities;
  5. import com.extensibility.util.Debug;
  6. import com.extensibility.util.HashVector;
  7. import com.extensibility.util.regexpr.Pattern;
  8. import com.extensibility.util.regexpr.PatternTerm;
  9. import com.extensibility.xml.AttributeDeclaration;
  10. import com.extensibility.xml.BaseDeclaration;
  11. import com.extensibility.xml.ContentModel;
  12. import com.extensibility.xml.ContentModelTerm;
  13. import com.extensibility.xml.ContentModelTermEnum;
  14. import com.extensibility.xml.ElementDeclaration;
  15. import com.extensibility.xml.SchemaIntf;
  16. import com.extensibility.xml.SchemaSpace;
  17. import com.extensibility.xml.URIResolver;
  18. import com.extensibility.xml.XMLTypeRef;
  19. import com.extensibility.xml.dt.DataType;
  20. import java.util.Enumeration;
  21. import java.util.Hashtable;
  22. import java.util.Vector;
  23. import org.w3c.dom.Attr;
  24. import org.w3c.dom.CharacterData;
  25. import org.w3c.dom.Document;
  26. import org.w3c.dom.Element;
  27. import org.w3c.dom.NamedNodeMap;
  28. import org.w3c.dom.Node;
  29. import org.w3c.dom.ProcessingInstruction;
  30.  
  31. public final class Validator {
  32.    static final ValidatorError NO_ERROR = new ValidatorError();
  33.    SchemaSpace schemaSpace;
  34.    boolean stopValidating;
  35.    Hashtable elementPatternMap;
  36.    HashVector elementAttributesMap;
  37.    Vector globalAttributes;
  38.  
  39.    public Validator(SchemaIntf var1) {
  40.       this(new SchemaSpace("", var1));
  41.    }
  42.  
  43.    public Validator(SchemaSpace var1) {
  44.       this.elementPatternMap = new Hashtable();
  45.       this.elementAttributesMap = new HashVector();
  46.       this.globalAttributes = new Vector();
  47.       this.schemaSpace = var1;
  48.       this.globalAttributes.addElement("xml:lang");
  49.       this.globalAttributes.addElement("xmlns");
  50.       this.globalAttributes.addElement("a-dtype");
  51.       this.globalAttributes.addElement("e-dtype");
  52.    }
  53.  
  54.    public void stop() {
  55.       this.stopValidating = true;
  56.    }
  57.  
  58.    public void reset() {
  59.       this.stopValidating = false;
  60.    }
  61.  
  62.    public ValidatorErrorList validateDocument(Document var1, AttrOwnerCache var2, URIResolver var3) {
  63.       ValidatorErrorList var4 = new ValidatorErrorList();
  64.       this.validateDocument(var1, var4, var2, var3);
  65.       return var4;
  66.    }
  67.  
  68.    public void validateDocument(Document var1, ValidatorErrorList var2, AttrOwnerCache var3, URIResolver var4) {
  69.       for(Node var5 = var1.getFirstChild(); var5 != null; var5 = var5.getNextSibling()) {
  70.          this.validateDeep(var5, var2, var3, var4);
  71.       }
  72.  
  73.    }
  74.  
  75.    public void validateDeep(Node var1, ValidatorErrorList var2, AttrOwnerCache var3, URIResolver var4) {
  76.       if (!this.stopValidating) {
  77.          Thread.yield();
  78.          if (var1.getNodeType() != 3 && var1.getNodeType() != 4) {
  79.             if (var1.getNodeType() == 1) {
  80.                this.validateElement((Element)var1, var2, var3, var4);
  81.                NamedNodeMap var5;
  82.                if (var3 != null) {
  83.                   var5 = var3.getNodeAttributes(var1);
  84.                } else {
  85.                   var5 = var1.getAttributes();
  86.                }
  87.  
  88.                for(int var6 = 0; var6 < var5.getLength(); ++var6) {
  89.                   this.validateAttribute(var1, (Attr)var5.item(var6), var2, var4);
  90.                }
  91.  
  92.                for(Node var7 = var1.getFirstChild(); var7 != null; var7 = var7.getNextSibling()) {
  93.                   if (var7.getNodeType() != 3 && var7.getNodeType() != 4) {
  94.                      this.validateDeep(var7, var2, var3, var4);
  95.                   }
  96.                }
  97.             } else {
  98.                Debug.assert(var1.getNodeType() != 2, "expected non-attribute");
  99.                this.validateLeaf(var1, var2, var3, var4);
  100.             }
  101.          } else {
  102.             this.validateDeep(var1.getParentNode(), var2, var3, var4);
  103.          }
  104.  
  105.       }
  106.    }
  107.  
  108.    public void validateElement(Element var1, ValidatorErrorList var2, AttrOwnerCache var3, URIResolver var4) {
  109.       var2.remove(var1);
  110.       this.validateElementAttributes(var1, var2, var3, var4);
  111.       ValidatorError var5 = this.validateElementContent(var1, var4);
  112.       if (var5 != NO_ERROR) {
  113.          var2.add(var5);
  114.       }
  115.  
  116.    }
  117.  
  118.    public void validateLeaf(Node var1, ValidatorErrorList var2, AttrOwnerCache var3, URIResolver var4) {
  119.       if (var1.getNodeType() == 8) {
  120.          var2.remove(var1);
  121.          String var5 = var1.getNodeValue();
  122.          if (var5 != null && var5.indexOf("--") >= 0) {
  123.             var2.add(new ValidatorError((CharacterData)var1, "\"--\" not allowed in comment node"));
  124.          }
  125.       } else if (var1.getNodeType() == 7) {
  126.          var2.remove(var1);
  127.          String var6 = var1.getNodeValue();
  128.          if (var6 == null || var6.trim().equals("")) {
  129.             var2.add(new ValidatorError((ProcessingInstruction)var1, "processing instruction node needs target"));
  130.          }
  131.  
  132.          if (var6.indexOf("?>") >= 0) {
  133.             var2.add(new ValidatorError((ProcessingInstruction)var1, "\">?\" not allowed in processing instruction node"));
  134.          }
  135.       } else if (var1.getNodeType() == 3) {
  136.          Node var7 = var1.getParentNode();
  137.          if (var7 instanceof Element) {
  138.             this.validateElement((Element)var7, var2, var3, var4);
  139.          }
  140.       }
  141.  
  142.    }
  143.  
  144.    public void validateAttribute(Node var1, Attr var2, ValidatorErrorList var3, URIResolver var4) {
  145.       var3.remove(var2);
  146.       String var5 = var2.getNodeName();
  147.       String var6 = LeafValidator.getTrimmedNodeValue(var2);
  148.       SchemaIntf var7 = DOMUtilities.getGoverningSchema(var1, var2, this.schemaSpace, var4);
  149.       AttributeDeclaration var8 = var7 == null ? null : var7.getNamedAttribute(DOMUtilities.getUnqualifiedName(var1), DOMUtilities.getUnqualifiedName(var2));
  150.       if (var8 != null) {
  151.          DataType var9 = var8.getDataType();
  152.          if (var9 != null) {
  153.             String var10 = LeafValidator.validate(var7, var9, var6);
  154.             if (var10 != null) {
  155.                var3.add(new ValidatorError(var2, var1, var10));
  156.             }
  157.          } else if (var8.isEnumeration()) {
  158.             Vector var11 = var8.getChoices();
  159.             if (var11 != null && var11.indexOf(var6) < 0) {
  160.                var3.add(new ValidatorError(var2, var1, "value doesn't match enumeration"));
  161.             }
  162.          }
  163.       }
  164.  
  165.    }
  166.  
  167.    public void validateElementAttributes(Element var1, ValidatorErrorList var2, AttrOwnerCache var3, URIResolver var4) {
  168.       String var5 = var1.getNodeName();
  169.       NamedNodeMap var6;
  170.       if (var3 != null) {
  171.          var6 = var3.getNodeAttributes(var1);
  172.       } else {
  173.          var6 = var1.getAttributes();
  174.       }
  175.  
  176.       int var7 = 0;
  177.       SchemaIntf var8 = DOMUtilities.getGoverningSchema(var1, (Node)null, this.schemaSpace, var4);
  178.       ElementDeclaration var9 = var8 == null ? null : var8.getNamedElement(DOMUtilities.getUnqualifiedName(var1));
  179.       if (var9 != null) {
  180.          Enumeration var10 = var9.getAttributes(true);
  181.  
  182.          while(var10.hasMoreElements()) {
  183.             AttributeDeclaration var11 = (AttributeDeclaration)var10.nextElement();
  184.             String var12 = ((BaseDeclaration)var11).getName();
  185.             if (var6.getNamedItem(var12) != null) {
  186.                ++var7;
  187.             } else if (var11.getRequired()) {
  188.                var2.add(new ValidatorError(var1, (Node)null, String.valueOf(String.valueOf("attribute \"").concat(String.valueOf(var12))).concat(String.valueOf("\" is required"))));
  189.             }
  190.          }
  191.  
  192.          if (var7 < var6.getLength()) {
  193.             Vector var15;
  194.             if (this.elementAttributesMap.get(var5) != null) {
  195.                var15 = this.elementAttributesMap.getVector(var5);
  196.             } else {
  197.                var15 = new Vector();
  198.                var10 = var9.getAttributes(true);
  199.  
  200.                while(var10.hasMoreElements()) {
  201.                   AttributeDeclaration var16 = (AttributeDeclaration)var10.nextElement();
  202.                   var15.addElement(((BaseDeclaration)var16).getName());
  203.                }
  204.  
  205.                this.elementAttributesMap.put(var5, var15);
  206.             }
  207.  
  208.             for(int var17 = 0; var17 < var6.getLength(); ++var17) {
  209.                String var13 = var6.item(var17).getNodeName();
  210.                if (var15.indexOf(var13) < 0 && this.globalAttributes.indexOf(var13) < 0 && var13.indexOf("xmlns") != 0) {
  211.                   var2.add(new ValidatorError(var1, var6.item(var17), String.valueOf(String.valueOf("undeclared attribute: \"").concat(String.valueOf(var13))).concat(String.valueOf("\""))));
  212.                }
  213.             }
  214.          }
  215.       }
  216.  
  217.    }
  218.  
  219.    public ValidatorError validateElementContent(Element var1, URIResolver var2) {
  220.       SchemaIntf var3 = DOMUtilities.getGoverningSchema(var1, (Node)null, this.schemaSpace, var2);
  221.       ElementDeclaration var4 = var3 == null ? null : var3.getNamedElement(DOMUtilities.getUnqualifiedName(var1));
  222.       if (var4 == null) {
  223.          String var12 = DOMUtilities.getNamePrefix(var1.getNodeName());
  224.          return var12 != null && !var12.equals("") && !var12.equals("xml") && DOMUtilities.getPrefixDeclaredNamespace(var1, var12) == null ? new ValidatorError(var1, (Node)null, "invalid namespace prefix (no matching xmlns attribute)") : new ValidatorError(var1, (Node)null, "no declaration");
  225.       } else {
  226.          ContentModel var5 = var4.getContentModel();
  227.          if (var5.isTextOnly()) {
  228.             for(Node var13 = var1.getFirstChild(); var13 != null; var13 = var13.getNextSibling()) {
  229.                if (var13.getNodeType() == 1) {
  230.                   return new ValidatorError(var1, var13, "elements not allowed in text-only content");
  231.                }
  232.             }
  233.  
  234.             DataType var14 = var4.getDataType();
  235.             if (var14 != null) {
  236.                String var15 = DOMUtilities.getTextValue(var1, var3);
  237.                String var16 = LeafValidator.validate(var3, var14, var15);
  238.                if (var16 != null) {
  239.                   return new ValidatorError(var1, (Node)null, var16);
  240.                }
  241.             }
  242.  
  243.             return NO_ERROR;
  244.          } else if (var5.isAny()) {
  245.             return this.validateANY(var1, var2);
  246.          } else if (var5.isEmpty()) {
  247.             return var1.getFirstChild() == null ? NO_ERROR : new ValidatorError(var1, (Node)null, "nothing allowed in empty content");
  248.          } else {
  249.             Pattern var6 = this.getPattern(DOMUtilities.getXMLTypeRef(var1, (Node)null, this.schemaSpace.getDefaultNS()), var5);
  250.             NodePatternInput var7 = new NodePatternInput(var1, var5.isOpen(), this.schemaSpace.getDefaultNS());
  251.             Vector var8 = new Vector();
  252.             if (var6.matches(var7, var8)) {
  253.                return NO_ERROR;
  254.             } else {
  255.                Node var9 = var7.hasNext() ? var7.peekNextNode() : null;
  256.                if (var8.size() == 0) {
  257.                   return new ValidatorError(var1, var9, String.valueOf("unexpected content at ").concat(String.valueOf(var9.getNodeName())));
  258.                } else {
  259.                   String var10 = null;
  260.                   Enumeration var11 = var8.elements();
  261.  
  262.                   while(var11.hasMoreElements()) {
  263.                      if (var10 == null) {
  264.                         var10 = var11.nextElement().toString();
  265.                      } else {
  266.                         var10 = String.valueOf(var10).concat(String.valueOf(String.valueOf(" or ").concat(String.valueOf(var11.nextElement().toString()))));
  267.                      }
  268.                   }
  269.  
  270.                   return new ValidatorError(var1, var9, String.valueOf("expected ").concat(String.valueOf(var10)));
  271.                }
  272.             }
  273.          }
  274.       }
  275.    }
  276.  
  277.    public boolean isValidCandidate(Element var1, Node var2, String var3, URIResolver var4) {
  278.       SchemaIntf var5 = DOMUtilities.getGoverningSchema(var1, (Node)null, this.schemaSpace, var4);
  279.       ElementDeclaration var6 = var5 == null ? null : var5.getNamedElement(DOMUtilities.getUnqualifiedName(var1));
  280.       if (var6 == null) {
  281.          return false;
  282.       } else {
  283.          ContentModel var7 = var6.getContentModel();
  284.          Pattern var8 = this.getPattern(DOMUtilities.getXMLTypeRef(var1, (Node)null, this.schemaSpace.getDefaultNS()), var7);
  285.          NodePatternInput var9 = new NodePatternInput(var1, var2, var3, var7.isOpen(), this.schemaSpace.getDefaultNS());
  286.          return var8.matches(var9);
  287.       }
  288.    }
  289.  
  290.    public Vector getPotentialChildren(Element var1, Node var2, URIResolver var3) {
  291.       Vector var4 = new Vector();
  292.       SchemaIntf var5 = DOMUtilities.getGoverningSchema(var1, (Node)null, this.schemaSpace, var3);
  293.       ElementDeclaration var6 = var5 == null ? null : var5.getNamedElement(DOMUtilities.getUnqualifiedName(var1));
  294.       if (var6 != null) {
  295.          ContentModel var7 = var6.getContentModel();
  296.          if (!var7.isTextOnly()) {
  297.             if (var7.isAny()) {
  298.                Enumeration var8 = var5.getElementDeclarations();
  299.  
  300.                while(var8.hasMoreElements()) {
  301.                   var4.addElement(((ElementDeclaration)var8.nextElement()).getName());
  302.                }
  303.             } else if (!var7.isEmpty()) {
  304.                XMLTypeRef var19 = DOMUtilities.getXMLTypeRef(var1, (Node)null, this.schemaSpace.getDefaultNS());
  305.                Pattern var9 = this.getPattern(var19, var7);
  306.                NodePatternInput var10 = new NodePatternInput(var1, var2, var7.isOpen(), this.schemaSpace.getDefaultNS());
  307.                Vector var11 = new Vector();
  308.                var9.matches(var10, var11);
  309.                String var12 = var19.getElementNamespace();
  310.                if (var10.hasNext()) {
  311.                   var11 = var9.getFollowers(var2 == null ? null : var2.getNodeName());
  312.                } else {
  313.                   String var13 = var10.getPatternNS();
  314.                   Node var14;
  315.                   if (var2 == null) {
  316.                      var14 = NodePatternInput.skipWhitespace(var1.getFirstChild(), this.schemaSpace.getDefaultNS(), var13);
  317.                   } else {
  318.                      var14 = NodePatternInput.skipWhitespace(var2.getNextSibling(), this.schemaSpace.getDefaultNS(), var13);
  319.                   }
  320.  
  321.                   if (var14 != null && this.indexOfNode(var11, var14) >= 0) {
  322.                      String var15 = var14.getNodeName();
  323.  
  324.                      while(true) {
  325.                         Node var16 = NodePatternInput.skipWhitespace(var14.getNextSibling(), this.schemaSpace.getDefaultNS(), var13);
  326.                         if (var16 == null || !var16.getNodeName().equals(var15)) {
  327.                            Vector var25 = new Vector();
  328.                            var9.matches(new NodePatternInput(var1, var14, var7.isOpen(), this.schemaSpace.getDefaultNS()), var25);
  329.                            if (this.indexOfNode(var25, var14) == -1) {
  330.                               var11.removeElementAt(this.indexOfNode(var11, var14));
  331.                            }
  332.                            break;
  333.                         }
  334.  
  335.                         var14 = var16;
  336.                      }
  337.                   }
  338.                }
  339.  
  340.                ContentModelTermEnum var20 = ((ContentModelTerm)var7).getLeafTerms();
  341.                Vector var21 = new Vector();
  342.  
  343.                while(var20.hasMoreElements()) {
  344.                   ContentModelTerm var22 = var20.nextContentModelTerm();
  345.                   ContentModelPatternTerm var26 = new ContentModelPatternTerm(var12, var22);
  346.                   String var17 = var22.getTerm();
  347.                   String var18 = var26.getTermQualifiedName();
  348.                   if (indexOfName(var11, var18) >= 0 && var21.indexOf(var17) < 0) {
  349.                      var21.addElement(var17);
  350.                   }
  351.                }
  352.  
  353.                var4 = var21;
  354.                String var23 = DOMUtilities.getNamespacePrefix(var12, var1);
  355.                if (var23 != null && !var23.equals("")) {
  356.                   var23 = String.valueOf(var23).concat(String.valueOf(":"));
  357.  
  358.                   for(int var27 = 0; var27 < var4.size(); ++var27) {
  359.                      String var28 = (String)var4.elementAt(var27);
  360.                      if (var28.indexOf(":") == -1) {
  361.                         var4.setElementAt(String.valueOf(var23).concat(String.valueOf(var28)), var27);
  362.                      }
  363.                   }
  364.                }
  365.             }
  366.          }
  367.       }
  368.  
  369.       var4.removeElement("#PCDATA");
  370.       return var4;
  371.    }
  372.  
  373.    protected static int indexOfName(Vector var0, String var1) {
  374.       for(int var2 = 0; var2 < var0.size(); ++var2) {
  375.          if (((PatternTerm)var0.elementAt(var2)).matches(var1)) {
  376.             return var2;
  377.          }
  378.       }
  379.  
  380.       return -1;
  381.    }
  382.  
  383.    protected int indexOfNode(Vector var1, Node var2) {
  384.       XMLTypeRef var3 = DOMUtilities.getXMLTypeRef(var2, (Node)null, this.schemaSpace.getDefaultNS());
  385.       String var4 = var3.getFullName();
  386.       return indexOfName(var1, var4);
  387.    }
  388.  
  389.    protected Pattern getPattern(XMLTypeRef var1, ContentModel var2) {
  390.       Pattern var3 = (Pattern)this.elementPatternMap.get(var1);
  391.       if (var3 == null) {
  392.          var3 = new Pattern(new ContentModelPatternTerm(var1.getElementNamespace(), var2));
  393.          this.elementPatternMap.put(var1, var3);
  394.       }
  395.  
  396.       return var3;
  397.    }
  398.  
  399.    public ValidatorError validateANY(Element var1, URIResolver var2) {
  400.       SchemaIntf var3 = DOMUtilities.getGoverningSchema(var1, (Node)null, this.schemaSpace, var2);
  401.       if (var3 != null) {
  402.          for(Node var4 = var1.getFirstChild(); var4 != null; var4 = var4.getNextSibling()) {
  403.             if (var4.getNodeType() == 1) {
  404.                String var5 = var4.getNodeName();
  405.                if (var3.getNamedElement(var5) == null) {
  406.                   return new ValidatorError(var1, var4, "unrecognized member for ANY content");
  407.                }
  408.             }
  409.          }
  410.       }
  411.  
  412.       return NO_ERROR;
  413.    }
  414. }
  415.