1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001-2005 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.parsers; 22 23 import java.io.IOException; 24 25 import com.sun.org.apache.xerces.internal.impl.Constants; 26 import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar; 27 import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader; 28 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar; 29 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader; 30 import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; 31 import com.sun.org.apache.xerces.internal.util.SymbolTable; 32 import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable; 33 import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl; 34 import com.sun.org.apache.xerces.internal.xni.XNIException; 35 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; 36 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; 37 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; 38 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 39 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 40 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; 41 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 42 43 /** 44 * <p> This configuration provides a generic way of using 45 * Xerces's grammar caching facilities. It extends the 46 * XIncludeAwareParserConfiguration and thus may validate documents 47 * according to XML schemas or DTD's. It also allows the user to 48 * preparse a grammar, and to lock the grammar pool 49 * implementation such that no more grammars will be added.</p> 50 * <p> Using the com.sun.org.apache.xerces.internal.xni.parser property, an 51 * application may instantiate a Xerces SAX or DOM parser with 52 * this configuration. When invoked in this manner, the default 53 * behaviour will be elicited; to use this configuration's 54 * specific facilities, the user will need to reference it 55 * directly.</p> 56 * <p> 57 * In addition to the features and properties recognized by the base 58 * parser configuration, this class recognizes these additional 59 * features and properties: 60 * <ul> 61 * </ul> 62 * 63 * @author Neil Graham, IBM 64 * 65 * @version $Id: XMLGrammarCachingConfiguration.java,v 1.6 2010-11-01 04:40:10 joehw Exp $ 66 */ 67 public class XMLGrammarCachingConfiguration 68 extends XIncludeAwareParserConfiguration { 69 70 // 71 // Constants 72 // 73 74 // a larg(ish) prime to use for a symbol table to be shared 75 // among 76 // potentially man parsers. Start one as close to 2K (20 77 // times larger than normal) and see what happens... 78 public static final int BIG_PRIME = 2039; 79 80 // the static symbol table to be shared amongst parsers 81 protected static final SynchronizedSymbolTable fStaticSymbolTable = 82 new SynchronizedSymbolTable(BIG_PRIME); 83 84 // the Grammar Pool to be shared similarly 85 protected static final XMLGrammarPoolImpl fStaticGrammarPool = 86 new XMLGrammarPoolImpl(); 87 88 // schema full checking constant 89 protected static final String SCHEMA_FULL_CHECKING = 90 Constants.XERCES_FEATURE_PREFIX+Constants.SCHEMA_FULL_CHECKING; 91 92 // Data 93 94 // variables needed for caching schema grammars. 95 protected XMLSchemaLoader fSchemaLoader; 96 97 // the DTD grammar loader 98 protected XMLDTDLoader fDTDLoader; 99 100 // 101 // Constructors 102 // 103 104 /** Default constructor. */ 105 public XMLGrammarCachingConfiguration() { 106 this(fStaticSymbolTable, fStaticGrammarPool, null); 107 } // <init>() 108 109 /** 110 * Constructs a parser configuration using the specified symbol table. 111 * 112 * @param symbolTable The symbol table to use. 113 */ 114 public XMLGrammarCachingConfiguration(SymbolTable symbolTable) { 115 this(symbolTable, fStaticGrammarPool, null); 116 } // <init>(SymbolTable) 117 118 /** 119 * Constructs a parser configuration using the specified symbol table and 120 * grammar pool. 121 * <p> 122 * <strong>REVISIT:</strong> 123 * Grammar pool will be updated when the new validation engine is 124 * implemented. 125 * 126 * @param symbolTable The symbol table to use. 127 * @param grammarPool The grammar pool to use. 128 */ 129 public XMLGrammarCachingConfiguration(SymbolTable symbolTable, 130 XMLGrammarPool grammarPool) { 131 this(symbolTable, grammarPool, null); 132 } // <init>(SymbolTable,XMLGrammarPool) 133 134 /** 135 * Constructs a parser configuration using the specified symbol table, 136 * grammar pool, and parent settings. 137 * <p> 138 * <strong>REVISIT:</strong> 139 * Grammar pool will be updated when the new validation engine is 140 * implemented. 141 * 142 * @param symbolTable The symbol table to use. 143 * @param grammarPool The grammar pool to use. 144 * @param parentSettings The parent settings. 145 */ 146 public XMLGrammarCachingConfiguration(SymbolTable symbolTable, 147 XMLGrammarPool grammarPool, 148 XMLComponentManager parentSettings) { 149 super(symbolTable, grammarPool, parentSettings); 150 151 // REVISIT: may need to add some features/properties 152 // specific to this configuration at some point... 153 154 // add default recognized features 155 // set state for default features 156 // add default recognized properties 157 // create and register missing components 158 fSchemaLoader = new XMLSchemaLoader(fSymbolTable); 159 fSchemaLoader.setProperty(XMLGRAMMAR_POOL, fGrammarPool); 160 161 // and set up the DTD loader too: 162 fDTDLoader = new XMLDTDLoader(fSymbolTable, fGrammarPool); 163 } // <init>(SymbolTable,XMLGrammarPool, XMLComponentManager) 164 165 // 166 // Public methods 167 // 168 169 /* 170 * lock the XMLGrammarPoolImpl object so that it does not 171 * accept any more grammars from the validators. 172 */ 173 public void lockGrammarPool() { 174 fGrammarPool.lockPool(); 175 } // lockGrammarPool() 176 177 /* 178 * clear the XMLGrammarPoolImpl object so that it does not 179 * contain any more grammars. 180 */ 181 public void clearGrammarPool() { 182 fGrammarPool.clear(); 183 } // clearGrammarPool() 184 185 /* 186 * unlock the XMLGrammarPoolImpl object so that it 187 * accepts more grammars from the validators. 188 */ 189 public void unlockGrammarPool() { 190 fGrammarPool.unlockPool(); 191 } // unlockGrammarPool() 192 193 /** 194 * Parse a grammar from a location identified by an URI. 195 * This method also adds this grammar to the XMLGrammarPool 196 * 197 * @param type The type of the grammar to be constructed 198 * @param uri The location of the grammar to be constructed. 199 * <strong>The parser will not expand this URI or make it 200 * available to the EntityResolver</strong> 201 * @return The newly created <code>Grammar</code>. 202 * @exception XNIException thrown on an error in grammar 203 * construction 204 * @exception IOException thrown if an error is encountered 205 * in reading the file 206 */ 207 public Grammar parseGrammar(String type, String uri) 208 throws XNIException, IOException { 209 XMLInputSource source = new XMLInputSource(null, uri, null); 210 return parseGrammar(type, source); 211 212 } 213 214 /** 215 * Parse a grammar from a location identified by an 216 * XMLInputSource. 217 * This method also adds this grammar to the XMLGrammarPool 218 * 219 * @param type The type of the grammar to be constructed 220 * @param is The XMLInputSource containing this grammar's 221 * information 222 * <strong>If a URI is included in the systemId field, the parser will not expand this URI or make it 223 * available to the EntityResolver</strong> 224 * @return The newly created <code>Grammar</code>. 225 * @exception XNIException thrown on an error in grammar 226 * construction 227 * @exception IOException thrown if an error is encountered 228 * in reading the file 229 */ 230 public Grammar parseGrammar(String type, XMLInputSource 231 is) throws XNIException, IOException { 232 if(type.equals(XMLGrammarDescription.XML_SCHEMA)) { 233 // by default, make all XMLGrammarPoolImpl's schema grammars available to fSchemaHandler 234 return parseXMLSchema(is); 235 } else if(type.equals(XMLGrammarDescription.XML_DTD)) { 236 return parseDTD(is); 237 } 238 // don't know this grammar... 239 return null; 240 } // parseGrammar(String, XMLInputSource): Grammar 241 242 // 243 // Protected methods 244 // 245 246 // package-protected methods 247 248 /* This method parses an XML Schema document. 249 * It requires a GrammarBucket parameter so that DOMASBuilder can 250 * extract the info it needs. 251 * Therefore, bucket must not be null! 252 */ 253 SchemaGrammar parseXMLSchema(XMLInputSource is) 254 throws IOException { 255 XMLEntityResolver resolver = getEntityResolver(); 256 if(resolver != null) { 257 fSchemaLoader.setEntityResolver(resolver); 258 } 259 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) { 260 fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter()); 261 } 262 fSchemaLoader.setProperty(ERROR_REPORTER, fErrorReporter); 263 264 String propPrefix = Constants.XERCES_PROPERTY_PREFIX; 265 String propName = propPrefix + Constants.SCHEMA_LOCATION; 266 fSchemaLoader.setProperty(propName, getProperty(propName)); 267 propName = propPrefix + Constants.SCHEMA_NONS_LOCATION; 268 fSchemaLoader.setProperty(propName, getProperty(propName)); 269 propName = Constants.JAXP_PROPERTY_PREFIX+Constants.SCHEMA_SOURCE; 270 fSchemaLoader.setProperty(propName, getProperty(propName)); 271 fSchemaLoader.setFeature(SCHEMA_FULL_CHECKING, getFeature(SCHEMA_FULL_CHECKING)); 272 273 // Should check whether the grammar with this namespace is already in 274 // the grammar resolver. But since we don't know the target namespace 275 // of the document here, we leave such check to XSDHandler 276 SchemaGrammar grammar = (SchemaGrammar)fSchemaLoader.loadGrammar(is); 277 // by default, hand it off to the grammar pool 278 if (grammar != null) { 279 fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA, 280 new Grammar[]{grammar}); 281 } 282 283 return grammar; 284 285 } // parseXMLSchema(XMLInputSource) : SchemaGrammar 286 287 /* This method parses an external DTD entity. 288 */ 289 DTDGrammar parseDTD(XMLInputSource is) 290 throws IOException { 291 XMLEntityResolver resolver = getEntityResolver(); 292 if(resolver != null) { 293 fDTDLoader.setEntityResolver(resolver); 294 } 295 fDTDLoader.setProperty(ERROR_REPORTER, fErrorReporter); 296 297 // Should check whether the grammar with this namespace is already in 298 // the grammar resolver. But since we don't know the target namespace 299 // of the document here, we leave such check to the application... 300 DTDGrammar grammar = (DTDGrammar)fDTDLoader.loadGrammar(is); 301 // by default, hand it off to the grammar pool 302 if (grammar != null) { 303 fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_DTD, 304 new Grammar[]{grammar}); 305 } 306 307 return grammar; 308 309 } // parseXMLDTD(XMLInputSource) : DTDGrammar 310 311 312 } // class XMLGrammarCachingConfiguration