KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > XMLVersionDetector


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl;
18
19 import java.io.EOFException JavaDoc;
20 import java.io.IOException JavaDoc;
21
22 import org.apache.xerces.impl.msg.XMLMessageFormatter;
23 import org.apache.xerces.util.SymbolTable;
24 import org.apache.xerces.xni.XMLString;
25 import org.apache.xerces.xni.parser.XMLComponentManager;
26 import org.apache.xerces.xni.parser.XMLConfigurationException;
27 import org.apache.xerces.xni.parser.XMLInputSource;
28
29 /**
30  * This class scans the version of the document to determine
31  * which scanner to use: XML 1.1 or XML 1.0.
32  * The version is scanned using XML 1.1. scanner.
33  *
34  * @xerces.internal
35  *
36  * @author Neil Graham, IBM
37  * @author Elena Litani, IBM
38  * @version $Id: XMLVersionDetector.java,v 1.14 2004/10/04 21:45:48 mrglavas Exp $
39  */

40 public class XMLVersionDetector {
41
42     //
43
// Constants
44
//
45

46     private final static char[] XML11_VERSION = new char[]{'1', '.', '1'};
47
48
49     // property identifiers
50

51     /** Property identifier: symbol table. */
52     protected static final String JavaDoc SYMBOL_TABLE =
53         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
54
55     /** Property identifier: error reporter. */
56     protected static final String JavaDoc ERROR_REPORTER =
57         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
58
59     /** Property identifier: entity manager. */
60     protected static final String JavaDoc ENTITY_MANAGER =
61         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
62
63     //
64
// Data
65
//
66

67     /** Symbol: "version". */
68     protected final static String JavaDoc fVersionSymbol = "version".intern();
69
70     // symbol: [xml]:
71
protected static final String JavaDoc fXMLSymbol = "[xml]".intern();
72
73     /** Symbol table. */
74     protected SymbolTable fSymbolTable;
75
76     /** Error reporter. */
77     protected XMLErrorReporter fErrorReporter;
78
79     /** Entity manager. */
80     protected XMLEntityManager fEntityManager;
81
82     protected String JavaDoc fEncoding = null;
83
84     private XMLString fVersionNum = new XMLString();
85
86     private final char [] fExpectedVersionString = {'<', '?', 'x', 'm', 'l', ' ', 'v', 'e', 'r', 's',
87                     'i', 'o', 'n', '=', ' ', ' ', ' ', ' ', ' '};
88
89     /**
90      *
91      *
92      * @param componentManager The component manager.
93      *
94      * @throws SAXException Throws exception if required features and
95      * properties cannot be found.
96      */

97     public void reset(XMLComponentManager componentManager)
98         throws XMLConfigurationException {
99
100         // Xerces properties
101
fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
102         fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
103         fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
104         for(int i=14; i<fExpectedVersionString.length; i++ )
105             fExpectedVersionString[i] = ' ';
106     } // reset(XMLComponentManager)
107

108     /**
109      * Reset the reference to the appropriate scanner given the version of the
110      * document and start document scanning.
111      * @param scanner - the scanner to use
112      * @param version - the version of the document (XML 1.1 or XML 1.0).
113      */

114     public void startDocumentParsing(XMLEntityHandler scanner, short version){
115
116         if (version == Constants.XML_VERSION_1_0){
117             fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
118         }
119         else {
120             fEntityManager.setScannerVersion(Constants.XML_VERSION_1_1);
121         }
122         // Make sure the locator used by the error reporter is the current entity scanner.
123
fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
124         
125         // Note: above we reset fEntityScanner in the entity manager, thus in startEntity
126
// in each scanner fEntityScanner field must be reset to reflect the change.
127
//
128
fEntityManager.setEntityHandler(scanner);
129         
130         scanner.startEntity(fXMLSymbol, fEntityManager.getCurrentResourceIdentifier(), fEncoding, null);
131     }
132
133
134     /**
135      * This methods scans the XML declaration to find out the version
136      * (and provisional encoding) of the document.
137      * The scanning is doing using XML 1.1 scanner.
138      * @param inputSource
139      * @return short - Constants.XML_VERSION_1_1 if document version 1.1,
140      * otherwise Constants.XML_VERSION_1_0
141      * @throws IOException
142      */

143     public short determineDocVersion(XMLInputSource inputSource) throws IOException JavaDoc {
144         fEncoding = fEntityManager.setupCurrentEntity(fXMLSymbol, inputSource, false, true);
145
146         // Must use XML 1.0 scanner to handle whitespace correctly
147
// in the XML declaration.
148
fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
149         XMLEntityScanner scanner = fEntityManager.getEntityScanner();
150         try {
151             if (!scanner.skipString("<?xml")) {
152                 // definitely not a well-formed 1.1 doc!
153
return Constants.XML_VERSION_1_0;
154             }
155             if (!scanner.skipDeclSpaces()) {
156                 fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5);
157                 return Constants.XML_VERSION_1_0;
158             }
159             if (!scanner.skipString("version")) {
160                 fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6);
161                 return Constants.XML_VERSION_1_0;
162             }
163             scanner.skipDeclSpaces();
164             // Check if the next character is '='. If it is then consume it.
165
if (scanner.peekChar() != '=') {
166                 fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13);
167                 return Constants.XML_VERSION_1_0;
168             }
169             scanner.scanChar();
170             scanner.skipDeclSpaces();
171             int quoteChar = scanner.scanChar();
172             fExpectedVersionString[14] = (char) quoteChar;
173             for (int versionPos = 0; versionPos < XML11_VERSION.length; versionPos++) {
174                 fExpectedVersionString[15 + versionPos] = (char) scanner.scanChar();
175             }
176             // REVISIT: should we check whether this equals quoteChar?
177
fExpectedVersionString[18] = (char) scanner.scanChar();
178             fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19);
179             int matched = 0;
180             for (; matched < XML11_VERSION.length; matched++) {
181                 if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched])
182                     break;
183             }
184             if (matched == XML11_VERSION.length)
185                 return Constants.XML_VERSION_1_1;
186             return Constants.XML_VERSION_1_0;
187             // premature end of file
188
}
189         catch (EOFException JavaDoc e) {
190             fErrorReporter.reportError(
191                 XMLMessageFormatter.XML_DOMAIN,
192                 "PrematureEOF",
193                 null,
194                 XMLErrorReporter.SEVERITY_FATAL_ERROR);
195             return Constants.XML_VERSION_1_0;
196             
197         }
198
199     }
200
201     // This method prepends "length" chars from the char array,
202
// from offset 0, to the manager's fCurrentEntity.ch.
203
private void fixupCurrentEntity(XMLEntityManager manager,
204                 char [] scannedChars, int length) {
205         XMLEntityManager.ScannedEntity currentEntity = manager.getCurrentEntity();
206         if(currentEntity.count-currentEntity.position+length > currentEntity.ch.length) {
207             //resize array; this case is hard to imagine...
208
char[] tempCh = currentEntity.ch;
209             currentEntity.ch = new char[length+currentEntity.count-currentEntity.position+1];
210             System.arraycopy(tempCh, 0, currentEntity.ch, 0, tempCh.length);
211         }
212         if(currentEntity.position < length) {
213             // have to move sensitive stuff out of the way...
214
System.arraycopy(currentEntity.ch, currentEntity.position, currentEntity.ch, length, currentEntity.count-currentEntity.position);
215             currentEntity.count += length-currentEntity.position;
216         } else {
217             // have to reintroduce some whitespace so this parses:
218
for(int i=length; i<currentEntity.position; i++)
219                 currentEntity.ch[i]=' ';
220         }
221         // prepend contents...
222
System.arraycopy(scannedChars, 0, currentEntity.ch, 0, length);
223         currentEntity.position = 0;
224         currentEntity.baseCharOffset = 0;
225         currentEntity.startPosition = 0;
226         currentEntity.columnNumber = currentEntity.lineNumber = 1;
227     }
228
229 } // class XMLVersionDetector
230

231
Popular Tags