/**
   * Adds all of the component's recognized features and properties to the list of default
   * recognized features and properties, and sets default values on the configuration for features
   * and properties which were previously absent from the configuration.
   *
   * @param component The component whose recognized features and properties will be added to the
   *     configuration
   */
  public void addRecognizedParamsAndSetDefaults(
      XMLComponent component, XSGrammarPoolContainer grammarContainer) {

    // register component's recognized features
    final String[] recognizedFeatures = component.getRecognizedFeatures();
    addRecognizedFeatures(recognizedFeatures);

    // register component's recognized properties
    final String[] recognizedProperties = component.getRecognizedProperties();
    addRecognizedProperties(recognizedProperties);

    // set default values
    setFeatureDefaults(component, recognizedFeatures, grammarContainer);
    setPropertyDefaults(component, recognizedProperties);
  }
 /** Sets feature defaults for the given component on this configuration. */
 private void setFeatureDefaults(
     final XMLComponent component,
     final String[] recognizedFeatures,
     XSGrammarPoolContainer grammarContainer) {
   if (recognizedFeatures != null) {
     for (int i = 0; i < recognizedFeatures.length; ++i) {
       String featureId = recognizedFeatures[i];
       Boolean state = grammarContainer.getFeature(featureId);
       if (state == null) {
         state = component.getFeatureDefault(featureId);
       }
       if (state != null) {
         // Do not overwrite values already set on the configuration.
         if (!fFeatures.containsKey(featureId)) {
           fFeatures.put(featureId, state);
           // For newly added components who recognize this feature
           // but did not offer a default value, we need to make
           // sure these components will get an opportunity to read
           // the value before parsing begins.
           fConfigUpdated = true;
         }
       }
     }
   }
 }
 /** Sets property defaults for the given component on this configuration. */
 private void setPropertyDefaults(
     final XMLComponent component, final String[] recognizedProperties) {
   if (recognizedProperties != null) {
     for (int i = 0; i < recognizedProperties.length; ++i) {
       String propertyId = recognizedProperties[i];
       Object value = component.getPropertyDefault(propertyId);
       if (value != null) {
         // Do not overwrite values already set on the configuration.
         if (!fProperties.containsKey(propertyId)) {
           fProperties.put(propertyId, value);
           // For newly added components who recognize this property
           // but did not offer a default value, we need to make
           // sure these components will get an opportunity to read
           // the value before parsing begins.
           fConfigUpdated = true;
         }
       }
     }
   }
 }
  /**
   * Create a SAX parser with the associated features
   *
   * @param features Hashtable of SAX features, may be null
   */
  SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing)
      throws SAXException {
    fSecurityManager = new XMLSecurityManager(secureProcessing);
    fSecurityPropertyMgr = new XMLSecurityPropertyManager();
    // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader
    xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr, fSecurityManager);

    // JAXP "namespaceAware" == SAX Namespaces feature
    // Note: there is a compatibility problem here with default values:
    // JAXP default is false while SAX 2 default is true!
    xmlReader.setFeature0(NAMESPACES_FEATURE, spf.isNamespaceAware());

    // SAX "namespaces" and "namespace-prefixes" features should not
    // both be false.  We make them opposite for backward compatibility
    // since JAXP 1.0 apps may want to receive xmlns* attributes.
    xmlReader.setFeature0(NAMESPACE_PREFIXES_FEATURE, !spf.isNamespaceAware());

    // Avoid setting the XInclude processing feature if the value is false.
    // This will keep the configuration from throwing an exception if it
    // does not support XInclude.
    if (spf.isXIncludeAware()) {
      xmlReader.setFeature0(XINCLUDE_FEATURE, true);
    }

    xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);

    xmlReader.setProperty0(SECURITY_MANAGER, fSecurityManager);

    if (secureProcessing) {
      /**
       * By default, secure processing is set, no external access is allowed. However, we need to
       * check if it is actively set on the factory since we allow the use of the System Property or
       * jaxp.properties to override the default value
       */
      if (features != null) {

        Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
        if (temp != null) {
          boolean value = ((Boolean) temp).booleanValue();
          if (value && Constants.IS_JDK8_OR_ABOVE) {
            fSecurityPropertyMgr.setValue(
                XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
                XMLSecurityPropertyManager.State.FSP,
                Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
            fSecurityPropertyMgr.setValue(
                XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA,
                XMLSecurityPropertyManager.State.FSP,
                Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
          }
        }
      }
    }

    // Set application's features, followed by validation features.
    setFeatures(features);

    // If validating, provide a default ErrorHandler that prints
    // validation errors with a warning telling the user to set an
    // ErrorHandler.
    if (spf.isValidating()) {
      fInitErrorHandler = new DefaultValidationErrorHandler(xmlReader.getLocale());
      xmlReader.setErrorHandler(fInitErrorHandler);
    } else {
      fInitErrorHandler = xmlReader.getErrorHandler();
    }
    xmlReader.setFeature0(VALIDATION_FEATURE, spf.isValidating());

    // Get the Schema object from the factory
    this.grammar = spf.getSchema();
    if (grammar != null) {
      XMLParserConfiguration config = xmlReader.getXMLParserConfiguration();
      XMLComponent validatorComponent = null;
      /** For Xerces grammars, use built-in schema validator. * */
      if (grammar instanceof XSGrammarPoolContainer) {
        validatorComponent = new XMLSchemaValidator();
        fSchemaValidationManager = new ValidationManager();
        fUnparsedEntityHandler = new UnparsedEntityHandler(fSchemaValidationManager);
        config.setDTDHandler(fUnparsedEntityHandler);
        fUnparsedEntityHandler.setDTDHandler(xmlReader);
        xmlReader.setDTDSource(fUnparsedEntityHandler);
        fSchemaValidatorComponentManager =
            new SchemaValidatorConfiguration(
                config, (XSGrammarPoolContainer) grammar, fSchemaValidationManager);
      }
      /** For third party grammars, use the JAXP validator component. * */
      else {
        validatorComponent = new JAXPValidatorComponent(grammar.newValidatorHandler());
        fSchemaValidationManager = null;
        fUnparsedEntityHandler = null;
        fSchemaValidatorComponentManager = config;
      }
      config.addRecognizedFeatures(validatorComponent.getRecognizedFeatures());
      config.addRecognizedProperties(validatorComponent.getRecognizedProperties());
      config.setDocumentHandler((XMLDocumentHandler) validatorComponent);
      ((XMLDocumentSource) validatorComponent).setDocumentHandler(xmlReader);
      xmlReader.setDocumentSource((XMLDocumentSource) validatorComponent);
      fSchemaValidator = validatorComponent;
    } else {
      fSchemaValidationManager = null;
      fUnparsedEntityHandler = null;
      fSchemaValidatorComponentManager = null;
      fSchemaValidator = null;
    }

    // Initial EntityResolver
    fInitEntityResolver = xmlReader.getEntityResolver();
  }