- /*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999-2003 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 apache@apache.org.
- *
- * 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) 2003, International
- * Business Machines, Inc., http://www.apache.org. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
- package com.sun.org.apache.xerces.internal.impl;
-
- import java.io.EOFException;
- import java.io.IOException;
-
- import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
- import com.sun.org.apache.xerces.internal.util.SymbolTable;
- import com.sun.org.apache.xerces.internal.xni.XMLString;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
- import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
-
- /**
- * This class scans the version of the document to determine
- * which scanner to use: XML 1.1 or XML 1.0.
- * The version is scanned using XML 1.1. scanner.
- *
- * @author Neil Graham, IBM
- * @author Elena Litani, IBM
- * @version $Id: XMLVersionDetector.java,v 1.12 2004/02/27 20:36:07 mrglavas Exp $
- */
-
- public class XMLVersionDetector {
-
- //
- // Constants
- //
-
- private final static char[] XML11_VERSION = new char[]{'1', '.', '1'};
-
-
- // property identifiers
-
- /** Property identifier: symbol table. */
- protected static final String SYMBOL_TABLE =
- Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
-
- /** Property identifier: error reporter. */
- protected static final String ERROR_REPORTER =
- Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
-
- /** Property identifier: entity manager. */
- protected static final String ENTITY_MANAGER =
- Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
-
- //
- // Data
- //
-
- /** Symbol: "version". */
- protected final static String fVersionSymbol = "version".intern();
-
- // symbol: [xml]:
- protected static final String fXMLSymbol = "[xml]".intern();
-
- /** Symbol table. */
- protected SymbolTable fSymbolTable;
-
- /** Error reporter. */
- protected XMLErrorReporter fErrorReporter;
-
- /** Entity manager. */
- protected XMLEntityManager fEntityManager;
-
- protected String fEncoding = null;
-
- private XMLString fVersionNum = new XMLString();
-
- private final char [] fExpectedVersionString = {'<', '?', 'x', 'm', 'l', ' ', 'v', 'e', 'r', 's',
- 'i', 'o', 'n', '=', ' ', ' ', ' ', ' ', ' '};
-
- /**
- *
- *
- * @param componentManager The component manager.
- *
- * @throws SAXException Throws exception if required features and
- * properties cannot be found.
- */
- public void reset(XMLComponentManager componentManager)
- throws XMLConfigurationException {
-
- // Xerces properties
- fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
- fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
- fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
- for(int i=14; i<fExpectedVersionString.length; i++ )
- fExpectedVersionString[i] = ' ';
- } // reset(XMLComponentManager)
-
- /**
- * Reset the reference to the appropriate scanner given the version of the
- * document and start document scanning.
- * @param scanner - the scanner to use
- * @param version - the version of the document (XML 1.1 or XML 1.0).
- */
- public void startDocumentParsing(XMLEntityHandler scanner, short version){
-
- if (version == Constants.XML_VERSION_1_0){
- fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
- }
- else {
- fEntityManager.setScannerVersion(Constants.XML_VERSION_1_1);
- }
- // Make sure the locator used by the error reporter is the current entity scanner.
- fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
-
- // Note: above we reset fEntityScanner in the entity manager, thus in startEntity
- // in each scanner fEntityScanner field must be reset to reflect the change.
- //
- fEntityManager.setEntityHandler(scanner);
-
- scanner.startEntity(fXMLSymbol, fEntityManager.getCurrentResourceIdentifier(), fEncoding, null);
- }
-
-
- /**
- * This methods scans the XML declaration to find out the version
- * (and provisional encoding) of the document.
- * The scanning is doing using XML 1.1 scanner.
- * @param inputSource
- * @return short - Constants.XML_VERSION_1_1 if document version 1.1,
- * otherwise Constants.XML_VERSION_1_0
- * @throws IOException
- */
- public short determineDocVersion(XMLInputSource inputSource) throws IOException {
- fEncoding = fEntityManager.setupCurrentEntity(fXMLSymbol, inputSource, false, true);
-
- // Must use XML 1.0 scanner to handle whitespace correctly
- // in the XML declaration.
- fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
- XMLEntityScanner scanner = fEntityManager.getEntityScanner();
- try {
- if (!scanner.skipString("<?xml")) {
- // definitely not a well-formed 1.1 doc!
- return Constants.XML_VERSION_1_0;
- }
- if (!scanner.skipDeclSpaces()) {
- fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5);
- return Constants.XML_VERSION_1_0;
- }
- if (!scanner.skipString("version")) {
- fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6);
- return Constants.XML_VERSION_1_0;
- }
- scanner.skipDeclSpaces();
- // Check if the next character is '='. If it is then consume it.
- if (scanner.peekChar() != '=') {
- fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13);
- return Constants.XML_VERSION_1_0;
- }
- scanner.scanChar();
- scanner.skipDeclSpaces();
- int quoteChar = scanner.scanChar();
- fExpectedVersionString[14] = (char) quoteChar;
- for (int versionPos = 0; versionPos < XML11_VERSION.length; versionPos++) {
- fExpectedVersionString[15 + versionPos] = (char) scanner.scanChar();
- }
- // REVISIT: should we check whether this equals quoteChar?
- fExpectedVersionString[18] = (char) scanner.scanChar();
- fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19);
- int matched = 0;
- for (; matched < XML11_VERSION.length; matched++) {
- if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched])
- break;
- }
- if (matched == XML11_VERSION.length)
- return Constants.XML_VERSION_1_1;
- return Constants.XML_VERSION_1_0;
- // premature end of file
- }
- catch (EOFException e) {
- fErrorReporter.reportError(
- XMLMessageFormatter.XML_DOMAIN,
- "PrematureEOF",
- null,
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- return Constants.XML_VERSION_1_0;
-
- }
-
- }
-
- // This method prepends "length" chars from the char array,
- // from offset 0, to the manager's fCurrentEntity.ch.
- private void fixupCurrentEntity(XMLEntityManager manager,
- char [] scannedChars, int length) {
- XMLEntityManager.ScannedEntity currentEntity = manager.getCurrentEntity();
- if(currentEntity.count-currentEntity.position+length > currentEntity.ch.length) {
- //resize array; this case is hard to imagine...
- char[] tempCh = currentEntity.ch;
- currentEntity.ch = new char[length+currentEntity.count-currentEntity.position+1];
- System.arraycopy(tempCh, 0, currentEntity.ch, 0, tempCh.length);
- }
- if(currentEntity.position < length) {
- // have to move sensitive stuff out of the way...
- System.arraycopy(currentEntity.ch, currentEntity.position, currentEntity.ch, length, currentEntity.count-currentEntity.position);
- currentEntity.count += length-currentEntity.position;
- } else {
- // have to reintroduce some whitespace so this parses:
- for(int i=length; i<currentEntity.position; i++)
- currentEntity.ch[i]=' ';
- }
- // prepend contents...
- System.arraycopy(scannedChars, 0, currentEntity.ch, 0, length);
- currentEntity.position = 0;
- currentEntity.columnNumber = currentEntity.lineNumber = 1;
- }
-
- } // class XMLVersionDetector
-