KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > impl > XMLVersionDetector


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2003 The Apache Software Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2003, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package com.sun.org.apache.xerces.internal.impl;
59
60 import java.io.EOFException JavaDoc;
61 import java.io.IOException JavaDoc;
62
63 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
64 import com.sun.org.apache.xerces.internal.util.SymbolTable;
65 import com.sun.org.apache.xerces.internal.xni.XMLString;
66 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
67 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
68 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
69
70 /**
71  * This class scans the version of the document to determine
72  * which scanner to use: XML 1.1 or XML 1.0.
73  * The version is scanned using XML 1.1. scanner.
74  *
75  * @author Neil Graham, IBM
76  * @author Elena Litani, IBM
77  * @version $Id: XMLVersionDetector.java,v 1.12 2004/02/27 20:36:07 mrglavas Exp $
78  */

79
80 public class XMLVersionDetector {
81
82     //
83
// Constants
84
//
85

86     private final static char[] XML11_VERSION = new char[]{'1', '.', '1'};
87
88
89     // property identifiers
90

91     /** Property identifier: symbol table. */
92     protected static final String JavaDoc SYMBOL_TABLE =
93         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
94
95     /** Property identifier: error reporter. */
96     protected static final String JavaDoc ERROR_REPORTER =
97         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
98
99     /** Property identifier: entity manager. */
100     protected static final String JavaDoc ENTITY_MANAGER =
101         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
102
103     //
104
// Data
105
//
106

107     /** Symbol: "version". */
108     protected final static String JavaDoc fVersionSymbol = "version".intern();
109
110     // symbol: [xml]:
111
protected static final String JavaDoc fXMLSymbol = "[xml]".intern();
112
113     /** Symbol table. */
114     protected SymbolTable fSymbolTable;
115
116     /** Error reporter. */
117     protected XMLErrorReporter fErrorReporter;
118
119     /** Entity manager. */
120     protected XMLEntityManager fEntityManager;
121
122     protected String JavaDoc fEncoding = null;
123
124     private XMLString fVersionNum = new XMLString();
125
126     private final char [] fExpectedVersionString = {'<', '?', 'x', 'm', 'l', ' ', 'v', 'e', 'r', 's',
127                     'i', 'o', 'n', '=', ' ', ' ', ' ', ' ', ' '};
128
129     /**
130      *
131      *
132      * @param componentManager The component manager.
133      *
134      * @throws SAXException Throws exception if required features and
135      * properties cannot be found.
136      */

137     public void reset(XMLComponentManager componentManager)
138         throws XMLConfigurationException {
139
140         // Xerces properties
141
fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
142         fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
143         fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
144         for(int i=14; i<fExpectedVersionString.length; i++ )
145             fExpectedVersionString[i] = ' ';
146     } // reset(XMLComponentManager)
147

148     /**
149      * Reset the reference to the appropriate scanner given the version of the
150      * document and start document scanning.
151      * @param scanner - the scanner to use
152      * @param version - the version of the document (XML 1.1 or XML 1.0).
153      */

154     public void startDocumentParsing(XMLEntityHandler scanner, short version){
155
156         if (version == Constants.XML_VERSION_1_0){
157             fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
158         }
159         else {
160             fEntityManager.setScannerVersion(Constants.XML_VERSION_1_1);
161         }
162         // Make sure the locator used by the error reporter is the current entity scanner.
163
fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
164         
165         // Note: above we reset fEntityScanner in the entity manager, thus in startEntity
166
// in each scanner fEntityScanner field must be reset to reflect the change.
167
//
168
fEntityManager.setEntityHandler(scanner);
169         
170         scanner.startEntity(fXMLSymbol, fEntityManager.getCurrentResourceIdentifier(), fEncoding, null);
171     }
172
173
174     /**
175      * This methods scans the XML declaration to find out the version
176      * (and provisional encoding) of the document.
177      * The scanning is doing using XML 1.1 scanner.
178      * @param inputSource
179      * @return short - Constants.XML_VERSION_1_1 if document version 1.1,
180      * otherwise Constants.XML_VERSION_1_0
181      * @throws IOException
182      */

183     public short determineDocVersion(XMLInputSource inputSource) throws IOException JavaDoc {
184         fEncoding = fEntityManager.setupCurrentEntity(fXMLSymbol, inputSource, false, true);
185
186         // Must use XML 1.0 scanner to handle whitespace correctly
187
// in the XML declaration.
188
fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
189         XMLEntityScanner scanner = fEntityManager.getEntityScanner();
190         try {
191             if (!scanner.skipString("<?xml")) {
192                 // definitely not a well-formed 1.1 doc!
193
return Constants.XML_VERSION_1_0;
194             }
195             if (!scanner.skipDeclSpaces()) {
196                 fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5);
197                 return Constants.XML_VERSION_1_0;
198             }
199             if (!scanner.skipString("version")) {
200                 fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6);
201                 return Constants.XML_VERSION_1_0;
202             }
203             scanner.skipDeclSpaces();
204             // Check if the next character is '='. If it is then consume it.
205
if (scanner.peekChar() != '=') {
206                 fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13);
207                 return Constants.XML_VERSION_1_0;
208             }
209             scanner.scanChar();
210             scanner.skipDeclSpaces();
211             int quoteChar = scanner.scanChar();
212             fExpectedVersionString[14] = (char) quoteChar;
213             for (int versionPos = 0; versionPos < XML11_VERSION.length; versionPos++) {
214                 fExpectedVersionString[15 + versionPos] = (char) scanner.scanChar();
215             }
216             // REVISIT: should we check whether this equals quoteChar?
217
fExpectedVersionString[18] = (char) scanner.scanChar();
218             fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19);
219             int matched = 0;
220             for (; matched < XML11_VERSION.length; matched++) {
221                 if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched])
222                     break;
223             }
224             if (matched == XML11_VERSION.length)
225                 return Constants.XML_VERSION_1_1;
226             return Constants.XML_VERSION_1_0;
227             // premature end of file
228
}
229         catch (EOFException JavaDoc e) {
230             fErrorReporter.reportError(
231                 XMLMessageFormatter.XML_DOMAIN,
232                 "PrematureEOF",
233                 null,
234                 XMLErrorReporter.SEVERITY_FATAL_ERROR);
235             return Constants.XML_VERSION_1_0;
236             
237         }
238
239     }
240
241     // This method prepends "length" chars from the char array,
242
// from offset 0, to the manager's fCurrentEntity.ch.
243
private void fixupCurrentEntity(XMLEntityManager manager,
244                 char [] scannedChars, int length) {
245         XMLEntityManager.ScannedEntity currentEntity = manager.getCurrentEntity();
246         if(currentEntity.count-currentEntity.position+length > currentEntity.ch.length) {
247             //resize array; this case is hard to imagine...
248
char[] tempCh = currentEntity.ch;
249             currentEntity.ch = new char[length+currentEntity.count-currentEntity.position+1];
250             System.arraycopy(tempCh, 0, currentEntity.ch, 0, tempCh.length);
251         }
252         if(currentEntity.position < length) {
253             // have to move sensitive stuff out of the way...
254
System.arraycopy(currentEntity.ch, currentEntity.position, currentEntity.ch, length, currentEntity.count-currentEntity.position);
255             currentEntity.count += length-currentEntity.position;
256         } else {
257             // have to reintroduce some whitespace so this parses:
258
for(int i=length; i<currentEntity.position; i++)
259                 currentEntity.ch[i]=' ';
260         }
261         // prepend contents...
262
System.arraycopy(scannedChars, 0, currentEntity.ch, 0, length);
263         currentEntity.position = 0;
264         currentEntity.columnNumber = currentEntity.lineNumber = 1;
265     }
266
267 } // class XMLVersionDetector
268

269
Popular Tags