Save This Page
Home » openjdk-7 » com.sun.org.apache.xerces.internal » impl » [javadoc | source]
    1   /*
    2    * reserved comment block
    3    * DO NOT REMOVE OR ALTER!
    4    */
    5   /*
    6    * The Apache Software License, Version 1.1
    7    *
    8    *
    9    * Copyright (c) 1999-2003 The Apache Software Foundation.
   10    * All rights reserved.
   11    *
   12    * Redistribution and use in source and binary forms, with or without
   13    * modification, are permitted provided that the following conditions
   14    * are met:
   15    *
   16    * 1. Redistributions of source code must retain the above copyright
   17    *    notice, this list of conditions and the following disclaimer.
   18    *
   19    * 2. Redistributions in binary form must reproduce the above copyright
   20    *    notice, this list of conditions and the following disclaimer in
   21    *    the documentation and/or other materials provided with the
   22    *    distribution.
   23    *
   24    * 3. The end-user documentation included with the redistribution,
   25    *    if any, must include the following acknowledgment:
   26    *       "This product includes software developed by the
   27    *        Apache Software Foundation (http://www.apache.org/)."
   28    *    Alternately, this acknowledgment may appear in the software itself,
   29    *    if and wherever such third-party acknowledgments normally appear.
   30    *
   31    * 4. The names "Xerces" and "Apache Software Foundation" must
   32    *    not be used to endorse or promote products derived from this
   33    *    software without prior written permission. For written
   34    *    permission, please contact apache@apache.org.
   35    *
   36    * 5. Products derived from this software may not be called "Apache",
   37    *    nor may "Apache" appear in their name, without prior written
   38    *    permission of the Apache Software Foundation.
   39    *
   40    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   41    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   42    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   43    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   44    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   45    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   46    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   47    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   48    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   49    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   50    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   51    * SUCH DAMAGE.
   52    * ====================================================================
   53    *
   54    * This software consists of voluntary contributions made by many
   55    * individuals on behalf of the Apache Software Foundation and was
   56    * originally based on software copyright (c) 2003, International
   57    * Business Machines, Inc., http://www.apache.org.  For more
   58    * information on the Apache Software Foundation, please see
   59    * <http://www.apache.org/>.
   60    */
   61   
   62   package com.sun.org.apache.xerces.internal.impl;
   63   
   64   import java.io.EOFException;
   65   import java.io.IOException;
   66   
   67   import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
   68   import com.sun.org.apache.xerces.internal.util.SymbolTable;
   69   import com.sun.org.apache.xerces.internal.xni.XMLString;
   70   import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
   71   import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
   72   import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
   73   import com.sun.xml.internal.stream.Entity.ScannedEntity;
   74   
   75   /**
   76    * This class scans the version of the document to determine
   77    * which scanner to use: XML 1.1 or XML 1.0.
   78    * The version is scanned using XML 1.1. scanner.
   79    *
   80    * @xerces.internal
   81    *
   82    * @author Neil Graham, IBM
   83    * @author Elena Litani, IBM
   84    */
   85   public class XMLVersionDetector {
   86   
   87       //
   88       // Constants
   89       //
   90   
   91       private final static char[] XML11_VERSION = new char[]{'1', '.', '1'};
   92   
   93   
   94       // property identifiers
   95   
   96       /** Property identifier: symbol table. */
   97       protected static final String SYMBOL_TABLE =
   98           Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
   99   
  100       /** Property identifier: error reporter. */
  101       protected static final String ERROR_REPORTER =
  102           Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
  103   
  104       /** Property identifier: entity manager. */
  105       protected static final String ENTITY_MANAGER =
  106           Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
  107   
  108       //
  109       // Data
  110       //
  111   
  112       /** Symbol: "version". */
  113       protected final static String fVersionSymbol = "version".intern();
  114   
  115       // symbol:  [xml]:
  116       protected static final String fXMLSymbol = "[xml]".intern();
  117   
  118       /** Symbol table. */
  119       protected SymbolTable fSymbolTable;
  120   
  121       /** Error reporter. */
  122       protected XMLErrorReporter fErrorReporter;
  123   
  124       /** Entity manager. */
  125       protected XMLEntityManager fEntityManager;
  126   
  127       protected String fEncoding = null;
  128   
  129       private XMLString fVersionNum = new XMLString();
  130   
  131       private final char [] fExpectedVersionString = {'<', '?', 'x', 'm', 'l', ' ', 'v', 'e', 'r', 's',
  132                       'i', 'o', 'n', '=', ' ', ' ', ' ', ' ', ' '};
  133   
  134       /**
  135        *
  136        *
  137        * @param componentManager The component manager.
  138        *
  139        * @throws SAXException Throws exception if required features and
  140        *                      properties cannot be found.
  141        */
  142       public void reset(XMLComponentManager componentManager)
  143           throws XMLConfigurationException {
  144   
  145           // Xerces properties
  146           fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
  147           fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
  148           fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
  149           for(int i=14; i<fExpectedVersionString.length; i++ )
  150               fExpectedVersionString[i] = ' ';
  151       } // reset(XMLComponentManager)
  152   
  153       /**
  154        * Reset the reference to the appropriate scanner given the version of the
  155        * document and start document scanning.
  156        * @param scanner - the scanner to use
  157        * @param version - the version of the document (XML 1.1 or XML 1.0).
  158        */
  159       public void startDocumentParsing(XMLEntityHandler scanner, short version){
  160   
  161           if (version == Constants.XML_VERSION_1_0){
  162               fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
  163           }
  164           else {
  165               fEntityManager.setScannerVersion(Constants.XML_VERSION_1_1);
  166           }
  167           // Make sure the locator used by the error reporter is the current entity scanner.
  168           fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
  169   
  170           // Note: above we reset fEntityScanner in the entity manager, thus in startEntity
  171           // in each scanner fEntityScanner field must be reset to reflect the change.
  172           //
  173           fEntityManager.setEntityHandler(scanner);
  174   
  175           scanner.startEntity(fXMLSymbol, fEntityManager.getCurrentResourceIdentifier(), fEncoding, null);
  176       }
  177   
  178   
  179       /**
  180        * This methods scans the XML declaration to find out the version
  181        * (and provisional encoding)  of the document.
  182        * The scanning is doing using XML 1.1 scanner.
  183        * @param inputSource
  184        * @return short - Constants.XML_VERSION_1_1 if document version 1.1,
  185        *                  otherwise Constants.XML_VERSION_1_0
  186        * @throws IOException
  187        */
  188       public short determineDocVersion(XMLInputSource inputSource) throws IOException {
  189           fEncoding = fEntityManager.setupCurrentEntity(fXMLSymbol, inputSource, false, true);
  190   
  191           // Must use XML 1.0 scanner to handle whitespace correctly
  192           // in the XML declaration.
  193           fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
  194           XMLEntityScanner scanner = fEntityManager.getEntityScanner();
  195           try {
  196               if (!scanner.skipString("<?xml")) {
  197                   // definitely not a well-formed 1.1 doc!
  198                   return Constants.XML_VERSION_1_0;
  199               }
  200               if (!scanner.skipDeclSpaces()) {
  201                   fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5);
  202                   return Constants.XML_VERSION_1_0;
  203               }
  204               if (!scanner.skipString("version")) {
  205                   fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6);
  206                   return Constants.XML_VERSION_1_0;
  207               }
  208               scanner.skipDeclSpaces();
  209               // Check if the next character is '='. If it is then consume it.
  210               if (scanner.peekChar() != '=') {
  211                   fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13);
  212                   return Constants.XML_VERSION_1_0;
  213               }
  214               scanner.scanChar();
  215               scanner.skipDeclSpaces();
  216               int quoteChar = scanner.scanChar();
  217               fExpectedVersionString[14] = (char) quoteChar;
  218               for (int versionPos = 0; versionPos < XML11_VERSION.length; versionPos++) {
  219                   fExpectedVersionString[15 + versionPos] = (char) scanner.scanChar();
  220               }
  221               // REVISIT:  should we check whether this equals quoteChar?
  222               fExpectedVersionString[18] = (char) scanner.scanChar();
  223               fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19);
  224               int matched = 0;
  225               for (; matched < XML11_VERSION.length; matched++) {
  226                   if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched])
  227                       break;
  228               }
  229               if (matched == XML11_VERSION.length)
  230                   return Constants.XML_VERSION_1_1;
  231               return Constants.XML_VERSION_1_0;
  232               // premature end of file
  233           }
  234           catch (EOFException e) {
  235               fErrorReporter.reportError(
  236                   XMLMessageFormatter.XML_DOMAIN,
  237                   "PrematureEOF",
  238                   null,
  239                   XMLErrorReporter.SEVERITY_FATAL_ERROR);
  240               return Constants.XML_VERSION_1_0;
  241   
  242           }
  243   
  244       }
  245   
  246       // This method prepends "length" chars from the char array,
  247       // from offset 0, to the manager's fCurrentEntity.ch.
  248       private void fixupCurrentEntity(XMLEntityManager manager,
  249                   char [] scannedChars, int length) {
  250           ScannedEntity currentEntity = manager.getCurrentEntity();
  251           if(currentEntity.count-currentEntity.position+length > currentEntity.ch.length) {
  252               //resize array; this case is hard to imagine...
  253               char[] tempCh = currentEntity.ch;
  254               currentEntity.ch = new char[length+currentEntity.count-currentEntity.position+1];
  255               System.arraycopy(tempCh, 0, currentEntity.ch, 0, tempCh.length);
  256           }
  257           if(currentEntity.position < length) {
  258               // have to move sensitive stuff out of the way...
  259               System.arraycopy(currentEntity.ch, currentEntity.position, currentEntity.ch, length, currentEntity.count-currentEntity.position);
  260               currentEntity.count += length-currentEntity.position;
  261           } else {
  262               // have to reintroduce some whitespace so this parses:
  263               for(int i=length; i<currentEntity.position; i++)
  264                   currentEntity.ch[i]=' ';
  265           }
  266           // prepend contents...
  267           System.arraycopy(scannedChars, 0, currentEntity.ch, 0, length);
  268           currentEntity.position = 0;
  269           currentEntity.baseCharOffset = 0;
  270           currentEntity.startPosition = 0;
  271           currentEntity.columnNumber = currentEntity.lineNumber = 1;
  272       }
  273   
  274   } // class XMLVersionDetector

Save This Page
Home » openjdk-7 » com.sun.org.apache.xerces.internal » impl » [javadoc | source]