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