~vcs-imports/xena/trunk

« back to all changes in this revision

Viewing changes to ext/src/xerces-2_9_1/src/org/apache/xerces/impl/XMLVersionDetector.java

  • Committer: matthewoliver
  • Date: 2009-12-10 03:18:07 UTC
  • Revision ID: vcs-imports@canonical.com-20091210031807-l086qguzdlljtkl9
Merged Xena Testing into Xena Stable for the Xena 5 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 * contributor license agreements.  See the NOTICE file distributed with
 
4
 * this work for additional information regarding copyright ownership.
 
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
6
 * (the "License"); you may not use this file except in compliance with
 
7
 * the License.  You may obtain a copy of the License at
 
8
 * 
 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
 
10
 * 
 
11
 * Unless required by applicable law or agreed to in writing, software
 
12
 * distributed under the License is distributed on an "AS IS" BASIS,
 
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
14
 * See the License for the specific language governing permissions and
 
15
 * limitations under the License.
 
16
 */
 
17
 
 
18
package org.apache.xerces.impl;
 
19
 
 
20
import java.io.CharConversionException;
 
21
import java.io.EOFException;
 
22
import java.io.IOException;
 
23
 
 
24
import org.apache.xerces.impl.io.MalformedByteSequenceException;
 
25
import org.apache.xerces.impl.msg.XMLMessageFormatter;
 
26
import org.apache.xerces.util.SymbolTable;
 
27
import org.apache.xerces.xni.parser.XMLComponentManager;
 
28
import org.apache.xerces.xni.parser.XMLConfigurationException;
 
29
import org.apache.xerces.xni.parser.XMLInputSource;
 
30
 
 
31
/**
 
32
 * This class scans the version of the document to determine
 
33
 * which scanner to use: XML 1.1 or XML 1.0.
 
34
 * The version is scanned using XML 1.1. scanner.  
 
35
 * 
 
36
 * @xerces.internal
 
37
 * 
 
38
 * @author Neil Graham, IBM 
 
39
 * @author Elena Litani, IBM
 
40
 * @version $Id: XMLVersionDetector.java,v 1.2 2009/12/10 03:18:32 matthewoliver Exp $
 
41
 */
 
42
public class XMLVersionDetector {
 
43
 
 
44
    //
 
45
    // Constants
 
46
    //
 
47
 
 
48
    private static final char[] XML11_VERSION = new char[]{'1', '.', '1'};
 
49
 
 
50
    // property identifiers
 
51
 
 
52
    /** Property identifier: symbol table. */
 
53
    protected static final String SYMBOL_TABLE = 
 
54
        Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
 
55
 
 
56
    /** Property identifier: error reporter. */
 
57
    protected static final String ERROR_REPORTER = 
 
58
        Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
 
59
 
 
60
    /** Property identifier: entity manager. */
 
61
    protected static final String ENTITY_MANAGER = 
 
62
        Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
 
63
 
 
64
    //
 
65
    // Data
 
66
    //
 
67
 
 
68
    /** Symbol: "version". */
 
69
    protected static final String fVersionSymbol = "version".intern();
 
70
 
 
71
    // symbol:  [xml]:
 
72
    protected static final String fXMLSymbol = "[xml]".intern();
 
73
 
 
74
    /** Symbol table. */
 
75
    protected SymbolTable fSymbolTable;
 
76
 
 
77
    /** Error reporter. */
 
78
    protected XMLErrorReporter fErrorReporter;
 
79
 
 
80
    /** Entity manager. */
 
81
    protected XMLEntityManager fEntityManager;
 
82
 
 
83
    protected String fEncoding = null;
 
84
 
 
85
    private final char [] fExpectedVersionString = {'<', '?', 'x', 'm', 'l', ' ', 'v', 'e', 'r', 's', 
 
86
                    'i', 'o', 'n', '=', ' ', ' ', ' ', ' ', ' '};
 
87
 
 
88
    /**
 
89
     * 
 
90
     * 
 
91
     * @param componentManager The component manager.
 
92
     *
 
93
     * @throws XNIException Throws exception if required features and
 
94
     *                      properties cannot be found.
 
95
     */
 
96
    public void reset(XMLComponentManager componentManager)
 
97
        throws XMLConfigurationException {
 
98
 
 
99
        // Xerces properties
 
100
        fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
 
101
        fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
 
102
        fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
 
103
        for(int i=14; i<fExpectedVersionString.length; i++ )
 
104
            fExpectedVersionString[i] = ' ';
 
105
    } // reset(XMLComponentManager)
 
106
 
 
107
    /**
 
108
     * Reset the reference to the appropriate scanner given the version of the
 
109
     * document and start document scanning.
 
110
     * @param scanner - the scanner to use
 
111
     * @param version - the version of the document (XML 1.1 or XML 1.0).
 
112
     */
 
113
    public void startDocumentParsing(XMLEntityHandler scanner, short version){
 
114
 
 
115
        if (version == Constants.XML_VERSION_1_0){
 
116
            fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
 
117
        }
 
118
        else {
 
119
            fEntityManager.setScannerVersion(Constants.XML_VERSION_1_1);
 
120
        }
 
121
        // Make sure the locator used by the error reporter is the current entity scanner.
 
122
        fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
 
123
        
 
124
        // Note: above we reset fEntityScanner in the entity manager, thus in startEntity
 
125
        // in each scanner fEntityScanner field must be reset to reflect the change.
 
126
        // 
 
127
        fEntityManager.setEntityHandler(scanner);
 
128
        
 
129
        scanner.startEntity(fXMLSymbol, fEntityManager.getCurrentResourceIdentifier(), fEncoding, null);        
 
130
    }
 
131
 
 
132
 
 
133
    /**
 
134
     * This methods scans the XML declaration to find out the version 
 
135
     * (and provisional encoding)  of the document.
 
136
     * The scanning is doing using XML 1.1 scanner.
 
137
     * @param inputSource
 
138
     * @return short - Constants.XML_VERSION_1_1 if document version 1.1, 
 
139
     *                  otherwise Constants.XML_VERSION_1_0 
 
140
     * @throws IOException
 
141
     */
 
142
    public short determineDocVersion(XMLInputSource inputSource) throws IOException {
 
143
        fEncoding = fEntityManager.setupCurrentEntity(fXMLSymbol, inputSource, false, true);
 
144
 
 
145
        // Must use XML 1.0 scanner to handle whitespace correctly
 
146
        // in the XML declaration.
 
147
        fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
 
148
        XMLEntityScanner scanner = fEntityManager.getEntityScanner();
 
149
        try {
 
150
            if (!scanner.skipString("<?xml")) {
 
151
                // definitely not a well-formed 1.1 doc!
 
152
                return Constants.XML_VERSION_1_0;
 
153
            }
 
154
            if (!scanner.skipDeclSpaces()) {
 
155
                fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5);
 
156
                return Constants.XML_VERSION_1_0;
 
157
            }
 
158
            if (!scanner.skipString("version")) {
 
159
                fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6);
 
160
                return Constants.XML_VERSION_1_0;
 
161
            }
 
162
            scanner.skipDeclSpaces();
 
163
            // Check if the next character is '='. If it is then consume it.
 
164
            if (scanner.peekChar() != '=') {
 
165
                fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13);
 
166
                return Constants.XML_VERSION_1_0;
 
167
            }
 
