mrglavas    2005/05/25 08:43:43

  Modified:    java/src/org/apache/xerces/jaxp/validation
                        DOMValidatorHelper.java
  Log:
  If the validation root is not the document element we must go up
  the ancestor chain to generate the namespace context. Created
  a namespace context which will walk up the ancestor chain of the
  DOMSource. It will only read the ancestor chain if there is no
  namespace/prefix mapping in the main namespace context.
  
  Revision  Changes    Path
  1.3       +145 -2    
xml-xerces/java/src/org/apache/xerces/jaxp/validation/DOMValidatorHelper.java
  
  Index: DOMValidatorHelper.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/java/src/org/apache/xerces/jaxp/validation/DOMValidatorHelper.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DOMValidatorHelper.java   25 May 2005 05:00:26 -0000      1.2
  +++ DOMValidatorHelper.java   25 May 2005 15:43:43 -0000      1.3
  @@ -17,6 +17,7 @@
   package org.apache.xerces.jaxp.validation;
   
   import java.io.IOException;
  +import java.util.Enumeration;
   import java.util.Locale;
   
   import javax.xml.parsers.DocumentBuilder;
  @@ -102,6 +103,9 @@
       /** The namespace context of this document: stores namespaces in scope. 
**/
       private NamespaceContext fNamespaceContext;
       
  +    /** The namespace context of the DOMSource, includes context from 
ancestor nodes. **/
  +    private DOMNamespaceContext fDOMNamespaceContext = new 
