src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java

Print this page




  28 import javax.xml.stream.XMLEventReader;
  29 import javax.xml.transform.Source;
  30 import javax.xml.transform.dom.DOMSource;
  31 import javax.xml.transform.sax.SAXSource;
  32 import javax.xml.transform.stax.StAXSource;
  33 import javax.xml.transform.stream.StreamSource;
  34 import javax.xml.validation.Schema;
  35 import javax.xml.validation.SchemaFactory;
  36 
  37 import com.sun.org.apache.xerces.internal.impl.Constants;
  38 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader;
  39 import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper;
  40 import com.sun.org.apache.xerces.internal.util.DOMInputSource;
  41 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
  42 import com.sun.org.apache.xerces.internal.util.SAXInputSource;
  43 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  44 import com.sun.org.apache.xerces.internal.util.SecurityManager;
  45 import com.sun.org.apache.xerces.internal.util.StAXInputSource;
  46 import com.sun.org.apache.xerces.internal.util.Status;
  47 import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;

  48 import com.sun.org.apache.xerces.internal.xni.XNIException;
  49 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
  50 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  51 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  52 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  53 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  54 import org.w3c.dom.Node;
  55 import org.w3c.dom.ls.LSResourceResolver;
  56 import org.xml.sax.ErrorHandler;
  57 import org.xml.sax.InputSource;
  58 import org.xml.sax.SAXException;
  59 import org.xml.sax.SAXNotRecognizedException;
  60 import org.xml.sax.SAXNotSupportedException;
  61 import org.xml.sax.SAXParseException;
  62 
  63 /**
  64  * {@link SchemaFactory} for XML Schema.
  65  *
  66  * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
  67  * @version $Id: XMLSchemaFactory.java,v 1.11 2010-11-01 04:40:08 joehw Exp $
  68  */
  69 public final class XMLSchemaFactory extends SchemaFactory {
  70 
  71     // property identifiers
  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     /** Property identifier: grammar pool. */
  78     private static final String XMLGRAMMAR_POOL =
  79         Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
  80 
  81     /** Property identifier: SecurityManager. */
  82     private static final String SECURITY_MANAGER =
  83         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
  84 






  85     //
  86     // Data
  87     //
  88 
  89     /** The XMLSchemaLoader */
  90     private final XMLSchemaLoader fXMLSchemaLoader = new XMLSchemaLoader();
  91 
  92     /** User-specified ErrorHandler; can be null. */
  93     private ErrorHandler fErrorHandler;
  94 
  95     /** The LSResrouceResolver */
  96     private LSResourceResolver fLSResourceResolver;
  97 
  98     /** The DOMEntityResolverWrapper */
  99     private final DOMEntityResolverWrapper fDOMEntityResolverWrapper;
 100 
 101     /** The ErrorHandlerWrapper */
 102     private ErrorHandlerWrapper fErrorHandlerWrapper;
 103 
 104     /** The SecurityManager. */


 115     private final boolean fUseServicesMechanism;
 116     public XMLSchemaFactory() {
 117         this(true);
 118     }
 119     public static XMLSchemaFactory newXMLSchemaFactoryNoServiceLoader() {
 120         return new XMLSchemaFactory(false);
 121     }
 122     private XMLSchemaFactory(boolean useServicesMechanism) {
 123         fUseServicesMechanism = useServicesMechanism;
 124         fErrorHandlerWrapper = new ErrorHandlerWrapper(DraconianErrorHandler.getInstance());
 125         fDOMEntityResolverWrapper = new DOMEntityResolverWrapper();
 126         fXMLGrammarPoolWrapper = new XMLGrammarPoolWrapper();
 127         fXMLSchemaLoader.setFeature(SCHEMA_FULL_CHECKING, true);
 128         fXMLSchemaLoader.setProperty(XMLGRAMMAR_POOL, fXMLGrammarPoolWrapper);
 129         fXMLSchemaLoader.setEntityResolver(fDOMEntityResolverWrapper);
 130         fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper);
 131 
 132         // Enable secure processing feature by default
 133         fSecurityManager = new SecurityManager();
 134         fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);








 135     }
 136 
 137     /**
 138      * <p>Is specified schema supported by this <code>SchemaFactory</code>?</p>
 139      *
 140      * @param schemaLanguage Specifies the schema language which the returned <code>SchemaFactory</code> will understand.
 141      *    <code>schemaLanguage</code> must specify a <a href="#schemaLanguage">valid</a> schema language.
 142      *
 143      * @return <code>true</code> if <code>SchemaFactory</code> supports <code>schemaLanguage</code>, else <code>false</code>.
 144      *
 145      * @throws NullPointerException If <code>schemaLanguage</code> is <code>null</code>.
 146      * @throws IllegalArgumentException If <code>schemaLanguage.length() == 0</code>
 147      *   or <code>schemaLanguage</code> does not specify a <a href="#schemaLanguage">valid</a> schema language.
 148      */
 149     public boolean isSchemaLanguageSupported(String schemaLanguage) {
 150         if (schemaLanguage == null) {
 151             throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 152                     "SchemaLanguageNull", null));
 153         }
 154         if (schemaLanguage.length() == 0) {


 257         final int grammarCount = pool.getGrammarCount();
 258         AbstractXMLSchema schema = null;
 259         if (grammarCount > 1) {
 260             schema = new XMLSchema(new ReadOnlyGrammarPool(pool));
 261         }
 262         else if (grammarCount == 1) {
 263             Grammar[] grammars = pool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA);
 264             schema = new SimpleXMLSchema(grammars[0]);
 265         }
 266         else {
 267             schema = new EmptyXMLSchema();
 268         }
 269         propagateFeatures(schema);
 270         return schema;
 271     }
 272 
 273     public Schema newSchema() throws SAXException {
 274         // Use a Schema that uses the system id as the equality source.
 275         AbstractXMLSchema schema = new WeakReferenceXMLSchema();
 276         propagateFeatures(schema);

 277         return schema;
 278     }
 279 
 280     public boolean getFeature(String name)
 281         throws SAXNotRecognizedException, SAXNotSupportedException {
 282         if (name == null) {
 283             throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 284                     "FeatureNameNull", null));
 285         }
 286         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 287             return (fSecurityManager != null);
 288         }
 289         try {
 290             return fXMLSchemaLoader.getFeature(name);
 291         }
 292         catch (XMLConfigurationException e) {
 293             String identifier = e.getIdentifier();
 294             if (e.getType() == Status.NOT_RECOGNIZED) {
 295                 throw new SAXNotRecognizedException(
 296                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),


 333                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 334                         "property-not-supported", new Object [] {identifier}));
 335             }
 336         }
 337     }
 338 
 339     public void setFeature(String name, boolean value)
 340         throws SAXNotRecognizedException, SAXNotSupportedException {
 341         if (name == null) {
 342             throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 343                     "FeatureNameNull", null));
 344         }
 345         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 346             if (System.getSecurityManager() != null && (!value)) {
 347                 throw new SAXNotSupportedException(
 348                         SAXMessageFormatter.formatMessage(null,
 349                         "jaxp-secureprocessing-feature", null));
 350             }
 351             fSecurityManager = value ? new SecurityManager() : null;
 352             fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);


 353             return;
 354         } else if (name.equals(Constants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
 355             //in secure mode, let _useServicesMechanism be determined by the constructor
 356             if (System.getSecurityManager() != null)
 357                 return;
 358         }
 359         try {
 360             fXMLSchemaLoader.setFeature(name, value);
 361         }
 362         catch (XMLConfigurationException e) {
 363             String identifier = e.getIdentifier();
 364             if (e.getType() == Status.NOT_RECOGNIZED) {
 365                 throw new SAXNotRecognizedException(
 366                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 367                         "feature-not-recognized", new Object [] {identifier}));
 368             }
 369             else {
 370                 throw new SAXNotSupportedException(
 371                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 372                         "feature-not-supported", new Object [] {identifier}));


 401                         "property-not-recognized", new Object [] {identifier}));
 402             }
 403             else {
 404                 throw new SAXNotSupportedException(
 405                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 406                         "property-not-supported", new Object [] {identifier}));
 407             }
 408         }
 409     }
 410 
 411     private void propagateFeatures(AbstractXMLSchema schema) {
 412         schema.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, fSecurityManager != null);
 413         schema.setFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM, fUseServicesMechanism);
 414         String[] features = fXMLSchemaLoader.getRecognizedFeatures();
 415         for (int i = 0; i < features.length; ++i) {
 416             boolean state = fXMLSchemaLoader.getFeature(features[i]);
 417             schema.setFeature(features[i], state);
 418         }
 419     }
 420 









 421     /**
 422      * Extension of XMLGrammarPoolImpl which exposes the number of
 423      * grammars stored in the grammar pool.
 424      */
 425     static class XMLGrammarPoolImplExtension extends XMLGrammarPoolImpl {
 426 
 427         /** Constructs a grammar pool with a default number of buckets. */
 428         public XMLGrammarPoolImplExtension() {
 429             super();
 430         }
 431 
 432         /** Constructs a grammar pool with a specified number of buckets. */
 433         public XMLGrammarPoolImplExtension(int initialCapacity) {
 434             super(initialCapacity);
 435         }
 436 
 437         /** Returns the number of grammars contained in this pool. */
 438         int getGrammarCount() {
 439             return fGrammarCount;
 440         }




  28 import javax.xml.stream.XMLEventReader;
  29 import javax.xml.transform.Source;
  30 import javax.xml.transform.dom.DOMSource;
  31 import javax.xml.transform.sax.SAXSource;
  32 import javax.xml.transform.stax.StAXSource;
  33 import javax.xml.transform.stream.StreamSource;
  34 import javax.xml.validation.Schema;
  35 import javax.xml.validation.SchemaFactory;
  36 
  37 import com.sun.org.apache.xerces.internal.impl.Constants;
  38 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader;
  39 import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper;
  40 import com.sun.org.apache.xerces.internal.util.DOMInputSource;
  41 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
  42 import com.sun.org.apache.xerces.internal.util.SAXInputSource;
  43 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  44 import com.sun.org.apache.xerces.internal.util.SecurityManager;
  45 import com.sun.org.apache.xerces.internal.util.StAXInputSource;
  46 import com.sun.org.apache.xerces.internal.util.Status;
  47 import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
  48 import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
  49 import com.sun.org.apache.xerces.internal.xni.XNIException;
  50 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
  51 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  52 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  53 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  54 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  55 import org.w3c.dom.Node;
  56 import org.w3c.dom.ls.LSResourceResolver;
  57 import org.xml.sax.ErrorHandler;
  58 import org.xml.sax.InputSource;
  59 import org.xml.sax.SAXException;
  60 import org.xml.sax.SAXNotRecognizedException;
  61 import org.xml.sax.SAXNotSupportedException;
  62 import org.xml.sax.SAXParseException;
  63 
  64 /**
  65  * {@link SchemaFactory} for XML Schema.
  66  *
  67  * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
  68  * @version $Id: XMLSchemaFactory.java,v 1.11 2010-11-01 04:40:08 joehw Exp $
  69  */
  70 public final class XMLSchemaFactory extends SchemaFactory {
  71 
  72     // property identifiers
  73 
  74     /** Feature identifier: schema full checking. */
  75     private static final String SCHEMA_FULL_CHECKING =
  76         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING;
  77 
  78     /** Property identifier: grammar pool. */
  79     private static final String XMLGRAMMAR_POOL =
  80         Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
  81 
  82     /** Property identifier: SecurityManager. */
  83     private static final String SECURITY_MANAGER =
  84         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
  85 
  86     /** property identifier: access external dtd. */
  87     public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
  88 
  89     /** Property identifier: access to external schema  */
  90     public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
  91 
  92     //
  93     // Data
  94     //
  95 
  96     /** The XMLSchemaLoader */
  97     private final XMLSchemaLoader fXMLSchemaLoader = new XMLSchemaLoader();
  98 
  99     /** User-specified ErrorHandler; can be null. */
 100     private ErrorHandler fErrorHandler;
 101 
 102     /** The LSResrouceResolver */
 103     private LSResourceResolver fLSResourceResolver;
 104 
 105     /** The DOMEntityResolverWrapper */
 106     private final DOMEntityResolverWrapper fDOMEntityResolverWrapper;
 107 
 108     /** The ErrorHandlerWrapper */
 109     private ErrorHandlerWrapper fErrorHandlerWrapper;
 110 
 111     /** The SecurityManager. */


 122     private final boolean fUseServicesMechanism;
 123     public XMLSchemaFactory() {
 124         this(true);
 125     }
 126     public static XMLSchemaFactory newXMLSchemaFactoryNoServiceLoader() {
 127         return new XMLSchemaFactory(false);
 128     }
 129     private XMLSchemaFactory(boolean useServicesMechanism) {
 130         fUseServicesMechanism = useServicesMechanism;
 131         fErrorHandlerWrapper = new ErrorHandlerWrapper(DraconianErrorHandler.getInstance());
 132         fDOMEntityResolverWrapper = new DOMEntityResolverWrapper();
 133         fXMLGrammarPoolWrapper = new XMLGrammarPoolWrapper();
 134         fXMLSchemaLoader.setFeature(SCHEMA_FULL_CHECKING, true);
 135         fXMLSchemaLoader.setProperty(XMLGRAMMAR_POOL, fXMLGrammarPoolWrapper);
 136         fXMLSchemaLoader.setEntityResolver(fDOMEntityResolverWrapper);
 137         fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper);
 138 
 139         // Enable secure processing feature by default
 140         fSecurityManager = new SecurityManager();
 141         fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);
 142 
 143         //by default, the secure feature is set to true, otherwise the default would have been 'file'
 144         String accessExternal = SecuritySupport.getDefaultAccessProperty(
 145                 Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT);
 146         fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, accessExternal);
 147         accessExternal = SecuritySupport.getDefaultAccessProperty(
 148                 Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT);
 149         fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal);   
 150     }
 151 
 152     /**
 153      * <p>Is specified schema supported by this <code>SchemaFactory</code>?</p>
 154      *
 155      * @param schemaLanguage Specifies the schema language which the returned <code>SchemaFactory</code> will understand.
 156      *    <code>schemaLanguage</code> must specify a <a href="#schemaLanguage">valid</a> schema language.
 157      *
 158      * @return <code>true</code> if <code>SchemaFactory</code> supports <code>schemaLanguage</code>, else <code>false</code>.
 159      *
 160      * @throws NullPointerException If <code>schemaLanguage</code> is <code>null</code>.
 161      * @throws IllegalArgumentException If <code>schemaLanguage.length() == 0</code>
 162      *   or <code>schemaLanguage</code> does not specify a <a href="#schemaLanguage">valid</a> schema language.
 163      */
 164     public boolean isSchemaLanguageSupported(String schemaLanguage) {
 165         if (schemaLanguage == null) {
 166             throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 167                     "SchemaLanguageNull", null));
 168         }
 169         if (schemaLanguage.length() == 0) {


 272         final int grammarCount = pool.getGrammarCount();
 273         AbstractXMLSchema schema = null;
 274         if (grammarCount > 1) {
 275             schema = new XMLSchema(new ReadOnlyGrammarPool(pool));
 276         }
 277         else if (grammarCount == 1) {
 278             Grammar[] grammars = pool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA);
 279             schema = new SimpleXMLSchema(grammars[0]);
 280         }
 281         else {
 282             schema = new EmptyXMLSchema();
 283         }
 284         propagateFeatures(schema);
 285         return schema;
 286     }
 287 
 288     public Schema newSchema() throws SAXException {
 289         // Use a Schema that uses the system id as the equality source.
 290         AbstractXMLSchema schema = new WeakReferenceXMLSchema();
 291         propagateFeatures(schema);
 292         propagateProperties(schema);
 293         return schema;
 294     }
 295 
 296     public boolean getFeature(String name)
 297         throws SAXNotRecognizedException, SAXNotSupportedException {
 298         if (name == null) {
 299             throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 300                     "FeatureNameNull", null));
 301         }
 302         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 303             return (fSecurityManager != null);
 304         }
 305         try {
 306             return fXMLSchemaLoader.getFeature(name);
 307         }
 308         catch (XMLConfigurationException e) {
 309             String identifier = e.getIdentifier();
 310             if (e.getType() == Status.NOT_RECOGNIZED) {
 311                 throw new SAXNotRecognizedException(
 312                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),


 349                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 350                         "property-not-supported", new Object [] {identifier}));
 351             }
 352         }
 353     }
 354 
 355     public void setFeature(String name, boolean value)
 356         throws SAXNotRecognizedException, SAXNotSupportedException {
 357         if (name == null) {
 358             throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 359                     "FeatureNameNull", null));
 360         }
 361         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 362             if (System.getSecurityManager() != null && (!value)) {
 363                 throw new SAXNotSupportedException(
 364                         SAXMessageFormatter.formatMessage(null,
 365                         "jaxp-secureprocessing-feature", null));
 366             }
 367             fSecurityManager = value ? new SecurityManager() : null;
 368             fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);
 369             fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
 370             fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
 371             return;
 372         } else if (name.equals(Constants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
 373             //in secure mode, let _useServicesMechanism be determined by the constructor
 374             if (System.getSecurityManager() != null)
 375                 return;
 376         }
 377         try {
 378             fXMLSchemaLoader.setFeature(name, value);
 379         }
 380         catch (XMLConfigurationException e) {
 381             String identifier = e.getIdentifier();
 382             if (e.getType() == Status.NOT_RECOGNIZED) {
 383                 throw new SAXNotRecognizedException(
 384                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 385                         "feature-not-recognized", new Object [] {identifier}));
 386             }
 387             else {
 388                 throw new SAXNotSupportedException(
 389                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 390                         "feature-not-supported", new Object [] {identifier}));


 419                         "property-not-recognized", new Object [] {identifier}));
 420             }
 421             else {
 422                 throw new SAXNotSupportedException(
 423                         SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(),
 424                         "property-not-supported", new Object [] {identifier}));
 425             }
 426         }
 427     }
 428 
 429     private void propagateFeatures(AbstractXMLSchema schema) {
 430         schema.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, fSecurityManager != null);
 431         schema.setFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM, fUseServicesMechanism);
 432         String[] features = fXMLSchemaLoader.getRecognizedFeatures();
 433         for (int i = 0; i < features.length; ++i) {
 434             boolean state = fXMLSchemaLoader.getFeature(features[i]);
 435             schema.setFeature(features[i], state);
 436         }
 437     }
 438 
 439     private void propagateProperties(AbstractXMLSchema schema) {
 440         String[] properties = fXMLSchemaLoader.getRecognizedProperties();
 441         for (int i = 0; i < properties.length; ++i) {
 442             Object state = fXMLSchemaLoader.getProperty(properties[i]);
 443             schema.setProperty(properties[i], state);
 444         }
 445     }
 446 
 447 
 448     /**
 449      * Extension of XMLGrammarPoolImpl which exposes the number of
 450      * grammars stored in the grammar pool.
 451      */
 452     static class XMLGrammarPoolImplExtension extends XMLGrammarPoolImpl {
 453 
 454         /** Constructs a grammar pool with a default number of buckets. */
 455         public XMLGrammarPoolImplExtension() {
 456             super();
 457         }
 458 
 459         /** Constructs a grammar pool with a specified number of buckets. */
 460         public XMLGrammarPoolImplExtension(int initialCapacity) {
 461             super(initialCapacity);
 462         }
 463 
 464         /** Returns the number of grammars contained in this pool. */
 465         int getGrammarCount() {
 466             return fGrammarCount;
 467         }