168
            scanner.scanChar();
 
169
            scanner.skipDeclSpaces();
 
170
            int quoteChar = scanner.scanChar();
 
171
            fExpectedVersionString[14] = (char) quoteChar;
 
172
            for (int versionPos = 0; versionPos < XML11_VERSION.length; versionPos++) {
 
173
                fExpectedVersionString[15 + versionPos] = (char) scanner.scanChar();
 
174
            }
 
175
            // REVISIT:  should we check whether this equals quoteChar? 
 
176
            fExpectedVersionString[18] = (char) scanner.scanChar();
 
177
            fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19);
 
178
            int matched = 0;
 
179
            for (; matched < XML11_VERSION.length; matched++) {
 
180
                if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched])
 
181
                    break;
 
182
            }
 
183
            return (matched == XML11_VERSION.length) ? 
 
184
                    Constants.XML_VERSION_1_1 :
 
185
                    Constants.XML_VERSION_1_0;
 
186
        }
 
187
        // encoding errors
 
188
        catch (MalformedByteSequenceException e) {
 
189
            fErrorReporter.reportError(e.getDomain(), e.getKey(), 
 
190
                e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
 
191
            return Constants.XML_VERSION_ERROR;
 
192
        }
 
193
        catch (CharConversionException e) {
 
194
            fErrorReporter.reportError(
 
195
                    XMLMessageFormatter.XML_DOMAIN,
 
196
                    "CharConversionFailure",
 
197
                    null,
 
198
                    XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
 
199
            return Constants.XML_VERSION_ERROR;
 
200
        }
 
201
        // premature end of file
 
202
        catch (EOFException e) {
 
203
            fErrorReporter.reportError(
 
204
                XMLMessageFormatter.XML_DOMAIN,
 
205
                "PrematureEOF",
 
206
                null,
 
207
                XMLErrorReporter.SEVERITY_FATAL_ERROR);
 
208
            return Constants.XML_VERSION_ERROR;
 
209
        }
 
210
    }
 
211
 
 
212
    // This method prepends "length" chars from the char array,
 
213
    // from offset 0, to the manager's fCurrentEntity.ch.
 
214
    private void fixupCurrentEntity(XMLEntityManager manager, 
 
215
                char [] scannedChars, int length) {
 
216
        XMLEntityManager.ScannedEntity currentEntity = manager.getCurrentEntity();
 
217
        if(currentEntity.count-currentEntity.position+length > currentEntity.ch.length) {
 
218
            //resize array; this case is hard to imagine...
 
219
            char[] tempCh = currentEntity.ch;
 
220
            currentEntity.ch = new char[length+currentEntity.count-currentEntity.position+1];
 
221
            System.arraycopy(tempCh, 0, currentEntity.ch, 0, tempCh.length);
 
222
        }
 
223
        if(currentEntity.position < length) {
 
224
            // have to move sensitive stuff out of the way...
 
225
            System.arraycopy(currentEntity.ch, currentEntity.position, currentEntity.ch, length, currentEntity.count-currentEntity.position);
 
226
            currentEntity.count += length-currentEntity.position;
 
227
        } else {
 
228
            // have to reintroduce some whitespace so this parses:
 
229
            for(int i=length; i<currentEntity.position; i++) 
 
230
                currentEntity.ch[i]=' ';
 
231
        }
 
232
        // prepend contents...
 
233
        System.arraycopy(scannedChars, 0, currentEntity.ch, 0, length);
 
234
        currentEntity.position = 0;
 
235
        currentEntity.baseCharOffset = 0;
 
236
        currentEntity.startPosition = 0;
 
237
        currentEntity.columnNumber = currentEntity.lineNumber = 1;
 
238
    }
 
239
 
 
240
} // class XMLVersionDetector
 
241