Author: mrglavas
Date: Sun Jan 29 22:38:26 2006
New Revision: 373451

URL: http://svn.apache.org/viewcvs?rev=373451&view=rev
Log:
Fixing JIRA Bug #506:
http://issues.apache.org/jira/browse/XERCESJ-506

Repairing the warn-on-undeclared-elemdef feature which has been broken for
many releases. When this feature is enabled, a warning is reported if an
element referenced in a content model is not declared.

Modified:
    xerces/java/trunk/src/org/apache/xerces/impl/dtd/DTDGrammar.java
    xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDLoader.java
    xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDProcessor.java

Modified: xerces/java/trunk/src/org/apache/xerces/impl/dtd/DTDGrammar.java
URL: 
http://svn.apache.org/viewcvs/xerces/java/trunk/src/org/apache/xerces/impl/dtd/DTDGrammar.java?rev=373451&r1=373450&r2=373451&view=diff
==============================================================================
--- xerces/java/trunk/src/org/apache/xerces/impl/dtd/DTDGrammar.java (original)
+++ xerces/java/trunk/src/org/apache/xerces/impl/dtd/DTDGrammar.java Sun Jan 29 
22:38:26 2006
@@ -1243,6 +1243,15 @@
         return true;
 
     } // getElementDecl(int,XMLElementDecl):boolean
+    
+    QName getElementDeclName(int elementDeclIndex) {
+        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
+            return null;
+        }
+        int chunk = elementDeclIndex >> CHUNK_SHIFT;
+        int index = elementDeclIndex &  CHUNK_MASK;
+        return fElementDeclName[chunk][index];
+    }
 
     // REVISIT: Make this getAttributeDeclCount/getAttributeDeclAt. -Ac
 

Modified: xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDLoader.java
URL: 
http://svn.apache.org/viewcvs/xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDLoader.java?rev=373451&r1=373450&r2=373451&view=diff
==============================================================================
--- xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDLoader.java 
(original)
+++ xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDLoader.java Sun Jan 
29 22:38:26 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -85,6 +85,7 @@
     private static final String[] LOADER_RECOGNIZED_FEATURES = {
         VALIDATION,
         WARN_ON_DUPLICATE_ATTDEF,
+        WARN_ON_UNDECLARED_ELEMDEF,
         NOTIFY_CHAR_REFS,
         STANDARD_URI_CONFORMANT_FEATURE,
         BALANCE_SYNTAX_TREES
@@ -208,7 +209,10 @@
         } 
         else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) {
             fWarnDuplicateAttdef = state;
-        } 
+        }
+        else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) {
+            fWarnOnUndeclaredElemdef = state;
+        }
         else if (featureId.equals(NOTIFY_CHAR_REFS)) {
             fDTDScanner.setFeature(featureId, state);
         } 
@@ -314,7 +318,10 @@
         } 
         else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) {
             return fWarnDuplicateAttdef;
-        } 
+        }
+        else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) {
+            return fWarnOnUndeclaredElemdef;
+        }
         else if (featureId.equals(NOTIFY_CHAR_REFS)) {
             return fDTDScanner.getFeature(featureId);
         }

Modified: xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDProcessor.java
URL: 
http://svn.apache.org/viewcvs/xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDProcessor.java?rev=373451&r1=373450&r2=373451&view=diff
==============================================================================
--- xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDProcessor.java 
(original)
+++ xerces/java/trunk/src/org/apache/xerces/impl/dtd/XMLDTDProcessor.java Sun 
Jan 29 22:38:26 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2002,2004,2005 The Apache Software Foundation.
+ * Copyright 1999-2002,2004-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -88,13 +88,17 @@
     /** Feature identifier: notify character references. */
     protected static final String NOTIFY_CHAR_REFS =
         Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE;
-
+    
     /** Feature identifier: warn on duplicate attdef */
     protected static final String WARN_ON_DUPLICATE_ATTDEF = 
-        Constants.XERCES_FEATURE_PREFIX 
+Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE; 
+        Constants.XERCES_FEATURE_PREFIX 
+Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
+    
+    /** Feature identifier: warn on undeclared element referenced in content 
model. */
+    protected static final String WARN_ON_UNDECLARED_ELEMDEF =
+        Constants.XERCES_FEATURE_PREFIX + 
Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
         
        protected static final String PARSER_SETTINGS = 
-                       Constants.XERCES_FEATURE_PREFIX + 
Constants.PARSER_SETTINGS;
+        Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
 
     // property identifiers
 
@@ -120,6 +124,7 @@
     private static final String[] RECOGNIZED_FEATURES = {
         VALIDATION,
         WARN_ON_DUPLICATE_ATTDEF,
+        WARN_ON_UNDECLARED_ELEMDEF,
         NOTIFY_CHAR_REFS,
     };
 
@@ -127,6 +132,7 @@
     private static final Boolean[] FEATURE_DEFAULTS = {
         null,
         Boolean.FALSE,
+        Boolean.FALSE,
         null,
     };
 