DOMNamespaceContext();
  +    
       /** Schema validator. **/
       private org.apache.xerces.impl.xs.XMLSchemaValidator fSchemaValidator;
       
  @@ -132,6 +136,9 @@
       /** Array for holding character data. **/
       private char [] fCharBuffer = new char[CHUNK_SIZE];
       
  +    /** Root node. **/
  +    private Node fRoot;
  +    
       /** Current element. **/
       private Node fCurrentElement;
       
  @@ -160,9 +167,11 @@
               final DOMSource domSource = (DOMSource) source;
               final DOMResult domResult = (DOMResult) result;
               Node node = domSource.getNode();
  +            fRoot = node;
               if (node != null) {
                   fComponentManager.reset();
                   fValidationManager.setEntityState(this);
  +                fDOMNamespaceContext.reset();
                   String systemId = domSource.getSystemId();
                   fXMLLocator.setLiteralSystemId(systemId);
                   fXMLLocator.setExpandedSystemId(systemId);
  @@ -171,7 +180,7 @@
                       // regardless of what type of node this is, fire start 
and end document events
                       setupEntityMap((node.getNodeType() == 
Node.DOCUMENT_NODE) ? (Document) node : node.getOwnerDocument());
                       setupDOMResultHandler(domSource, domResult);
  -                    fSchemaValidator.startDocument(fXMLLocator, null, 
fNamespaceContext, null);
  +                    fSchemaValidator.startDocument(fXMLLocator, null, 
fDOMNamespaceContext, null);
                       validate(node);
                       fSchemaValidator.endDocument(null);
                   }
  @@ -183,6 +192,7 @@
                   }
                   finally {
                       // Release references to application objects
  +                    fRoot = null;
                       fCurrentElement = null;
                       fEntities = null;
                       if (fDOMValidatorHandler != null) {
  @@ -441,4 +451,137 @@
           return fCurrentElement;
       }
       
  +    /**
  +     * NamespaceContext for the DOMSource, includes context for ancestor 
nodes.
  +     */
  +    final class DOMNamespaceContext implements NamespaceContext {
  +        
  +        //
  +        // Data
  +        //
  +
  +        /** 
  +         * Namespace binding information. This array is composed of a
  +         * series of tuples containing the namespace binding information:
  +         * <prefix, uri>.
  +         */
  +        protected String[] fNamespace = new String[16 * 2];
  +
  +        /** The size of the namespace information array. */
  +        protected int fNamespaceSize = 0;
  +        
  +        /** 
  +         * Flag indicating whether the namespace context 
  +         * has been from the root node's ancestors.
  +         */
  +        protected boolean fDOMContextBuilt = false;
  +        
  +        //
  +        // Methods
  +        //
  +
  +        public void pushContext() {
  +            fNamespaceContext.pushContext();
  +        }
  +
  +        public void popContext() {
  +            fNamespaceContext.popContext();
  +        }
  +
  +        public boolean declarePrefix(String prefix, String uri) {
  +            return fNamespaceContext.declarePrefix(prefix, uri);
  +        }
  +
  +        public String getURI(String prefix) {
  +            String uri = fNamespaceContext.getURI(prefix);
  +            if (uri == null) {
  +                if (!fDOMContextBuilt) {
  +                    fillNamespaceContext();
  +                    fDOMContextBuilt = true;
  +                }
  +                uri = getURI0(prefix);
  +            }
  +            return uri;
  +        }
  +
  +        public String getPrefix(String uri) {
  +            return fNamespaceContext.getPrefix(uri);
  +        }
  +
  +        public int getDeclaredPrefixCount() {
  +            return fNamespaceContext.getDeclaredPrefixCount();
  +        }
  +
  +        public String getDeclaredPrefixAt(int index) {
  +            return fNamespaceContext.getDeclaredPrefixAt(index);
  +        }
  +
  +        public Enumeration getAllPrefixes() {
  +            return fNamespaceContext.getAllPrefixes();
  +        }
  +
  +        public void reset() {
  +            fDOMContextBuilt = false;
  +            fNamespaceSize = 0; 
  +        }
  +        
  +        private void fillNamespaceContext() {
  +            if (fRoot != null) {
  +                Node currentNode = fRoot.getParentNode();
  +                while (currentNode != null) {
  +                    if (Node.ELEMENT_NODE == currentNode.getNodeType()) {
  +                        NamedNodeMap attributes = 
currentNode.getAttributes();
  +                        final int attrCount = attributes.getLength();
  +                        for (int i = 0; i < attrCount; ++i) {
  +                            Attr attr = (Attr) attributes.item(i);
  +                            String value = attr.getValue();
  +                            if (value == null) {
  +                                value = XMLSymbols.EMPTY_STRING;
  +                            }
  +                            fillQName(fAttributeQName, attr);
  +                            // REVISIT: Should we be looking at 
non-namespace attributes
  +                            // for additional mappings? Should we detect 
illegal namespace
  +                            // declarations and exclude them from the 
context? -- mrglavas
  +                            if (fAttributeQName.uri == 
NamespaceContext.XMLNS_URI) {
  +                                // process namespace attribute
  +                                if (fAttributeQName.prefix == 
XMLSymbols.PREFIX_XMLNS) {
  +                                    
declarePrefix0(fAttributeQName.localpart, fSymbolTable.addSymbol(value));
  +                                }
  +                                else {
  +                                    declarePrefix0(XMLSymbols.EMPTY_STRING, 
fSymbolTable.addSymbol(value));
  +                                }
  +                            }
  +                        }
  +                        
  +                    }
  +                    currentNode = currentNode.getParentNode();
  +                }
  +            }
  +        }
  +        
  +        private void declarePrefix0(String prefix, String uri) {           
  +            // resize array, if needed
  +            if (fNamespaceSize == fNamespace.length) {
  +                String[] namespacearray = new String[fNamespaceSize * 2];
  +                System.arraycopy(fNamespace, 0, namespacearray, 0, 
fNamespaceSize);
  +                fNamespace = namespacearray;
  +            }
  +
  +            // bind prefix to uri in current context
  +            fNamespace[fNamespaceSize++] = prefix;
  +            fNamespace[fNamespaceSize++] = uri;
  +        }
  +        
  +        private String getURI0(String prefix) {
  +            // find prefix in the DOM context
  +            for (int i = 0; i < fNamespaceSize; i += 2) {
  +                if (fNamespace[i] == prefix) {
  +                    return fNamespace[i + 1];
  +                }
  +            }
  +            // prefix not found
  +            return null;
  +        }
  +    }
  +    
   } // DOMValidatorHelper
  
  
  

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

Reply via email to