elena 2002/09/12 14:56:57 Modified: java/src/org/apache/xerces/impl XMLDocumentFragmentScannerImpl.java XMLDocumentScannerImpl.java java/src/org/apache/xerces/impl/dtd XMLDTDValidator.java java/src/org/apache/xerces/impl/xs/dom DOMParser.java java/src/org/apache/xerces/util XMLAttributesImpl.java Added: java/src/org/apache/xerces/impl XMLNSDocumentScannerImpl.java java/src/org/apache/xerces/impl/dtd XMLDTDValidatorFilter.java XMLNSDTDValidator.java java/src/org/apache/xerces/parsers IntegratedParserConfiguration.java Log: Add a specialized scanner implementation that is also responsible for binding the namespace. This scanner will not bind namespaces if DTD grammar is available since it might add some default namespace attribute. Add a new DTD Validator that is responsible to bind namespaces, in case the scanner could not do it. Create a new parser configuration that uses this scanner and DTD validator and does not include the XMLNamespaceBinder in the pipeline. This should increase the spead of parsing from 6%-12% (depending on the size of the document and document structure). More changes will be added later -- to optimize namespace binding in the DTD, and in the scanner. Revision Changes Path 1.20 +25 -23 xml-xerces/java/src/org/apache/xerces/impl/XMLDocumentFragmentScannerImpl.java Index: XMLDocumentFragmentScannerImpl.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/XMLDocumentFragmentScannerImpl.java,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- XMLDocumentFragmentScannerImpl.java 11 Sep 2002 20:22:35 -0000 1.19 +++ XMLDocumentFragmentScannerImpl.java 12 Sep 2002 21:56:56 -0000 1.20 @@ -190,7 +190,7 @@ private static final boolean DEBUG_DISPATCHER = false; /** Debug content dispatcher scanning. */ - private static final boolean DEBUG_CONTENT_SCANNING = false; + protected static final boolean DEBUG_CONTENT_SCANNING = false; // // Data @@ -250,14 +250,23 @@ // temporary variables - /** Array of 3 strings. */ - private String[] fStrings = new String[3]; + /** Element QName. */ + protected QName fElementQName = new QName(); + + /** Attribute QName. */ + protected QName fAttributeQName = new QName(); + + /** Element attributes. */ + protected XMLAttributesImpl fAttributes = new XMLAttributesImpl(); /** String. */ - private XMLString fString = new XMLString(); + protected XMLString fTempString = new XMLString(); /** String. */ - private XMLString fString2 = new XMLString(); + protected XMLString fTempString2 = new XMLString(); + + /** Array of 3 strings. */ + private String[] fStrings = new String[3]; /** String buffer. */ private XMLStringBuffer fStringBuffer = new XMLStringBuffer(); @@ -265,17 +274,10 @@ /** String buffer. */ private XMLStringBuffer fStringBuffer2 = new XMLStringBuffer(); - /** Element QName. */ - private QName fElementQName = new QName(); - - /** Attribute QName. */ - private QName fAttributeQName = new QName(); /** Another QName. */ private QName fQName = new QName(); - /** Element attributes. */ - private XMLAttributesImpl fAttributes = new XMLAttributesImpl(); /** Single character array. */ private final char[] fSingleChar = new char[1]; @@ -815,11 +817,11 @@ } //REVISIT: one more case needs to be included: external PE and standalone is no boolean isVC = fHasExternalDTD && !fStandalone; - scanAttributeValue(fString, fString2, + scanAttributeValue(fTempString, fTempString2, fAttributeQName.rawname, attributes, oldLen, isVC); - attributes.setValue(oldLen, fString.toString()); - attributes.setNonNormalizedValue(oldLen, fString2.toString()); + attributes.setValue(oldLen, fTempString.toString()); + attributes.setNonNormalizedValue(oldLen, fTempString2.toString()); attributes.setSpecified(oldLen, true); if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanAttribute()"); @@ -832,13 +834,13 @@ */ protected int scanContent() throws IOException, XNIException { - XMLString content = fString; + XMLString content = fTempString; int c = fEntityScanner.scanContent(content); if (c == '\r') { // happens when there is the character reference fEntityScanner.scanChar(); fStringBuffer.clear(); - fStringBuffer.append(fString); + fStringBuffer.append(fTempString); fStringBuffer.append((char)c); content = fStringBuffer; c = -1; @@ -847,7 +849,7 @@ fDocumentHandler.characters(content, null); } - if (c == ']' && fString.length == 0) { + if (c == ']' && fTempString.length == 0) { fStringBuffer.clear(); fStringBuffer.append((char)fEntityScanner.scanChar()); // remember where we are in case we get an endEntity before we @@ -881,7 +883,7 @@ /** * Scans a CDATA section. * <p> - * <strong>Note:</strong> This method uses the fString and + * <strong>Note:</strong> This method uses the fTempString and * fStringBuffer variables. * * @param complete True if the CDATA section is to be scanned @@ -1114,8 +1116,8 @@ } fSingleChar[0] = c; - fString.setValues(fSingleChar, 0, 1); - fDocumentHandler.characters(fString, null); + fTempString.setValues(fSingleChar, 0, 1); + fDocumentHandler.characters(fTempString, null); if (fNotifyBuiltInRefs) { fDocumentHandler.endGeneralEntity(entity, null); @@ -1528,7 +1530,7 @@ fStringBuffer.append((char)fEntityScanner.scanChar()); } String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length); - scanPIData(target, fString); + scanPIData(target, fTempString); } // standard text declaration 1.22 +2 -2 xml-xerces/java/src/org/apache/xerces/impl/XMLDocumentScannerImpl.java Index: XMLDocumentScannerImpl.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/XMLDocumentScannerImpl.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- XMLDocumentScannerImpl.java 15 Aug 2002 17:51:22 -0000 1.21 +++ XMLDocumentScannerImpl.java 12 Sep 2002 21:56:56 -0000 1.22 @@ -886,7 +886,7 @@ * @author Andy Clark, IBM * @author Eric Ye, IBM */ - protected final class ContentDispatcher + protected class ContentDispatcher extends FragmentContentDispatcher { // 1.1 xml-xerces/java/src/org/apache/xerces/impl/XMLNSDocumentScannerImpl.java Index: XMLNSDocumentScannerImpl.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999-2002 The Apache Software Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xerces" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2002, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.xerces.impl; import java.io.IOException; import org.apache.xerces.impl.msg.XMLMessageFormatter; import org.apache.xerces.impl.dtd.XMLDTDValidatorFilter; import org.apache.xerces.util.SymbolTable; import org.apache.xerces.util.XMLSymbols; import org.apache.xerces.util.NamespaceSupport; import org.apache.xerces.util.SymbolTable; import org.apache.xerces.util.XMLAttributesImpl; import org.apache.xerces.util.XMLChar; import org.apache.xerces.xni.QName; import org.apache.xerces.xni.NamespaceContext; import org.apache.xerces.xni.XMLString; import org.apache.xerces.xni.XNIException; import org.apache.xerces.xni.XMLDocumentHandler; import org.apache.xerces.xni.parser.XMLDocumentFilter; import org.apache.xerces.xni.parser.XMLComponentManager; import org.apache.xerces.xni.parser.XMLConfigurationException; /** * The scanner acts as the source for the document * information which is communicated to the document handler. * * This class scans an XML document, checks if document has a DTD, and if * DTD is not found the scanner will remove the DTD Validator from the pipeline and perform * namespace binding. * * Note: This scanner should only be used when the namespace processing is on! * * <p> * This component requires the following features and properties from the * component manager that uses it: * <ul> * <li>http://xml.org/sax/features/namespaces {true} -- if the value of this * feature is set to false this scanner must not be used.</li> * <li>http://xml.org/sax/features/validation</li> * <li>http://apache.org/xml/features/nonvalidating/load-external-dtd</li> * <li>http://apache.org/xml/features/scanner/notify-char-refs</li> * <li>http://apache.org/xml/features/scanner/notify-builtin-refs</li> * <li>http://apache.org/xml/properties/internal/symbol-table</li> * <li>http://apache.org/xml/properties/internal/error-reporter</li> * <li>http://apache.org/xml/properties/internal/entity-manager</li> * <li>http://apache.org/xml/properties/internal/dtd-scanner</li> * </ul> * * @author Elena Litani, IBM * * @version $Id: XMLNSDocumentScannerImpl.java,v 1.1 2002/09/12 21:56:56 elena Exp $ */ public class XMLNSDocumentScannerImpl extends XMLDocumentScannerImpl { /** If is true, the dtd validator is no longer in the pipeline * and the scanner should bind namespaces */ protected boolean fBindNamespaces; /** If validating parser, make sure we report an error in the * scanner if DTD grammar is missing.*/ protected boolean fPerformValidation; /** Namespace support. */ protected NamespaceSupport fNamespaceSupport = new NamespaceSupport(); protected String[] fUri= new String[4]; protected String[] fLocalpart = new String[4]; protected int fLength = 0; // private data // /** The filter component before DTD validator if any. If the DTDValidator followed the scanner, this field is null.*/ private XMLDocumentFilter fPreviousComponent; /** DTD validator */ private XMLDTDValidatorFilter fDTDValidator; /** The document handler (of filter) after the DTD validator */ private XMLDocumentHandler fNextComponent; /** * The scanner is responsible for removing DTD validator * from the pipeline if it is not needed. * * @param previous The filter component before DTDValidator * @param dtdValidator * The DTDValidator * @param next The documentHandler after the DTDValidator */ public void setComponents(XMLDocumentFilter previous, XMLDTDValidatorFilter dtd, XMLDocumentHandler next){ fPreviousComponent = previous; fDTDValidator = dtd; fNextComponent = next; } /** * Scans a start element. This method will handle the binding of * namespace information and notifying the handler of the start * of the element. * <p> * <pre> * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' * [40] STag ::= '<' Name (S Attribute)* S? '>' * </pre> * <p> * <strong>Note:</strong> This method assumes that the leading * '<' character has been consumed. * <p> * <strong>Note:</strong> This method uses the fElementQName and * fAttributes variables. The contents of these variables will be * destroyed. The caller should copy important information out of * these variables before calling this method. * * @returns True if element is empty. (i.e. It matches * production [44]. */ protected boolean scanStartElement() throws IOException, XNIException { if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanStartElementNS()"); String rawname = null; // Note: namespace processing is on by default fEntityScanner.scanQName(fElementQName); if (fBindNamespaces) { fNamespaceSupport.pushContext(); rawname = fElementQName.rawname; if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) { if (fPerformValidation) { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "MSG_GRAMMAR_NOT_FOUND", new Object[]{ rawname}, XMLErrorReporter.SEVERITY_ERROR); if (fDoctypeName == null || !fDoctypeName.equals(rawname)) { fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN, "RootElementTypeMustMatchDoctypedecl", new Object[]{fDoctypeName, rawname}, XMLErrorReporter.SEVERITY_ERROR); } } } } // push element stack fCurrentElement = fElementStack.pushElement(fElementQName); // attributes boolean empty = false; fAttributes.removeAllAttributes(); do { // spaces boolean sawSpace = fEntityScanner.skipSpaces(); // end tag? int c = fEntityScanner.peekChar(); if (c == '>') { fEntityScanner.scanChar(); break; } else if (c == '/') { fEntityScanner.scanChar(); if (!fEntityScanner.skipChar('>')) { reportFatalError("ElementUnterminated", new Object[]{rawname}); } empty = true; break; } else if (!XMLChar.isNameStart(c) || !sawSpace) { reportFatalError("ElementUnterminated", new Object[]{rawname}); } // attributes scanAttribute(fAttributes); } while (true); if (fBindNamespaces) { // REVISIT: is it required? forbit xmlns prefix for element if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "ElementXMLNSPrefix", new Object[]{fElementQName.rawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // bind the element String prefix = fElementQName.prefix != null ? fElementQName.prefix : XMLSymbols.EMPTY_STRING; fElementQName.uri = fNamespaceSupport.getURI(prefix); if (fElementQName.prefix == null && fElementQName.uri != null) { fElementQName.prefix = XMLSymbols.EMPTY_STRING; } if (fElementQName.prefix != null && fElementQName.uri == null) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "ElementPrefixUnbound", new Object[]{fElementQName.prefix, fElementQName.rawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // bind attributes (xmlns are already bound bellow) int length = fAttributes.getLength(); fLength = 0; //initialize structure for (int i = 0; i < length; i++) { fAttributes.getName(i, fAttributeQName); String aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; String uri = fNamespaceSupport.getURI(aprefix); // REVISIT: try removing the first "if" and see if it is faster. // if (fAttributeQName.uri != null && fAttributeQName.uri == uri) { checkDuplicates(fAttributeQName, fAttributes); continue; } if (aprefix != XMLSymbols.EMPTY_STRING) { fAttributeQName.uri = uri; if (uri == null) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "AttributePrefixUnbound", new Object[]{aprefix, fAttributeQName.rawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } fAttributes.setURI(i, uri); checkDuplicates(fAttributeQName, fAttributes); } } } //handleStartElement(fElementQName, fAttributes); // call handler if (fDocumentHandler != null) { if (empty) { fDocumentHandler.emptyElement(fElementQName, fAttributes, null); // handleEndElement(fElementQName, null); if (fBindNamespaces) { int count = fNamespaceSupport.getDeclaredPrefixCount(); for (int i = count - 1; i >= 0; i--) { String prefix = fNamespaceSupport.getDeclaredPrefixAt(i); fDocumentHandler.endPrefixMapping(prefix, null); } fNamespaceSupport.popContext(); } //decrease the markup depth.. fMarkupDepth--; // check that this element was opened in the same entity if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { reportFatalError("ElementEntityMismatch", new Object[]{fCurrentElement.rawname}); } //pop the element off the stack.. fElementStack.popElement(fElementQName); } else { fDocumentHandler.startElement(fElementQName, fAttributes, null); } } if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanStartElement(): "+empty); return empty; } // scanStartElement():boolean private final void checkDuplicates(QName qname, XMLAttributesImpl attributes){ // Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/> // search if such attribute already exists for (int i = 0; i < fLength; i++) { if (qname.uri == fUri[i] && fLocalpart[i].equals(qname.localpart)) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "AttributeNSNotUnique", new Object[]{fElementQName.rawname,qname.uri, qname.uri}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } int index = fLength; if (fLength++ == fUri.length) { String[] uris = new String[fUri.length + 4]; String[] lps = new String [fUri.length + 4]; System.arraycopy(fUri, 0, uris, 0, fUri.length); System.arraycopy(fLocalpart, 0, lps, 0, fLocalpart.length); fUri = uris; fLocalpart = lps; } fUri[index] = qname.uri; fLocalpart[index] = qname.localpart; } /** * Scans an attribute. * <p> * <pre> * [41] Attribute ::= Name Eq AttValue * </pre> * <p> * <strong>Note:</strong> This method assumes that the next * character on the stream is the first character of the attribute * name. * <p> * <strong>Note:</strong> This method uses the fAttributeQName and * fQName variables. The contents of these variables will be * destroyed. * * @param attributes The attributes list for the scanned attribute. */ protected void scanAttribute(XMLAttributesImpl attributes) throws IOException, XNIException { if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanAttribute()"); // name fEntityScanner.scanQName(fAttributeQName); // equals fEntityScanner.skipSpaces(); if (!fEntityScanner.skipChar('=')) { reportFatalError("EqRequiredInAttribute", new Object[]{fAttributeQName.rawname}); } fEntityScanner.skipSpaces(); // content int oldLen = attributes.getLength(); attributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, null); // WFC: Unique Att Spec if (oldLen == attributes.getLength()) { reportFatalError("AttributeNotUnique", new Object[]{fCurrentElement.rawname, fAttributeQName.rawname}); } //REVISIT: one more case needs to be included: external PE and standalone is no boolean isVC = fHasExternalDTD && !fStandalone; // REVISIT: it seems that this function should not take attributes, and length scanAttributeValue(this.fTempString, fTempString2, fAttributeQName.rawname, attributes, oldLen, isVC); String value = fTempString.toString(); attributes.setValue(oldLen, value); attributes.setNonNormalizedValue(oldLen, fTempString2.toString()); attributes.setSpecified(oldLen, true); if (fBindNamespaces) { // get namespace declarations String localpart = fAttributeQName.localpart; String prefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; // when it's of form xmlns="..." or xmlns:prefix="...", // it's a namespace declaration. but prefix:xmlns="..." isn't. if (prefix == XMLSymbols.PREFIX_XMLNS || prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) { // get the internalized value of this attribute String uri = fSymbolTable.addSymbol(value); // 1. "xmlns" can't be bound to any namespace if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXMLNS", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // 2. the namespace for "xmlns" can't be bound to any prefix if (uri == NamespaceContext.XMLNS_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXMLNS", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // 3. "xml" can't be bound to any other namespace than it's own if (localpart == XMLSymbols.PREFIX_XML) { if (uri != NamespaceContext.XML_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXML", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } // 4. the namespace for "xml" can't be bound to any other prefix else { if (uri ==NamespaceContext.XML_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXML", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING; // http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-prefix // We should only report an error if there is a prefix, // that is, the local part is not "xmlns". -SG if (uri == XMLSymbols.EMPTY_STRING && localpart != XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "EmptyPrefixedAttName", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // declare prefix in context fNamespaceSupport.declarePrefix(prefix, uri.length() != 0 ? uri : null); // bind namespace attribute to a namespace attributes.setURI(oldLen, fNamespaceSupport.getURI(XMLSymbols.PREFIX_XMLNS)); // call handler if (fDocumentHandler != null) { fDocumentHandler.startPrefixMapping(prefix, uri, null); } } else { // attempt to bind attribute if (fAttributeQName.prefix != null) { attributes.setURI(oldLen, fNamespaceSupport.getURI(fAttributeQName.prefix)); } } } if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanAttribute()"); } // scanAttribute(XMLAttributes) /** * Scans an end element. * <p> * <pre> * [42] ETag ::= '</' Name S? '>' * </pre> * <p> * <strong>Note:</strong> This method uses the fElementQName variable. * The contents of this variable will be destroyed. The caller should * copy the needed information out of this variable before calling * this method. * * @returns The element depth. */ protected int scanEndElement() throws IOException, XNIException { if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanEndElement()"); // pop context fElementStack.popElement(fElementQName) ; // Take advantage of the fact that next string _should_ be "fElementQName.rawName", //In scanners most of the time is consumed on checks done for XML characters, we can // optimize on it and avoid the checks done for endElement, //we will also avoid symbol table lookup - [EMAIL PROTECTED] // this should work both for namespace processing true or false... //REVISIT: if the string is not the same as expected.. we need to do better error handling.. //We can skip this for now... In any case if the string doesn't match -- document is not well formed. if (!fEntityScanner.skipString(fElementQName.rawname)) { reportFatalError("ETagRequired", new Object[]{fElementQName.rawname}); } // end fEntityScanner.skipSpaces(); if (!fEntityScanner.skipChar('>')) { reportFatalError("ETagUnterminated", new Object[]{fElementQName.rawname}); } fMarkupDepth--; //we have increased the depth for two markup "<" characters fMarkupDepth--; // check that this element was opened in the same entity if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { reportFatalError("ElementEntityMismatch", new Object[]{fCurrentElement.rawname}); } // call handler if (fDocumentHandler != null ) { if (fBindNamespaces) { int count = fNamespaceSupport.getDeclaredPrefixCount(); for (int i = count - 1; i >= 0; i--) { String prefix = fNamespaceSupport.getDeclaredPrefixAt(i); fDocumentHandler.endPrefixMapping(prefix, null); } fNamespaceSupport.popContext(); } fDocumentHandler.endElement(fElementQName, null); } return fMarkupDepth; } // scanEndElement():int public void reset(XMLComponentManager componentManager) throws XMLConfigurationException { super.reset(componentManager); fPerformValidation = false; fBindNamespaces = false; fNamespaceSupport.reset(); } /** Creates a content dispatcher. */ protected Dispatcher createContentDispatcher() { return new NSContentDispatcher(); } // createContentDispatcher():Dispatcher /** * Dispatcher to handle content scanning. */ protected final class NSContentDispatcher extends ContentDispatcher { /** * Scan for root element hook. This method is a hook for * subclasses to add code that handles scanning for the root * element. This method will also attempt to remove DTD validator * from the pipeline, if there is no DTD grammar. If DTD validator * is no longer in the pipeline bind namespaces in the scanner. * * * @returns True if the caller should stop and return true which * allows the scanner to switch to a new scanning * dispatcher. A return value of false indicates that * the content dispatcher should continue as normal. */ protected boolean scanRootElementHook() throws IOException, XNIException { if (!fDTDValidator.hasGrammar()) { fBindNamespaces = true; fPerformValidation = fDTDValidator.validate(); // re-configure pipeline // if (fPreviousComponent != null) { // there is a filter component between scanner and DTDValidator fPreviousComponent.setDocumentHandler(fNextComponent); fNextComponent.setDocumentSource(fPreviousComponent); } else { // DTD validator was the next component after the scanner. fDocumentHandler = fNextComponent; fNextComponent.setDocumentSource(XMLNSDocumentScannerImpl.this); } } if (scanStartElement()) { setScannerState(SCANNER_STATE_TRAILING_MISC); setDispatcher(fTrailingMiscDispatcher); return true; } return false; } // scanRootElementHook():boolean } } // class XMLDocumentScannerImpl 1.32 +43 -21 xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLDTDValidator.java Index: XMLDTDValidator.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLDTDValidator.java,v retrieving revision 1.31 retrieving revision 1.32 diff -u -r1.31 -r1.32 --- XMLDTDValidator.java 16 Aug 2002 20:41:18 -0000 1.31 +++ XMLDTDValidator.java 12 Sep 2002 21:56:57 -0000 1.32 @@ -128,7 +128,7 @@ * @version $Id$ */ public class XMLDTDValidator - implements XMLComponent, XMLDocumentFilter { + implements XMLComponent, XMLDocumentFilter, XMLDTDValidatorFilter { // // Constants @@ -270,6 +270,9 @@ // state + /** True if seen DOCTYPE declaration. */ + protected boolean fSeenDoctypeDecl = false; + /** Perform validation. */ private boolean fPerformValidation; @@ -290,9 +293,6 @@ /** The root element name. */ private final QName fRootElement = new QName(); - /** True if seen DOCTYPE declaration. */ - private boolean fSeenDoctypeDecl = false; - private boolean fInCDATASection = false; // element stack @@ -721,7 +721,7 @@ public void startElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { - handleStartElement(element, attributes); + handleStartElement(element, attributes, augs); // call handlers if (fDocumentHandler != null) { fDocumentHandler.startElement(element, attributes, augs); @@ -742,7 +742,7 @@ public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { - boolean removed = handleStartElement(element, attributes); + boolean removed = handleStartElement(element, attributes, augs); if (fDocumentHandler !=null) { fDocumentHandler.emptyElement(element, attributes, augs); @@ -1036,6 +1036,17 @@ } } + + public final boolean hasGrammar(){ + + return (fDTDGrammar != null); + } + + public final boolean validate(){ + return fValidation && (!fDynamicValidation || fSeenDoctypeDecl) + && (fDTDValidation || fSeenDoctypeDecl); + } + // // Private methods // @@ -1518,7 +1529,7 @@ } /** Root element specified. */ - private void rootElementSpecified(QName rootElement) throws XNIException { + private final void rootElementSpecified(QName rootElement) throws XNIException { if (fPerformValidation) { String root1 = fRootElement.rawname; String root2 = rootElement.rawname; @@ -1761,7 +1772,8 @@ } } // ensureStackCapacity - + + // // Protected methods // @@ -1769,7 +1781,8 @@ /** Handle element * @return true if validator is removed from the pipeline */ - protected boolean handleStartElement(QName element, XMLAttributes attributes) throws XNIException { + protected boolean handleStartElement(QName element, XMLAttributes attributes, Augmentations augs) + throws XNIException { // REVISIT: Here are current assumptions about validation features // given that XMLSchema validator is in the pipeline @@ -1883,9 +1896,13 @@ fElementQNamePartsStack[fElementDepth].setValues(fCurrentElement); fElementIndexStack[fElementDepth] = fCurrentElementIndex; fContentSpecTypeStack[fElementDepth] = fCurrentContentSpecType; + startNamespaceScope(element, attributes, augs); return false; - } // handleStartElement(QName,XMLAttributes,boolean) + } // handleStartElement(QName,XMLAttributes) + + protected void startNamespaceScope(QName element, XMLAttributes attributes, Augmentations augs){ + } /** Handle end element. */ protected void handleEndElement(QName element, Augmentations augs, boolean isEmpty) @@ -1926,16 +1943,7 @@ fElementChildrenLength = fElementChildrenOffsetStack[fElementDepth + 1] + 1; } - // call handlers - if (fDocumentHandler != null && !isEmpty) { - // NOTE: The binding of the element doesn't actually happen - // yet because the namespace binder does that. However, - // if it does it before this point, then the endPrefix- - // Mapping calls get made too soon! As long as the - // rawnames match, we know it'll have a good binding, - // so we can just use the current element. -Ac - fDocumentHandler.endElement(fCurrentElement, augs); - } + endNamespaceScope(fCurrentElement, augs, isEmpty); // now pop this element off the top of the element stack if (fElementDepth < -1) { @@ -1973,5 +1981,19 @@ fInElementContent = (fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN); } // handleEndElement(QName,boolean) + + protected void endNamespaceScope(QName element, Augmentations augs, boolean isEmpty){ + + // call handlers + if (fDocumentHandler != null && !isEmpty) { + // NOTE: The binding of the element doesn't actually happen + // yet because the namespace binder does that. However, + // if it does it before this point, then the endPrefix- + // Mapping calls get made too soon! As long as the + // rawnames match, we know it'll have a good binding, + // so we can just use the current element. -Ac + fDocumentHandler.endElement(fCurrentElement, augs); + } + } } // class XMLDTDValidator 1.1 xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLDTDValidatorFilter.java Index: XMLDTDValidatorFilter.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2001, 2002 The Apache Software Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xerces" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2002, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.xerces.impl.dtd; import org.apache.xerces.xni.parser.XMLDocumentFilter; /** * Defines a DTD Validator filter to allow * components to query the DTD validator. * * @author Elena Litani, IBM * * @version $Id: XMLDTDValidatorFilter.java,v 1.1 2002/09/12 21:56:57 elena Exp $ */ public interface XMLDTDValidatorFilter extends XMLDocumentFilter { /** * Returns true if the validator has a DTD grammar * * @return */ public boolean hasGrammar(); /** * Return true if validator must validate the document * * @return */ public boolean validate(); } // interface XMLDTDValidatorFilter 1.1 xml-xerces/java/src/org/apache/xerces/impl/dtd/XMLNSDTDValidator.java Index: XMLNSDTDValidator.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999-2002 The Apache Software Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xerces" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.xerces.impl.dtd; import org.apache.xerces.impl.XMLErrorReporter; import org.apache.xerces.impl.msg.XMLMessageFormatter; import org.apache.xerces.util.NamespaceSupport; import org.apache.xerces.util.XMLSymbols; import org.apache.xerces.xni.NamespaceContext; import org.apache.xerces.xni.Augmentations; import org.apache.xerces.xni.QName; import org.apache.xerces.xni.XMLAttributes; import org.apache.xerces.xni.XMLDocumentHandler; import org.apache.xerces.xni.XNIException; import org.apache.xerces.xni.parser.XMLComponentManager; import org.apache.xerces.xni.parser.XMLConfigurationException; /** * The DTD validator. The validator implements a document * filter: receiving document events from the scanner; validating * the content and structure; augmenting the InfoSet, if applicable; * and notifying the parser of the information resulting from the * validation process. * <p> Formerly, this component also handled DTD events and grammar construction. * To facilitate the development of a meaningful DTD grammar caching/preparsing * framework, this functionality has been moved into the XMLDTDLoader * class. Therefore, this class no longer implements the DTDFilter * or DTDContentModelFilter interfaces. * <p> * This component requires the following features and properties from the * component manager that uses it: * <ul> * <li>http://xml.org/sax/features/namespaces</li> * <li>http://xml.org/sax/features/validation</li> * <li>http://apache.org/xml/features/validation/dynamic</li> * <li>http://apache.org/xml/properties/internal/symbol-table</li> * <li>http://apache.org/xml/properties/internal/error-reporter</li> * <li>http://apache.org/xml/properties/internal/grammar-pool</li> * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li> * </ul> * * @author Elena Litani, IBM * * @version $Id: XMLNSDTDValidator.java,v 1.1 2002/09/12 21:56:57 elena Exp $ */ public class XMLNSDTDValidator extends XMLDTDValidator{ /** Namespace support. */ protected NamespaceSupport fNamespaceSupport = new NamespaceSupport(); /** Attribute QName. */ private QName fAttributeQName = new QName(); public void reset(XMLComponentManager componentManager){ super.reset(componentManager); fNamespaceSupport.reset(); } /** Bind namespaces */ protected final void startNamespaceScope (QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { // add new namespace context fNamespaceSupport.pushContext(); if (element.prefix == XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "ElementXMLNSPrefix", new Object[]{element.rawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // search for new namespace bindings int length = attributes.getLength(); for (int i = 0; i < length; i++) { String localpart = attributes.getLocalName(i); String prefix = attributes.getPrefix(i); // when it's of form xmlns="..." or xmlns:prefix="...", // it's a namespace declaration. but prefix:xmlns="..." isn't. if (prefix == XMLSymbols.PREFIX_XMLNS || prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) { // get the internalized value of this attribute String uri = fSymbolTable.addSymbol(attributes.getValue(i)); // 1. "xmlns" can't be bound to any namespace if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXMLNS", new Object[]{attributes.getQName(i)}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // 2. the namespace for "xmlns" can't be bound to any prefix if (uri == NamespaceContext.XMLNS_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXMLNS", new Object[]{attributes.getQName(i)}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // 3. "xml" can't be bound to any other namespace than it's own if (localpart == XMLSymbols.PREFIX_XML) { if (uri != NamespaceContext.XML_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXML", new Object[]{attributes.getQName(i)}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } // 4. the namespace for "xml" can't be bound to any other prefix else { if (uri ==NamespaceContext.XML_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXML", new Object[]{attributes.getQName(i)}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING; // http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-prefix // We should only report an error if there is a prefix, // that is, the local part is not "xmlns". -SG if (uri == XMLSymbols.EMPTY_STRING && localpart != XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "EmptyPrefixedAttName", new Object[]{attributes.getQName(i)}, XMLErrorReporter.SEVERITY_FATAL_ERROR); continue; } // declare prefix in context fNamespaceSupport.declarePrefix(prefix, uri.length() != 0 ? uri : null); // call handler if (fDocumentHandler != null) { fDocumentHandler.startPrefixMapping(prefix, uri, augs); } } } // bind the element String prefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING; element.uri = fNamespaceSupport.getURI(prefix); if (element.prefix == null && element.uri != null) { element.prefix = XMLSymbols.EMPTY_STRING; } if (element.prefix != null && element.uri == null) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "ElementPrefixUnbound", new Object[]{element.prefix, element.rawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // bind the attributes for (int i = 0; i < length; i++) { attributes.getName(i, fAttributeQName); String aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; String arawname = fAttributeQName.rawname; if (arawname == XMLSymbols.PREFIX_XMLNS) { fAttributeQName.uri = fNamespaceSupport.getURI(XMLSymbols.PREFIX_XMLNS); attributes.setName(i, fAttributeQName); } else if (aprefix != XMLSymbols.EMPTY_STRING) { fAttributeQName.uri = fNamespaceSupport.getURI(aprefix); if (fAttributeQName.uri == null) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "AttributePrefixUnbound", new Object[]{aprefix, arawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } attributes.setName(i, fAttributeQName); } } // verify that duplicate attributes don't exist // Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/> int attrCount = attributes.getLength(); for (int i = 0; i < attrCount - 1; i++) { String alocalpart = attributes.getLocalName(i); String auri = attributes.getURI(i); for (int j = i + 1; j < attrCount; j++) { String blocalpart = attributes.getLocalName(j); String buri = attributes.getURI(j); if (alocalpart == blocalpart && auri == buri) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "AttributeNSNotUnique", new Object[]{element.rawname,alocalpart, auri}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } } } // startNamespaceScope(QName,XMLAttributes) /** Handles end element. */ protected void endNamespaceScope(QName element, Augmentations augs, boolean isEmpty) throws XNIException { // bind element String eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING; element.uri = fNamespaceSupport.getURI(eprefix); if (element.uri != null) { element.prefix = eprefix; } // call handlers if (fDocumentHandler != null) { if (!isEmpty) { fDocumentHandler.endElement(element, augs); } } // end prefix mappings if (fDocumentHandler != null) { int count = fNamespaceSupport.getDeclaredPrefixCount(); for (int i = count - 1; i >= 0; i--) { String prefix = fNamespaceSupport.getDeclaredPrefixAt(i); fDocumentHandler.endPrefixMapping(prefix, augs); } } // pop context fNamespaceSupport.popContext(); } // endNamespaceScope(QName,boolean) } 1.6 +9 -3 xml-xerces/java/src/org/apache/xerces/impl/xs/dom/DOMParser.java Index: DOMParser.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/dom/DOMParser.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- DOMParser.java 13 Aug 2002 22:57:10 -0000 1.5 +++ DOMParser.java 12 Sep 2002 21:56:57 -0000 1.6 @@ -57,7 +57,7 @@ package org.apache.xerces.impl.xs.dom; -import org.apache.xerces.parsers.NonValidatingConfiguration; +import org.apache.xerces.parsers.IntegratedParserConfiguration; import org.apache.xerces.impl.Constants; import org.apache.xerces.impl.XMLErrorReporter; import org.apache.xerces.impl.xs.SchemaSymbols; @@ -114,7 +114,10 @@ * Constructs a DOM parser using the dtd/xml schema parser configuration. */ public DOMParser() { - super(new NonValidatingConfiguration()); + // REVISIT: should we use a new configuration with scannerNS->dom API with + // no dtd scanners/valitors..? + // + super(new IntegratedParserConfiguration()); try { // use our own document implementation setProperty(DOCUMENT_CLASS, "org.apache.xerces.impl.xs.dom.DocumentImpl"); @@ -239,5 +242,8 @@ fLocator.getLineNumber(), fLocator.getColumnNumber()); } + + + } // class DOMParser 1.1 xml-xerces/java/src/org/apache/xerces/parsers/IntegratedParserConfiguration.java Index: IntegratedParserConfiguration.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2001, 2002 The Apache Software Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xerces" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 2002, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.xerces.parsers; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; import java.util.Locale; import org.apache.xerces.impl.Constants; import org.apache.xerces.impl.msg.XMLMessageFormatter; import org.apache.xerces.impl.XMLDocumentScannerImpl; import org.apache.xerces.impl.XMLNSDocumentScannerImpl; import org.apache.xerces.impl.dtd.XMLDTDValidator; import org.apache.xerces.impl.dtd.XMLNSDTDValidator; import org.apache.xerces.impl.xs.XSMessageFormatter; import org.apache.xerces.impl.xs.XMLSchemaValidator; import org.apache.xerces.util.SymbolTable; import org.apache.xerces.xni.XMLLocator; import org.apache.xerces.xni.XNIException; import org.apache.xerces.xni.grammars.XMLGrammarPool; import org.apache.xerces.xni.parser.XMLComponent; import org.apache.xerces.xni.parser.XMLDocumentScanner; import org.apache.xerces.xni.parser.XMLConfigurationException; import org.apache.xerces.xni.parser.XMLComponentManager; import org.apache.xerces.xni.parser.XMLDocumentSource; import org.apache.xerces.xni.parser.XMLInputSource; /** * This is configuration uses a scanner that integrates both scanning of the document * and binding namespaces. * * If namespace feature is turned on, the pipeline is constructured with the * following components: * XMLNSDocumentScannerImpl -> XMLNSDTDValidator -> (optional) XMLSchemaValidator * * If the namespace feature is turned off the default document scanner implementation * is used (XMLDocumentScannerImpl). * <p> * In addition to the features and properties recognized by the base * parser configuration, this class recognizes these additional * features and properties: * <ul> * <li>Features * <ul> * <li>http://apache.org/xml/features/validation/schema</li> * <li>http://apache.org/xml/features/validation/schema-full-checking</li> * <li>http://apache.org/xml/features/validation/schema/normalized-value</li> * <li>http://apache.org/xml/features/validation/schema/element-default</li> * </ul> * <li>Properties * <ul> * <li>http://apache.org/xml/properties/internal/error-reporter</li> * <li>http://apache.org/xml/properties/internal/entity-manager</li> * <li>http://apache.org/xml/properties/internal/document-scanner</li> * <li>http://apache.org/xml/properties/internal/dtd-scanner</li> * <li>http://apache.org/xml/properties/internal/grammar-pool</li> * <li>http://apache.org/xml/properties/internal/validator/dtd</li> * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li> * </ul> * </ul> * * @author Elena Litani, IBM * * @version $Id: IntegratedParserConfiguration.java,v 1.1 2002/09/12 21:56:57 elena Exp $ */ public class IntegratedParserConfiguration extends StandardParserConfiguration { // // REVISIT: should this configuration depend on the others // like DTD/Standard one? // /** Document scanner that does namespace binding. */ protected XMLNSDocumentScannerImpl fNamespaceScanner; protected XMLDocumentScannerImpl fNonNSScanner; protected XMLNSDTDValidator fNSDTDValidator; protected static final String XMLSCHEMA_VALIDATION = Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE; /** Default constructor. */ public IntegratedParserConfiguration() { this(null, null, null); } // <init>() public IntegratedParserConfiguration(SymbolTable symbolTable, XMLGrammarPool grammarPool) { this(symbolTable, grammarPool, null); } // <init>(SymbolTable,XMLGrammarPool) /** * Constructs a parser configuration using the specified symbol table, * grammar pool, and parent settings. * <p> * <strong>REVISIT:</strong> * Grammar pool will be updated when the new validation engine is * implemented. * * @param symbolTable The symbol table to use. * @param grammarPool The grammar pool to use. * @param parentSettings The parent settings. */ public IntegratedParserConfiguration(SymbolTable symbolTable, XMLGrammarPool grammarPool, XMLComponentManager parentSettings) { // save parent fParentSettings = parentSettings; // create a vector to hold all the components in use fComponents = new Vector(); // create storage for recognized features and properties fRecognizedFeatures = new Vector(); fRecognizedProperties = new Vector(); // create table for features and properties fFeatures = new Hashtable(); fProperties = new Hashtable(); // add default recognized features final String[] recognizedFeatures = { VALIDATION, NAMESPACES, EXTERNAL_GENERAL_ENTITIES, EXTERNAL_PARAMETER_ENTITIES, WARN_ON_DUPLICATE_ATTDEF, WARN_ON_UNDECLARED_ELEMDEF, ALLOW_JAVA_ENCODINGS, CONTINUE_AFTER_FATAL_ERROR, LOAD_EXTERNAL_DTD, NOTIFY_BUILTIN_REFS, NOTIFY_CHAR_REFS, WARN_ON_DUPLICATE_ENTITYDEF, NORMALIZE_DATA, SCHEMA_ELEMENT_DEFAULT }; addRecognizedFeatures(recognizedFeatures); // set state for default features setFeature(VALIDATION, false); setFeature(NAMESPACES, true); setFeature(EXTERNAL_GENERAL_ENTITIES, true); setFeature(EXTERNAL_PARAMETER_ENTITIES, true); setFeature(WARN_ON_DUPLICATE_ATTDEF, false); setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false); setFeature(WARN_ON_UNDECLARED_ELEMDEF, false); setFeature(ALLOW_JAVA_ENCODINGS, false); setFeature(CONTINUE_AFTER_FATAL_ERROR, false); setFeature(LOAD_EXTERNAL_DTD, true); setFeature(NOTIFY_BUILTIN_REFS, false); setFeature(NOTIFY_CHAR_REFS, false); setFeature(SCHEMA_ELEMENT_DEFAULT, true); setFeature(NORMALIZE_DATA, true); // add default recognized properties final String[] recognizedProperties = { XML_STRING, SYMBOL_TABLE, ERROR_HANDLER, ENTITY_RESOLVER, ERROR_REPORTER, ENTITY_MANAGER, DOCUMENT_SCANNER, DTD_SCANNER, DTD_PROCESSOR, DTD_VALIDATOR, NAMESPACE_BINDER, XMLGRAMMAR_POOL, DATATYPE_VALIDATOR_FACTORY, VALIDATION_MANAGER }; addRecognizedProperties(recognizedProperties); if (symbolTable == null) { symbolTable = new SymbolTable(); } fSymbolTable = symbolTable; setProperty(SYMBOL_TABLE, fSymbolTable); fGrammarPool = grammarPool; if (fGrammarPool != null) { setProperty(XMLGRAMMAR_POOL, fGrammarPool); } fEntityManager = createEntityManager(); setProperty(ENTITY_MANAGER, fEntityManager); addComponent(fEntityManager); fErrorReporter = createErrorReporter(); fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner()); setProperty(ERROR_REPORTER, fErrorReporter); addComponent(fErrorReporter); // create namespace aware scanner fNamespaceScanner = new XMLNSDocumentScannerImpl(); addComponent((XMLComponent)fNamespaceScanner); setProperty(DOCUMENT_SCANNER, fNamespaceScanner); // create namespace + dtd validator fNSDTDValidator = new XMLNSDTDValidator(); setProperty(DTD_VALIDATOR, fNSDTDValidator); addComponent(fNSDTDValidator); fDTDScanner = createDTDScanner(); if (fDTDScanner != null) { setProperty(DTD_SCANNER, fDTDScanner); if (fDTDScanner instanceof XMLComponent) { addComponent((XMLComponent)fDTDScanner); } } fDTDProcessor = createDTDProcessor(); if (fDTDProcessor != null) { setProperty(DTD_PROCESSOR, fDTDProcessor); if (fDTDProcessor instanceof XMLComponent) { addComponent((XMLComponent)fDTDProcessor); } } fDatatypeValidatorFactory = createDatatypeValidatorFactory(); if (fDatatypeValidatorFactory != null) { setProperty(DATATYPE_VALIDATOR_FACTORY, fDatatypeValidatorFactory); } fValidationManager = createValidationManager(); if (fValidationManager != null) { setProperty (VALIDATION_MANAGER, fValidationManager); } // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { XMLMessageFormatter xmft = new XMLMessageFormatter(); fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); } // set locale try { setLocale(Locale.getDefault()); } catch (XNIException e) { // do nothing // REVISIT: What is the right thing to do? -Ac } } // <init>(SymbolTable,XMLGrammarPool) /** Configures the pipeline. */ protected void configurePipeline() { // setup dtd pipeline if (fDTDScanner != null) { if (fDTDProcessor != null) { fDTDScanner.setDTDHandler(fDTDProcessor); fDTDProcessor.setDTDHandler(fDTDHandler); fDTDScanner.setDTDContentModelHandler(fDTDProcessor); fDTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler); } else { fDTDScanner.setDTDHandler(fDTDHandler); fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); } } // setup document pipeline if ( fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) { // If schema validator was not in the pipeline insert it. if (fSchemaValidator == null) { fSchemaValidator = new XMLSchemaValidator(); // add schema component fProperties.put(SCHEMA_VALIDATOR, fSchemaValidator); addComponent(fSchemaValidator); // add schema message formatter if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) { XSMessageFormatter xmft = new XSMessageFormatter(); fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft); } } fProperties.put(DTD_VALIDATOR, fNSDTDValidator); fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner); fScanner = fNamespaceScanner; fNamespaceScanner.setComponents(null, fNSDTDValidator, fSchemaValidator); fNamespaceScanner.setDocumentHandler(fNSDTDValidator); fNSDTDValidator.setDocumentSource(fNamespaceScanner); fNSDTDValidator.setDocumentHandler(fSchemaValidator); fSchemaValidator.setDocumentSource(fNSDTDValidator); fSchemaValidator.setDocumentHandler(fDocumentHandler); fLastComponent = fSchemaValidator; } else { if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { fScanner = fNamespaceScanner; fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner); fNamespaceScanner.setComponents(null, fNSDTDValidator, fDocumentHandler); fNamespaceScanner.setDocumentHandler(fNSDTDValidator); fNSDTDValidator.setDocumentSource(fNamespaceScanner); fNSDTDValidator.setDocumentHandler(fDocumentHandler); fDocumentHandler.setDocumentSource(fNSDTDValidator); fLastComponent = fNSDTDValidator; } else { if (fNonNSScanner == null) { fNonNSScanner = new XMLDocumentScannerImpl(); addComponent((XMLComponent)fNonNSScanner); } fScanner = fNonNSScanner; fProperties.put(DTD_VALIDATOR, fNSDTDValidator); fProperties.put(DOCUMENT_SCANNER, fNonNSScanner); fNonNSScanner.setDocumentHandler(fNSDTDValidator); fNSDTDValidator.setDocumentSource(fNonNSScanner); fNSDTDValidator.setDocumentHandler(fDocumentHandler); fDocumentHandler.setDocumentSource(fNSDTDValidator); fLastComponent = fNSDTDValidator; } } } // configurePipeline() } // class IntegratedParserConfiguration 1.16 +12 -1 xml-xerces/java/src/org/apache/xerces/util/XMLAttributesImpl.java Index: XMLAttributesImpl.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/util/XMLAttributesImpl.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- XMLAttributesImpl.java 4 May 2002 05:30:10 -0000 1.15 +++ XMLAttributesImpl.java 12 Sep 2002 21:56:57 -0000 1.16 @@ -655,6 +655,17 @@ } return fAugmentations[attributeIndex]; } + + /** + * Sets the uri of the attribute at the specified index. + * + * @param attrIndex The attribute index. + * @param uri Namespace uri + */ + public void setURI(int attrIndex, String uri) { + fAttributes[attrIndex].name.uri = uri; + } // getURI(int,QName) + // // Classes //
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]