@@ -162,6 +168,9 @@
 
     /** warn on duplicate attribute definition, this feature works only when 
validation is true */
     protected boolean fWarnDuplicateAttdef;
+    
+    /** warn on undeclared element referenced in content model, this feature 
only works when valiation is true */
+    protected boolean fWarnOnUndeclaredElemdef;
         
     // properties
 
@@ -312,9 +321,16 @@
 
         try {
             fWarnDuplicateAttdef = 
componentManager.getFeature(WARN_ON_DUPLICATE_ATTDEF);
-        } catch (XMLConfigurationException e) {
+        } 
+        catch (XMLConfigurationException e) {
             fWarnDuplicateAttdef = false;
         }
+        try {
+            fWarnOnUndeclaredElemdef = 
componentManager.getFeature(WARN_ON_UNDECLARED_ELEMDEF);
+        } 
+        catch (XMLConfigurationException e) {
+            fWarnOnUndeclaredElemdef = false;
+        }
 
         // get needed components
         fErrorReporter =
@@ -1277,7 +1293,6 @@
             if(fGrammarPool != null)
                 fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_DTD, new 
Grammar[] {fDTDGrammar});
         }
-        // check VC: Notation declared,  in the production of NDataDecl
         if (fValidation) {
             DTDGrammar grammar = (fDTDGrammar != null? fDTDGrammar: 
fGrammarBucket.getActiveGrammar());
 
@@ -1322,9 +1337,15 @@
                                                
XMLErrorReporter.SEVERITY_ERROR);
                 }
             }
-
-            fTableOfIDAttributeNames = null;//should be safe to release these 
references
+            
+            // should be safe to release these references
+            fTableOfIDAttributeNames = null;
             fTableOfNOTATIONAttributeNames = null;
+            
+            // check whether each element referenced in a content model is 
declared
+            if (fWarnOnUndeclaredElemdef) {
+                checkDeclaredElements(grammar);
+            }
         }
 
         // call handlers
@@ -1643,7 +1664,6 @@
         return false;
     }
 
-    
     protected boolean isValidNmtoken(String nmtoken) {
         return XMLChar.isValidNmtoken(nmtoken);
     } // isValidNmtoken(String):  boolean
@@ -1651,4 +1671,61 @@
     protected boolean isValidName(String name) {
         return XMLChar.isValidName(name);
     } // isValidName(String):  boolean
+    
+    /** 
+     * Checks that all elements referenced in content models have
+     * been declared. This method calls out to the error handler 
+     * to indicate warnings.
+     */
+    private void checkDeclaredElements(DTDGrammar grammar) {
+        int elementIndex = grammar.getFirstElementDeclIndex();
+        XMLContentSpec contentSpec = new XMLContentSpec();
+        while (elementIndex >= 0) {
+            int type = grammar.getContentSpecType(elementIndex);
+            if (type == XMLElementDecl.TYPE_CHILDREN || type == 
XMLElementDecl.TYPE_MIXED) {
+                checkDeclaredElements(grammar, 
+                        elementIndex, 
+                        grammar.getContentSpecIndex(elementIndex),
+                        contentSpec);
+            }
+            elementIndex = grammar.getNextElementDeclIndex(elementIndex);
+        }
+    }
+    
+    /** 
+     * Does a recursive (if necessary) check on the specified element's
+     * content spec to make sure that all children refer to declared
+     * elements.
+     */
+    private void checkDeclaredElements(DTDGrammar grammar, int elementIndex, 
+            int contentSpecIndex, XMLContentSpec contentSpec) {
+        grammar.getContentSpec(contentSpecIndex, contentSpec);
+        if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
+            String value = (String) contentSpec.value;
+            if (value != null && grammar.getElementDeclIndex(value) == -1) {
+                fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
+                        "UndeclaredElementInContentSpec",
+                        new 
Object[]{grammar.getElementDeclName(elementIndex).rawname, value},
+                        XMLErrorReporter.SEVERITY_WARNING);
+            }
+        } 
+        else {
+            // It's not a leaf, so we have to recurse its left and maybe right
+            // nodes. Save both values before we recurse and trash the node.
+            final int leftNode = ((int[])contentSpec.value)[0];
+            final int rightNode = ((int[])contentSpec.otherValue)[0];
+            if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
+                || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
+                //  Recurse on both children.
+                checkDeclaredElements(grammar, elementIndex, leftNode, 
contentSpec);
+                checkDeclaredElements(grammar, elementIndex, rightNode, 
contentSpec);
+            }
+            else if (contentSpec.type == 
XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
+                  || contentSpec.type == 
XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
+                  || contentSpec.type == 
XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
+                checkDeclaredElements(grammar, elementIndex, leftNode, 
contentSpec);
+            }
+        }
+    }
+    
 } // class XMLDTDProcessor



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to