286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * Copyright 2005 The Apache Software Foundation.
286N/A *
286N/A * Licensed under the Apache License, Version 2.0 (the "License");
286N/A * you may not use this file except in compliance with the License.
286N/A * You may obtain a copy of the License at
286N/A *
286N/A * http://www.apache.org/licenses/LICENSE-2.0
286N/A *
286N/A * Unless required by applicable law or agreed to in writing, software
286N/A * distributed under the License is distributed on an "AS IS" BASIS,
286N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286N/A * See the License for the specific language governing permissions and
286N/A * limitations under the License.
286N/A */
286N/A
286N/Apackage com.sun.org.apache.xerces.internal.impl.xs.traversers;
286N/A
286N/Aimport com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOMParser;
286N/Aimport com.sun.org.apache.xerces.internal.util.NamespaceSupport;
286N/Aimport com.sun.org.apache.xerces.internal.util.SAXLocatorWrapper;
286N/Aimport com.sun.org.apache.xerces.internal.util.SymbolTable;
286N/Aimport com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
286N/Aimport com.sun.org.apache.xerces.internal.util.XMLSymbols;
286N/Aimport com.sun.org.apache.xerces.internal.xni.NamespaceContext;
286N/Aimport com.sun.org.apache.xerces.internal.xni.QName;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLString;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XNIException;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
286N/Aimport org.w3c.dom.Document;
286N/Aimport org.xml.sax.Attributes;
286N/Aimport org.xml.sax.ContentHandler;
286N/Aimport org.xml.sax.Locator;
286N/Aimport org.xml.sax.SAXException;
286N/Aimport org.xml.sax.SAXParseException;
286N/Aimport org.xml.sax.helpers.LocatorImpl;
286N/A
286N/A/**
286N/A * <p>SchemaContentHandler converts SAX events into XNI
286N/A * and passes them directly to the SchemaDOMParser.</p>
286N/A *
286N/A * @xerces.internal
286N/A *
286N/A * @author Michael Glavassevich, IBM
286N/A * @author Jack Z. Wang, IBM
286N/A *
286N/A */
286N/Afinal class SchemaContentHandler implements ContentHandler {
286N/A
286N/A /** Symbol table **/
286N/A private SymbolTable fSymbolTable;
286N/A
286N/A /** SchemaDOMParser, events will be delegated to SchemaDOMParser to pass */
286N/A private SchemaDOMParser fSchemaDOMParser;
286N/A
286N/A /** XML Locator wrapper for SAX. **/
286N/A private final SAXLocatorWrapper fSAXLocatorWrapper = new SAXLocatorWrapper();
286N/A
286N/A /** The namespace context of this document: stores namespaces in scope */
286N/A private NamespaceSupport fNamespaceContext = new NamespaceSupport();
286N/A
286N/A /** Indicate if push NamespaceContest is needed */
286N/A private boolean fNeedPushNSContext;
286N/A
286N/A /** Flag used to track whether namespace declarations are reported as attributes. */
286N/A private boolean fNamespacePrefixes = false;
286N/A
286N/A /** Flag used to track whether XML names and Namespace URIs have been internalized. */
286N/A private boolean fStringsInternalized = false;
286N/A
286N/A /** Fields for start element, end element and characters. */
286N/A private final QName fElementQName = new QName();
286N/A private final QName fAttributeQName = new QName();
286N/A private final XMLAttributesImpl fAttributes = new XMLAttributesImpl();
286N/A private final XMLString fTempString = new XMLString();
286N/A
286N/A /**
286N/A * <p>Constructs an SchemaContentHandler.</p>
286N/A */
286N/A public SchemaContentHandler() {}
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
286N/A */
286N/A public Document getDocument() {
286N/A return fSchemaDOMParser.getDocument();
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
286N/A */
286N/A public void setDocumentLocator(Locator locator) {
286N/A fSAXLocatorWrapper.setLocator(locator);
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#startDocument()
286N/A */
286N/A public void startDocument() throws SAXException {
286N/A fNeedPushNSContext = true;
286N/A try {
286N/A fSchemaDOMParser.startDocument(fSAXLocatorWrapper, null, fNamespaceContext, null);
286N/A }
286N/A catch (XMLParseException e) {
286N/A convertToSAXParseException(e);
286N/A }
286N/A catch (XNIException e) {
286N/A convertToSAXException(e);
286N/A }
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#endDocument()
286N/A */
286N/A public void endDocument() throws SAXException {
286N/A fSAXLocatorWrapper.setLocator(null);
286N/A try {
286N/A fSchemaDOMParser.endDocument(null);
286N/A }
286N/A catch (XMLParseException e) {
286N/A convertToSAXParseException(e);
286N/A }
286N/A catch (XNIException e) {
286N/A convertToSAXException(e);
286N/A }
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
286N/A */
286N/A public void startPrefixMapping(String prefix, String uri) throws SAXException {
286N/A if (fNeedPushNSContext) {
286N/A fNeedPushNSContext = false;
286N/A fNamespaceContext.pushContext();
286N/A }
286N/A if (!fStringsInternalized) {
286N/A prefix = (prefix != null) ? fSymbolTable.addSymbol(prefix) : XMLSymbols.EMPTY_STRING;
286N/A uri = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null;
286N/A }
286N/A else {
286N/A if (prefix == null) {
286N/A prefix = XMLSymbols.EMPTY_STRING;
286N/A }
286N/A if (uri != null && uri.length() == 0) {
286N/A uri = null;
286N/A }
286N/A }
286N/A fNamespaceContext.declarePrefix(prefix, uri);
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
286N/A */
286N/A public void endPrefixMapping(String prefix) throws SAXException {
286N/A // do nothing
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
286N/A */
286N/A public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
286N/A if (fNeedPushNSContext) {
286N/A fNamespaceContext.pushContext();
286N/A }
286N/A fNeedPushNSContext = true;
286N/A
286N/A // Fill element QName and XMLAttributes
286N/A fillQName(fElementQName, uri, localName, qName);
286N/A fillXMLAttributes(atts);
286N/A
286N/A // Add namespace declarations if necessary
286N/A if (!fNamespacePrefixes) {
286N/A final int prefixCount = fNamespaceContext.getDeclaredPrefixCount();
286N/A if (prefixCount > 0) {
286N/A addNamespaceDeclarations(prefixCount);
286N/A }
286N/A }
286N/A
286N/A try {
286N/A fSchemaDOMParser.startElement(fElementQName, fAttributes, null);
286N/A }
286N/A catch (XMLParseException e) {
286N/A convertToSAXParseException(e);
286N/A }
286N/A catch (XNIException e) {
286N/A convertToSAXException(e);
286N/A }
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
286N/A */
286N/A public void endElement(String uri, String localName, String qName) throws SAXException {
286N/A fillQName(fElementQName, uri, localName, qName);
286N/A try {
286N/A fSchemaDOMParser.endElement(fElementQName, null);
286N/A }
286N/A catch (XMLParseException e) {
286N/A convertToSAXParseException(e);
286N/A }
286N/A catch (XNIException e) {
286N/A convertToSAXException(e);
286N/A }
286N/A finally {
286N/A fNamespaceContext.popContext();
286N/A }
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#characters(char[], int, int)
286N/A */
286N/A public void characters(char[] ch, int start, int length) throws SAXException {
286N/A try {
286N/A fTempString.setValues(ch, start, length);
286N/A fSchemaDOMParser.characters(fTempString, null);
286N/A }
286N/A catch (XMLParseException e) {
286N/A convertToSAXParseException(e);
286N/A }
286N/A catch (XNIException e) {
286N/A convertToSAXException(e);
286N/A }
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
286N/A */
286N/A public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
286N/A try {
286N/A fTempString.setValues(ch, start, length);
286N/A fSchemaDOMParser.ignorableWhitespace(fTempString, null);
286N/A }
286N/A catch (XMLParseException e) {
286N/A convertToSAXParseException(e);
286N/A }
286N/A catch (XNIException e) {
286N/A convertToSAXException(e);
286N/A }
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
286N/A */
286N/A public void processingInstruction(String target, String data) throws SAXException {
286N/A try {
286N/A fTempString.setValues(data.toCharArray(), 0, data.length());
286N/A fSchemaDOMParser.processingInstruction(target, fTempString, null);
286N/A }
286N/A catch (XMLParseException e) {
286N/A convertToSAXParseException(e);
286N/A }
286N/A catch (XNIException e) {
286N/A convertToSAXException(e);
286N/A }
286N/A }
286N/A
286N/A /*
286N/A * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
286N/A */
286N/A public void skippedEntity(String arg) throws SAXException {
286N/A // do-nothing
286N/A }
286N/A
286N/A /*
286N/A * Other methods
286N/A */
286N/A
286N/A private void fillQName(QName toFill, String uri, String localpart, String rawname) {
286N/A if (!fStringsInternalized) {
286N/A uri = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null;
286N/A localpart = (localpart != null) ? fSymbolTable.addSymbol(localpart) : XMLSymbols.EMPTY_STRING;
286N/A rawname = (rawname != null) ? fSymbolTable.addSymbol(rawname) : XMLSymbols.EMPTY_STRING;
286N/A }
286N/A else {
286N/A if (uri != null && uri.length() == 0) {
286N/A uri = null;
286N/A }
286N/A if (localpart == null) {
286N/A localpart = XMLSymbols.EMPTY_STRING;
286N/A }
286N/A if (rawname == null) {
286N/A rawname = XMLSymbols.EMPTY_STRING;
286N/A }
286N/A }
286N/A String prefix = XMLSymbols.EMPTY_STRING;
286N/A int prefixIdx = rawname.indexOf(':');
286N/A if (prefixIdx != -1) {
286N/A prefix = fSymbolTable.addSymbol(rawname.substring(0, prefixIdx));
286N/A // local part may be an empty string if this is a namespace declaration
286N/A if (localpart == XMLSymbols.EMPTY_STRING) {
286N/A localpart = fSymbolTable.addSymbol(rawname.substring(prefixIdx + 1));
286N/A }
286N/A }
286N/A // local part may be an empty string if this is a namespace declaration
286N/A else if (localpart == XMLSymbols.EMPTY_STRING) {
286N/A localpart = rawname;
286N/A }
286N/A toFill.setValues(prefix, localpart, rawname, uri);
286N/A }
286N/A
286N/A private void fillXMLAttributes(Attributes atts) {
286N/A fAttributes.removeAllAttributes();
286N/A final int attrCount = atts.getLength();
286N/A for (int i = 0; i < attrCount; ++i) {
286N/A fillQName(fAttributeQName, atts.getURI(i), atts.getLocalName(i), atts.getQName(i));
286N/A String type = atts.getType(i);
286N/A fAttributes.addAttributeNS(fAttributeQName, (type != null) ? type : XMLSymbols.fCDATASymbol, atts.getValue(i));
286N/A fAttributes.setSpecified(i, true);
286N/A }
286N/A }
286N/A
286N/A private void addNamespaceDeclarations(final int prefixCount) {
286N/A String prefix = null;
286N/A String localpart = null;
286N/A String rawname = null;
286N/A String nsPrefix = null;
286N/A String nsURI = null;
286N/A for (int i = 0; i < prefixCount; ++i) {
286N/A nsPrefix = fNamespaceContext.getDeclaredPrefixAt(i);
286N/A nsURI = fNamespaceContext.getURI(nsPrefix);
286N/A if (nsPrefix.length() > 0) {
286N/A prefix = XMLSymbols.PREFIX_XMLNS;
286N/A localpart = nsPrefix;
286N/A rawname = fSymbolTable.addSymbol(prefix + ":" + localpart);
286N/A }
286N/A else {
286N/A prefix = XMLSymbols.EMPTY_STRING;
286N/A localpart = XMLSymbols.PREFIX_XMLNS;
286N/A rawname = XMLSymbols.PREFIX_XMLNS;
286N/A }
286N/A fAttributeQName.setValues(prefix, localpart, rawname, NamespaceContext.XMLNS_URI);
286N/A fAttributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, nsURI);
286N/A }
286N/A }
286N/A
286N/A public void reset(SchemaDOMParser schemaDOMParser, SymbolTable symbolTable,
286N/A boolean namespacePrefixes, boolean stringsInternalized) {
286N/A fSchemaDOMParser = schemaDOMParser;
286N/A fSymbolTable = symbolTable;
286N/A fNamespacePrefixes = namespacePrefixes;
286N/A fStringsInternalized = stringsInternalized;
286N/A }
286N/A
286N/A /*
286N/A * Static methods
286N/A */
286N/A
286N/A static void convertToSAXParseException(XMLParseException e) throws SAXException {
286N/A Exception ex = e.getException();
286N/A if (ex == null) {
286N/A // must be a parser exception; mine it for locator info and throw
286N/A // a SAXParseException
286N/A LocatorImpl locatorImpl = new LocatorImpl();
286N/A locatorImpl.setPublicId(e.getPublicId());
286N/A locatorImpl.setSystemId(e.getExpandedSystemId());
286N/A locatorImpl.setLineNumber(e.getLineNumber());
286N/A locatorImpl.setColumnNumber(e.getColumnNumber());
286N/A throw new SAXParseException(e.getMessage(), locatorImpl);
286N/A }
286N/A if (ex instanceof SAXException) {
286N/A // why did we create an XMLParseException?
286N/A throw (SAXException) ex;
286N/A }
286N/A throw new SAXException(ex);
286N/A }
286N/A
286N/A static void convertToSAXException(XNIException e) throws SAXException {
286N/A Exception ex = e.getException();
286N/A if (ex == null) {
286N/A throw new SAXException(e.getMessage());
286N/A }
286N/A if (ex instanceof SAXException) {
286N/A throw (SAXException) ex;
286N/A }
286N/A throw new SAXException(ex);
286N/A }
286N/A
286N/A} // SchemaContentHandler