XML11NSDocumentScannerImpl.java revision 286
286N/A * reserved comment block 286N/A * DO NOT REMOVE OR ALTER! 286N/A * The Apache Software License, Version 1.1 286N/A * Copyright (c) 1999-2003 The Apache Software Foundation. 286N/A * Redistribution and use in source and binary forms, with or without 286N/A * modification, are permitted provided that the following conditions 286N/A * 1. Redistributions of source code must retain the above copyright 286N/A * notice, this list of conditions and the following disclaimer. 286N/A * 2. Redistributions in binary form must reproduce the above copyright 286N/A * notice, this list of conditions and the following disclaimer in 286N/A * the documentation and/or other materials provided with the 286N/A * 3. The end-user documentation included with the redistribution, 286N/A * if any, must include the following acknowledgment: 286N/A * "This product includes software developed by the 286N/A * Alternately, this acknowledgment may appear in the software itself, 286N/A * if and wherever such third-party acknowledgments normally appear. 286N/A * 4. The names "Xerces" and "Apache Software Foundation" must 286N/A * not be used to endorse or promote products derived from this 286N/A * software without prior written permission. For written 286N/A * permission, please contact apache@apache.org. 286N/A * 5. Products derived from this software may not be called "Apache", 286N/A * nor may "Apache" appear in their name, without prior written 286N/A * permission of the Apache Software Foundation. 286N/A * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 286N/A * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 286N/A * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 286N/A * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 286N/A * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 286N/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 286N/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 286N/A * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 286N/A * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 286N/A * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 286N/A * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 286N/A * ==================================================================== 286N/A * This software consists of voluntary contributions made by many 286N/A * individuals on behalf of the Apache Software Foundation and was 286N/A * originally based on software copyright (c) 2002, International 286N/A * information on the Apache Software Foundation, please see 286N/A * The scanner acts as the source for the document 286N/A * information which is communicated to the document handler. 286N/A * This class scans an XML document, checks if document has a DTD, and if 286N/A * DTD is not found the scanner will remove the DTD Validator from the pipeline and perform 286N/A * Note: This scanner should only be used when the namespace processing is on! 286N/A * This component requires the following features and properties from the 286N/A * component manager that uses it: 286N/A * feature is set to false this scanner must not be used.</li> 286N/A * @author Elena Litani, IBM 286N/A * @author Michael Glavassevich, IBM 286N/A * @author Sunitha Reddy, Sun Microsystems 286N/A * If is true, the dtd validator is no longer in the pipeline 286N/A * and the scanner should bind namespaces 286N/A * If validating parser, make sure we report an error in the 286N/A * scanner if DTD grammar is missing. 286N/A * Saw spaces after element name or between attributes. 286N/A * This is reserved for the case where scanning of a start element spans 286N/A * several methods, as is the case when scanning the start of a root element 286N/A * where a DTD external subset may be read after scanning the element name. 286N/A * The scanner is responsible for removing DTD validator 286N/A * from the pipeline if it is not needed. 286N/A * @param validator the DTD validator from the pipeline 286N/A * Scans a start element. This method will handle the binding of 286N/A * namespace information and notifying the handler of the start 286N/A * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' 286N/A * [40] STag ::= '<' Name (S Attribute)* S? '>' 286N/A * <strong>Note:</strong> This method assumes that the leading 286N/A * '<' character has been consumed. 286N/A * <strong>Note:</strong> This method uses the fElementQName and 286N/A * fAttributes variables. The contents of these variables will be 286N/A * destroyed. The caller should copy important information out of 286N/A * these variables before calling this method. 286N/A * @return True if element is empty. (i.e. It matches 286N/A // Note: namespace processing is on by default 286N/A // REVISIT - [Q] Why do we need this local variable? -- mrglavas 286N/A "MSG_GRAMMAR_NOT_FOUND",
286N/A "RootElementTypeMustMatchDoctypedecl",
286N/A // Second chance. Check if this character is a high 286N/A // surrogate of a valid name start character. 286N/A "ElementAttributeLimit",
286N/A // REVISIT: is it required? forbit xmlns prefix for element 286N/A // assign uri to the element 286N/A // make sure that object in the element stack is updated as well 286N/A // making sure that the object in the element stack is updated too. 286N/A "ElementPrefixUnbound",
286N/A // bind attributes (xmlns are already bound bellow) 286N/A // REVISIT: try removing the first "if" and see if it is faster. 286N/A "AttributePrefixUnbound",
286N/A "AttributeNSNotUnique",
286N/A //decrease the markup depth.. 286N/A // check that this element was opened in the same entity 286N/A "ElementEntityMismatch",
286N/A /*if (fBindNamespaces) { 286N/A fNamespaceContext.popContext(); 286N/A //pop the element off the stack.. 286N/A }
// scanStartElement():boolean 286N/A * Scans the name of an element in a start or empty tag. 286N/A * @see #scanStartElement() 286N/A // Note: namespace processing is on by default 286N/A // Must skip spaces here because the DTD scanner 286N/A // would consume them at the end of the external subset. 286N/A }
// scanStartElementName() 286N/A * Scans the remainder of a start or empty tag after the element name. 286N/A * @see #scanStartElement 286N/A * @return True if element is empty. 286N/A // REVISIT - [Q] Why do we need this local variable? -- mrglavas 286N/A "MSG_GRAMMAR_NOT_FOUND",
286N/A "RootElementTypeMustMatchDoctypedecl",
286N/A // Second chance. Check if this character is a high 286N/A // surrogate of a valid name start character. 286N/A // REVISIT: is it required? forbit xmlns prefix for element 286N/A // assign uri to the element 286N/A // make sure that object in the element stack is updated as well 286N/A // making sure that the object in the element stack is updated too. 286N/A "ElementPrefixUnbound",
286N/A // bind attributes (xmlns are already bound bellow) 286N/A // REVISIT: try removing the first "if" and see if it is faster. 286N/A "AttributePrefixUnbound",
286N/A "AttributeNSNotUnique",
286N/A //decrease the markup depth.. 286N/A // check that this element was opened in the same entity 286N/A "ElementEntityMismatch",
286N/A //pop the element off the stack.. 286N/A }
// scanStartElementAfterName() 286N/A * [41] Attribute ::= Name Eq AttValue 286N/A * <strong>Note:</strong> This method assumes that the next 286N/A * character on the stream is the first character of the attribute 286N/A * <strong>Note:</strong> This method uses the fAttributeQName and 286N/A * fQName variables. The contents of these variables will be 286N/A * @param attributes The attributes list for the scanned attribute. 286N/A "EqRequiredInAttribute",
286N/A // WFC: Unique Att Spec 286N/A //REVISIT: one more case needs to be included: external PE and standalone is no 286N/A // REVISIT: it seems that this function should not take attributes, and length 286N/A // record namespace declarations if any. 286N/A // when it's of form xmlns="..." or xmlns:prefix="...", 286N/A // it's a namespace declaration. but prefix:xmlns="..." isn't. 286N/A // get the internalized value of this attribute 286N/A // 1. "xmlns" can't be bound to any namespace 286N/A // 2. the namespace for "xmlns" can't be bound to any prefix 286N/A // 3. "xml" can't be bound to any other namespace than it's own 286N/A // 4. the namespace for "xml" can't be bound to any other prefix 286N/A // Declare prefix in context. Removing the association between a prefix and a 286N/A // namespace name is permitted in XML 1.1, so if the uri value is the empty string, 286N/A // the prefix is being unbound. -- mrglavas 286N/A // bind namespace attribute to a namespace 286N/A // attempt to bind attribute 286N/A }
// scanAttribute(XMLAttributes) 286N/A * Scans an end element. 286N/A * [42] ETag ::= '</' Name S? '>' 286N/A * <strong>Note:</strong> This method uses the fElementQName variable. 286N/A * The contents of this variable will be destroyed. The caller should 286N/A * copy the needed information out of this variable before calling 286N/A * @return The element depth. 286N/A // Take advantage of the fact that next string _should_ be "fElementQName.rawName", 286N/A //In scanners most of the time is consumed on checks done for XML characters, we can 286N/A // optimize on it and avoid the checks done for endElement, 286N/A //we will also avoid symbol table lookup - neeraj.bajaj@sun.com 286N/A // this should work both for namespace processing true or false... 286N/A //REVISIT: if the string is not the same as expected.. we need to do better error handling.. 286N/A //We can skip this for now... In any case if the string doesn't match -- document is not well formed. 286N/A //we have increased the depth for two markup "<" characters 286N/A // check that this element was opened in the same entity 286N/A "ElementEntityMismatch",
286N/A /*if (fBindNamespaces) { 286N/A fNamespaceContext.popContext(); 286N/A }
// scanEndElement():int 286N/A /** Creates a content Driver. */ 286N/A }
// createContentDriver():Driver 286N/A /** return the next state on the input 286N/A //since namespace context should still be valid when the parser is at the end element state therefore 286N/A //we pop the context only when next() has been called after the end element state was encountered. - nb. 286N/A * Driver to handle content scanning. 286N/A * Scan for root element hook. This method is a hook for 286N/A * subclasses to add code that handles scanning for the root 286N/A * element. This method will also attempt to remove DTD validator 286N/A * from the pipeline, if there is no DTD grammar. If DTD validator 286N/A * is no longer in the pipeline bind namespaces in the scanner. 286N/A * @return True if the caller should stop and return true which 286N/A * allows the scanner to switch to a new scanning 286N/A * Driver. A return value of false indicates that 286N/A * the content Driver should continue as normal. 286N/A }
// scanRootElementHook():boolean 286N/A * Re-configures pipeline by removing the DTD validator 286N/A * if no DTD grammar exists. If no validator exists in the 286N/A * pipeline or there is no DTD grammar, namespace binding 286N/A * is performed by the scanner in the enclosing class. 286N/A // re-configure pipeline 286N/A }
// reconfigurePipeline()