You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2005/05/30 05:08:51 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/impl/xs/traversers SchemaContentHandler.java

mrglavas    2005/05/29 20:08:51

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

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xerces.apache.org
For additional commands, e-mail: commits-help@xerces.apache.org