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 com.sun.org.apache.xerces.internal.jaxp.validation; 19 20 import java.io.IOException; 21 import java.io.InputStream; 22 import java.io.Reader; 23 24 import javax.xml.XMLConstants; 25 import javax.xml.stream.XMLEventReader; 26 import javax.xml.transform.Source; 27 import javax.xml.transform.dom.DOMSource; 28 import javax.xml.transform.sax.SAXSource; 29 import javax.xml.transform.stax.StAXSource; 30 import javax.xml.transform.stream.StreamSource; 31 import javax.xml.validation.Schema; 32 import javax.xml.validation.SchemaFactory; 33 34 import com.sun.org.apache.xerces.internal.impl.Constants; 35 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader; 36 import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper; 37 import com.sun.org.apache.xerces.internal.util.DOMInputSource; 38 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; 39 import com.sun.org.apache.xerces.internal.util.SAXInputSource; 40 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; 41 import com.sun.org.apache.xerces.internal.util.StAXInputSource; 42 import com.sun.org.apache.xerces.internal.util.Status; 43 import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl; 44 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; 45 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; 46 import com.sun.org.apache.xerces.internal.xni.XNIException; 47 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; 48 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; 49 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; 50 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 51 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 52 import org.w3c.dom.Node; 53 import org.w3c.dom.ls.LSResourceResolver; 54 import org.xml.sax.ErrorHandler; 55 import org.xml.sax.InputSource; 56 import org.xml.sax.SAXException; 57 import org.xml.sax.SAXNotRecognizedException; 58 import org.xml.sax.SAXNotSupportedException; 59 import org.xml.sax.SAXParseException; 60 61 /** 62 * {@link SchemaFactory} for XML Schema. 63 * 64 * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) 65 */ 66 public final class XMLSchemaFactory extends SchemaFactory { 67 68 // feature identifiers 69 70 /** JAXP Source feature prefix. */ 71 private static final String JAXP_SOURCE_FEATURE_PREFIX = "http://javax.xml.transform"; 72 73 /** Feature identifier: schema full checking. */ 74 private static final String SCHEMA_FULL_CHECKING = 75 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING; 76 77 /** Feature identifier: use grammar pool only. */ 78 private static final String USE_GRAMMAR_POOL_ONLY = 79 Constants.XERCES_FEATURE_PREFIX + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE; 80 81 // property identifiers 82 83 /** Property identifier: grammar pool. */ 84 private static final String XMLGRAMMAR_POOL = 85 Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; 86 87 /** Property identifier: XMLSecurityManager. */ 88 private static final String SECURITY_MANAGER = 89 Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; 90 91 /** Property identifier: Security property manager. */ 92 private static final String XML_SECURITY_PROPERTY_MANAGER = 93 Constants.XML_SECURITY_PROPERTY_MANAGER; 94 95 96 // 97 // Data 98 // 99 100 /** The XMLSchemaLoader */ 101 private final XMLSchemaLoader fXMLSchemaLoader = new XMLSchemaLoader(); 102 103 /** User-specified ErrorHandler; can be null. */ 104 private ErrorHandler fErrorHandler; 105 106 /** The LSResrouceResolver */ 107 private LSResourceResolver fLSResourceResolver; 108 109 /** The DOMEntityResolverWrapper */ 110 private final DOMEntityResolverWrapper fDOMEntityResolverWrapper; 111 112 /** The ErrorHandlerWrapper */ 113 private final ErrorHandlerWrapper fErrorHandlerWrapper; 114 115 /** The SecurityManager. */ 116 private XMLSecurityManager fSecurityManager; 117 118 /** The Security property manager. */ 119 private XMLSecurityPropertyManager fSecurityPropertyMgr; 120 121 /** The container for the real grammar pool. */ 122 private final XMLGrammarPoolWrapper fXMLGrammarPoolWrapper; 123 124 /** Whether or not to allow new schemas to be added to the grammar pool */ 125 private boolean fUseGrammarPoolOnly; 126 127 /** 128 * Indicates whether implementation parts should use 129 * service loader (or similar). 130 * Note the default value (false) is the safe option.. 131 */ 132 private final boolean fUseServicesMechanism; 133 134 135 public XMLSchemaFactory() { 136 this(true); 137 } 138 public static XMLSchemaFactory newXMLSchemaFactoryNoServiceLoader() { 139 return new XMLSchemaFactory(false); 140 } 141 private XMLSchemaFactory(boolean useServicesMechanism) { 142 fUseServicesMechanism = useServicesMechanism; 143 fErrorHandlerWrapper = new ErrorHandlerWrapper(DraconianErrorHandler.getInstance()); 144 fDOMEntityResolverWrapper = new DOMEntityResolverWrapper(); 145 fXMLGrammarPoolWrapper = new XMLGrammarPoolWrapper(); 146 fXMLSchemaLoader.setFeature(SCHEMA_FULL_CHECKING, true); 147 fXMLSchemaLoader.setProperty(XMLGRAMMAR_POOL, fXMLGrammarPoolWrapper); 148 fXMLSchemaLoader.setEntityResolver(fDOMEntityResolverWrapper); 149 fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper); 150 fUseGrammarPoolOnly = true; 151 152 // Enable secure processing feature by default 153 fSecurityManager = new XMLSecurityManager(true); 154 fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); 155 156 fSecurityPropertyMgr = new XMLSecurityPropertyManager(); 157 fXMLSchemaLoader.setProperty(XML_SECURITY_PROPERTY_MANAGER, 158 fSecurityPropertyMgr); 159 } 160 161 /** 162 * <p>Is specified schema supported by this <code>SchemaFactory</code>?</p> 163 * 164 * @param schemaLanguage Specifies the schema language which the returned <code>SchemaFactory</code> will understand. 165 * <code>schemaLanguage</code> must specify a <a href="#schemaLanguage">valid</a> schema language. 166 * 167 * @return <code>true</code> if <code>SchemaFactory</code> supports <code>schemaLanguage</code>, else <code>false</code>. 168 * 169 * @throws NullPointerException If <code>schemaLanguage</code> is <code>null</code>. 170 * @throws IllegalArgumentException If <code>schemaLanguage.length() == 0</code> 171 * or <code>schemaLanguage</code> does not specify a <a href="#schemaLanguage">valid</a> schema language. 172 */ 173 public boolean isSchemaLanguageSupported(String schemaLanguage) { 174 if (schemaLanguage == null) { 175 throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 176 "SchemaLanguageNull", null)); 177 } 178 if (schemaLanguage.length() == 0) { 179 throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 180 "SchemaLanguageLengthZero", null)); 181 } 182 // only W3C XML Schema 1.0 is supported 183 return schemaLanguage.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI) || 184 schemaLanguage.equals(Constants.W3C_XML_SCHEMA10_NS_URI); 185 } 186 187 public LSResourceResolver getResourceResolver() { 188 return fLSResourceResolver; 189 } 190 191 public void setResourceResolver(LSResourceResolver resourceResolver) { 192 fLSResourceResolver = resourceResolver; 193 fDOMEntityResolverWrapper.setEntityResolver(resourceResolver); 194 fXMLSchemaLoader.setEntityResolver(fDOMEntityResolverWrapper); 195 } 196 197 public ErrorHandler getErrorHandler() { 198 return fErrorHandler; 199 } 200 201 public void setErrorHandler(ErrorHandler errorHandler) { 202 fErrorHandler = errorHandler; 203 fErrorHandlerWrapper.setErrorHandler(errorHandler != null ? errorHandler : DraconianErrorHandler.getInstance()); 204 fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper); 205 } 206 207 public Schema newSchema( Source[] schemas ) throws SAXException { 208 209 // this will let the loader store parsed Grammars into the pool. 210 XMLGrammarPoolImplExtension pool = new XMLGrammarPoolImplExtension(); 211 fXMLGrammarPoolWrapper.setGrammarPool(pool); 212 213 XMLInputSource[] xmlInputSources = new XMLInputSource[schemas.length]; 214 InputStream inputStream; 215 Reader reader; 216 for (int i = 0; i < schemas.length; ++i) { 217 Source source = schemas[i]; 218 if (source instanceof StreamSource) { 219 StreamSource streamSource = (StreamSource) source; 220 String publicId = streamSource.getPublicId(); 221 String systemId = streamSource.getSystemId(); 222 inputStream = streamSource.getInputStream(); 223 reader = streamSource.getReader(); 224 XMLInputSource xmlInputSource = new XMLInputSource(publicId, systemId, null); 225 xmlInputSource.setByteStream(inputStream); 226 xmlInputSource.setCharacterStream(reader); 227 xmlInputSources[i] = xmlInputSource; 228 } 229 else if (source instanceof SAXSource) { 230 SAXSource saxSource = (SAXSource) source; 231 InputSource inputSource = saxSource.getInputSource(); 232 if (inputSource == null) { 233 throw new SAXException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 234 "SAXSourceNullInputSource", null)); 235 } 236 xmlInputSources[i] = new SAXInputSource(saxSource.getXMLReader(), inputSource); 237 } 238 else if (source instanceof DOMSource) { 239 DOMSource domSource = (DOMSource) source; 240 Node node = domSource.getNode(); 241 String systemID = domSource.getSystemId(); 242 xmlInputSources[i] = new DOMInputSource(node, systemID); 243 } 244 else if (source instanceof StAXSource) { 245 StAXSource staxSource = (StAXSource) source; 246 XMLEventReader eventReader = staxSource.getXMLEventReader(); 247 if (eventReader != null) { 248 xmlInputSources[i] = new StAXInputSource(eventReader); 249 } 250 else { 251 xmlInputSources[i] = new StAXInputSource(staxSource.getXMLStreamReader()); 252 } 253 } 254 else if (source == null) { 255 throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 256 "SchemaSourceArrayMemberNull", null)); 257 } 258 else { 259 throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 260 "SchemaFactorySourceUnrecognized", 261 new Object [] {source.getClass().getName()})); 262 } 263 } 264 265 try { 266 fXMLSchemaLoader.loadGrammar(xmlInputSources); 267 } 268 catch (XNIException e) { 269 // this should have been reported to users already. 270 throw Util.toSAXException(e); 271 } 272 catch (IOException e) { 273 // this hasn't been reported, so do so now. 274 SAXParseException se = new SAXParseException(e.getMessage(),null,e); 275 if (fErrorHandler != null) { 276 fErrorHandler.error(se); 277 } 278 throw se; // and we must throw it. 279 } 280 281 // Clear reference to grammar pool. 282 fXMLGrammarPoolWrapper.setGrammarPool(null); 283 284 // Select Schema implementation based on grammar count. 285 final int grammarCount = pool.getGrammarCount(); 286 AbstractXMLSchema schema = null; 287 if (fUseGrammarPoolOnly) { 288 if (grammarCount > 1) { 289 schema = new XMLSchema(new ReadOnlyGrammarPool(pool)); 290 } 291 else if (grammarCount == 1) { 292 Grammar[] grammars = pool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA); 293 schema = new SimpleXMLSchema(grammars[0]); 294 } 295 else { 296 schema = new EmptyXMLSchema(); 297 } 298 } 299 else { 300 schema = new XMLSchema(new ReadOnlyGrammarPool(pool), false); 301 } 302 propagateFeatures(schema); 303 propagateProperties(schema); 304 return schema; 305 } 306 307 public Schema newSchema() throws SAXException { 308 /* 309 * It would make sense to return an EmptyXMLSchema object here, if 310 * fUseGrammarPoolOnly is set to true. However, because the default 311 * value of this feature is true, doing so would change the default 312 * behaviour of this method. Thus, we return a WeakReferenceXMLSchema 313 * regardless of the value of fUseGrammarPoolOnly. -PM 314 */ 315 316 // Use a Schema that uses the system id as the equality source. 317 AbstractXMLSchema schema = new WeakReferenceXMLSchema(); 318 propagateFeatures(schema); 319 propagateProperties(schema); 320 return schema; 321 } 322 323 public Schema newSchema(XMLGrammarPool pool) throws SAXException { 324 // If the "use-grammar-pool-only" feature is set to true 325 // prevent the application's grammar pool from being mutated 326 // by wrapping it in a ReadOnlyGrammarPool. 327 final AbstractXMLSchema schema = (fUseGrammarPoolOnly) ? 328 new XMLSchema(new ReadOnlyGrammarPool(pool)) : 329 new XMLSchema(pool, false); 330 propagateFeatures(schema); 331 return schema; 332 } 333 334 public boolean getFeature(String name) 335 throws SAXNotRecognizedException, SAXNotSupportedException { 336 if (name == null) { 337 throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 338 "FeatureNameNull", null)); 339 } 340 if (name.startsWith(JAXP_SOURCE_FEATURE_PREFIX)) { 341 // Indicates to the caller that this SchemaFactory supports a specific JAXP Source. 342 if (name.equals(StreamSource.FEATURE) || 343 name.equals(SAXSource.FEATURE) || 344 name.equals(DOMSource.FEATURE) || 345 name.equals(StAXSource.FEATURE)) { 346 return true; 347 } 348 } 349 if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { 350 return (fSecurityManager != null && fSecurityManager.isSecureProcessing()); 351 } 352 else if (name.equals(USE_GRAMMAR_POOL_ONLY)) { 353 return fUseGrammarPoolOnly; 354 } 355 try { 356 return fXMLSchemaLoader.getFeature(name); 357 } 358 catch (XMLConfigurationException e) { 359 String identifier = e.getIdentifier(); 360 if (e.getType() == Status.NOT_RECOGNIZED) { 361 throw new SAXNotRecognizedException( 362 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 363 "feature-not-recognized", new Object [] {identifier})); 364 } 365 else { 366 throw new SAXNotSupportedException( 367 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 368 "feature-not-supported", new Object [] {identifier})); 369 } 370 } 371 } 372 373 public Object getProperty(String name) 374 throws SAXNotRecognizedException, SAXNotSupportedException { 375 if (name == null) { 376 throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 377 "ProperyNameNull", null)); 378 } 379 if (name.equals(SECURITY_MANAGER)) { 380 return fSecurityManager; 381 } 382 else if (name.equals(XMLGRAMMAR_POOL)) { 383 throw new SAXNotSupportedException( 384 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 385 "property-not-supported", new Object [] {name})); 386 } 387 try { 388 return fXMLSchemaLoader.getProperty(name); 389 } 390 catch (XMLConfigurationException e) { 391 String identifier = e.getIdentifier(); 392 if (e.getType() == Status.NOT_RECOGNIZED) { 393 throw new SAXNotRecognizedException( 394 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 395 "property-not-recognized", new Object [] {identifier})); 396 } 397 else { 398 throw new SAXNotSupportedException( 399 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 400 "property-not-supported", new Object [] {identifier})); 401 } 402 } 403 } 404 405 public void setFeature(String name, boolean value) 406 throws SAXNotRecognizedException, SAXNotSupportedException { 407 if (name == null) { 408 throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 409 "FeatureNameNull", null)); 410 } 411 if (name.startsWith(JAXP_SOURCE_FEATURE_PREFIX)) { 412 if (name.equals(StreamSource.FEATURE) || 413 name.equals(SAXSource.FEATURE) || 414 name.equals(DOMSource.FEATURE) || 415 name.equals(StAXSource.FEATURE)) { 416 throw new SAXNotSupportedException( 417 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 418 "feature-read-only", new Object [] {name})); 419 } 420 } 421 if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { 422 if (System.getSecurityManager() != null && (!value)) { 423 throw new SAXNotSupportedException( 424 SAXMessageFormatter.formatMessage(null, 425 "jaxp-secureprocessing-feature", null)); 426 } 427 428 fSecurityManager.setSecureProcessing(value); 429 if (value) { 430 if (Constants.IS_JDK8_OR_ABOVE) { 431 fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, 432 XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); 433 fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, 434 XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); 435 } 436 } 437 438 fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); 439 return; 440 } 441 else if (name.equals(USE_GRAMMAR_POOL_ONLY)) { 442 fUseGrammarPoolOnly = value; 443 return; 444 } 445 else if (name.equals(Constants.ORACLE_FEATURE_SERVICE_MECHANISM)) { 446 //in secure mode, let _useServicesMechanism be determined by the constructor 447 if (System.getSecurityManager() != null) 448 return; 449 } 450 try { 451 fXMLSchemaLoader.setFeature(name, value); 452 } 453 catch (XMLConfigurationException e) { 454 String identifier = e.getIdentifier(); 455 if (e.getType() == Status.NOT_RECOGNIZED) { 456 throw new SAXNotRecognizedException( 457 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 458 "feature-not-recognized", new Object [] {identifier})); 459 } 460 else { 461 throw new SAXNotSupportedException( 462 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 463 "feature-not-supported", new Object [] {identifier})); 464 } 465 } 466 } 467 468 public void setProperty(String name, Object object) 469 throws SAXNotRecognizedException, SAXNotSupportedException { 470 if (name == null) { 471 throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 472 "ProperyNameNull", null)); 473 } 474 if (name.equals(SECURITY_MANAGER)) { 475 fSecurityManager = XMLSecurityManager.convert(object, fSecurityManager); 476 fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); 477 return; 478 } else if (name.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) { 479 if (object == null) { 480 fSecurityPropertyMgr = new XMLSecurityPropertyManager(); 481 } else { 482 fSecurityPropertyMgr = (XMLSecurityPropertyManager)object; 483 } 484 fXMLSchemaLoader.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); 485 return; 486 } 487 else if (name.equals(XMLGRAMMAR_POOL)) { 488 throw new SAXNotSupportedException( 489 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 490 "property-not-supported", new Object [] {name})); 491 } 492 try { 493 //check if the property is managed by security manager 494 if (fSecurityManager == null || 495 !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, object)) { 496 //check if the property is managed by security property manager 497 if (fSecurityPropertyMgr == null || 498 !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, object)) { 499 //fall back to the existing property manager 500 fXMLSchemaLoader.setProperty(name, object); 501 } 502 } 503 } 504 catch (XMLConfigurationException e) { 505 String identifier = e.getIdentifier(); 506 if (e.getType() == Status.NOT_RECOGNIZED) { 507 throw new SAXNotRecognizedException( 508 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 509 "property-not-recognized", new Object [] {identifier})); 510 } 511 else { 512 throw new SAXNotSupportedException( 513 SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), 514 "property-not-supported", new Object [] {identifier})); 515 } 516 } 517 } 518 519 private void propagateFeatures(AbstractXMLSchema schema) { 520 schema.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, 521 (fSecurityManager != null && fSecurityManager.isSecureProcessing())); 522 schema.setFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM, fUseServicesMechanism); 523 String[] features = fXMLSchemaLoader.getRecognizedFeatures(); 524 for (int i = 0; i < features.length; ++i) { 525 boolean state = fXMLSchemaLoader.getFeature(features[i]); 526 schema.setFeature(features[i], state); 527 } 528 } 529 530 private void propagateProperties(AbstractXMLSchema schema) { 531 String[] properties = fXMLSchemaLoader.getRecognizedProperties(); 532 for (int i = 0; i < properties.length; ++i) { 533 Object state = fXMLSchemaLoader.getProperty(properties[i]); 534 schema.setProperty(properties[i], state); 535 } 536 } 537 538 539 /** 540 * Extension of XMLGrammarPoolImpl which exposes the number of 541 * grammars stored in the grammar pool. 542 */ 543 static class XMLGrammarPoolImplExtension extends XMLGrammarPoolImpl { 544 545 /** Constructs a grammar pool with a default number of buckets. */ 546 public XMLGrammarPoolImplExtension() { 547 super(); 548 } 549 550 /** Constructs a grammar pool with a specified number of buckets. */ 551 public XMLGrammarPoolImplExtension(int initialCapacity) { 552 super(initialCapacity); 553 } 554 555 /** Returns the number of grammars contained in this pool. */ 556 int getGrammarCount() { 557 return fGrammarCount; 558 } 559 560 } // XMLSchemaFactory.XMLGrammarPoolImplExtension 561 562 /** 563 * A grammar pool which wraps another. 564 */ 565 static class XMLGrammarPoolWrapper implements XMLGrammarPool { 566 567 private XMLGrammarPool fGrammarPool; 568 569 /* 570 * XMLGrammarPool methods 571 */ 572 573 public Grammar[] retrieveInitialGrammarSet(String grammarType) { 574 return fGrammarPool.retrieveInitialGrammarSet(grammarType); 575 } 576 577 public void cacheGrammars(String grammarType, Grammar[] grammars) { 578 fGrammarPool.cacheGrammars(grammarType, grammars); 579 } 580 581 public Grammar retrieveGrammar(XMLGrammarDescription desc) { 582 return fGrammarPool.retrieveGrammar(desc); 583 } 584 585 public void lockPool() { 586 fGrammarPool.lockPool(); 587 } 588 589 public void unlockPool() { 590 fGrammarPool.unlockPool(); 591 } 592 593 public void clear() { 594 fGrammarPool.clear(); 595 } 596 597 /* 598 * Other methods 599 */ 600 601 void setGrammarPool(XMLGrammarPool grammarPool) { 602 fGrammarPool = grammarPool; 603 } 604 605 XMLGrammarPool getGrammarPool() { 606 return fGrammarPool; 607 } 608 609 } // XMLSchemaFactory.XMLGrammarPoolWrapper 610 611 } // XMLSchemaFactory