1 /*
   2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  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.jaxp;
  22 
  23 import com.sun.org.apache.xerces.internal.impl.Constants;
  24 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  25 import java.util.HashMap;
  26 import java.util.Map;
  27 import javax.xml.XMLConstants;
  28 import javax.xml.parsers.ParserConfigurationException;
  29 import javax.xml.parsers.SAXParser;
  30 import javax.xml.parsers.SAXParserFactory;
  31 import javax.xml.validation.Schema;
  32 import org.xml.sax.SAXException;
  33 import org.xml.sax.SAXNotRecognizedException;
  34 import org.xml.sax.SAXNotSupportedException;
  35 
  36 /**
  37  * This is the implementation specific class for the
  38  * <code>javax.xml.parsers.SAXParserFactory</code>. This is the platform
  39  * default implementation for the platform.
  40  *
  41  * @author Rajiv Mordani
  42  * @author Edwin Goei
  43  *
  44  */
  45 public class SAXParserFactoryImpl extends SAXParserFactory {
  46 
  47     /** Feature identifier: validation. */
  48     private static final String VALIDATION_FEATURE =
  49         Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
  50 
  51     /** Feature identifier: namespaces. */
  52     private static final String NAMESPACES_FEATURE =
  53         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
  54 
  55     /** Feature identifier: XInclude processing */
  56     private static final String XINCLUDE_FEATURE =
  57         Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;
  58 
  59     private Map<String, Boolean> features;
  60     private Schema grammar;
  61     private boolean isXIncludeAware;
  62 
  63     /**
  64      * State of the secure processing feature, initially <code>false</code>
  65      */
  66     private boolean fSecureProcess = true;
  67 
  68     /**
  69      * Creates a new instance of <code>SAXParser</code> using the currently
  70      * configured factory parameters.
  71      * @return javax.xml.parsers.SAXParser
  72      */
  73     public SAXParser newSAXParser()
  74         throws ParserConfigurationException
  75     {
  76         SAXParser saxParserImpl;
  77         try {
  78             saxParserImpl = new SAXParserImpl(this, features, fSecureProcess);
  79         } catch (SAXException se) {
  80             // Translate to ParserConfigurationException
  81             throw new ParserConfigurationException(se.getMessage());
  82         }
  83         return saxParserImpl;
  84     }
  85 
  86     /**
  87      * Common code for translating exceptions
  88      */
  89     private SAXParserImpl newSAXParserImpl()
  90         throws ParserConfigurationException, SAXNotRecognizedException,
  91         SAXNotSupportedException
  92     {
  93         SAXParserImpl saxParserImpl;
  94         try {
  95             saxParserImpl = new SAXParserImpl(this, features);
  96         } catch (SAXNotSupportedException e) {
  97             throw e;
  98         } catch (SAXNotRecognizedException e) {
  99             throw e;
 100         } catch (SAXException se) {
 101             throw new ParserConfigurationException(se.getMessage());
 102         }
 103         return saxParserImpl;
 104     }
 105 
 106     /**
 107      * Sets the particular feature in the underlying implementation of
 108      * org.xml.sax.XMLReader.
 109      */
 110     public void setFeature(String name, boolean value)
 111         throws ParserConfigurationException, SAXNotRecognizedException,
 112                 SAXNotSupportedException {
 113         if (name == null) {
 114             throw new NullPointerException();
 115         }
 116         // If this is the secure processing feature, save it then return.
 117         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 118             if (System.getSecurityManager() != null && (!value)) {
 119                 throw new ParserConfigurationException(
 120                         SAXMessageFormatter.formatMessage(null,
 121                         "jaxp-secureprocessing-feature", null));
 122             }
 123             fSecureProcess = value;
 124             putInFeatures(name, value);
 125             return;
 126         }
 127 
 128         // XXX This is ugly.  We have to collect the features and then
 129         // later create an XMLReader to verify the features.
 130         putInFeatures(name, value);
 131         // Test the feature by possibly throwing SAX exceptions
 132         try {
 133             newSAXParserImpl();
 134         } catch (SAXNotSupportedException e) {
 135             features.remove(name);
 136             throw e;
 137         } catch (SAXNotRecognizedException e) {
 138             features.remove(name);
 139             throw e;
 140         }
 141     }
 142 
 143     /**
 144      * returns the particular property requested for in the underlying
 145      * implementation of org.xml.sax.XMLReader.
 146      */
 147     public boolean getFeature(String name)
 148         throws ParserConfigurationException, SAXNotRecognizedException,
 149                 SAXNotSupportedException {
 150         if (name == null) {
 151             throw new NullPointerException();
 152         }
 153         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 154             return fSecureProcess;
 155         }
 156         // Check for valid name by creating a dummy XMLReader to get
 157         // feature value
 158         return newSAXParserImpl().getXMLReader().getFeature(name);
 159     }
 160 
 161     public Schema getSchema() {
 162         return grammar;
 163     }
 164 
 165     public void setSchema(Schema grammar) {
 166         this.grammar = grammar;
 167     }
 168 
 169     public boolean isXIncludeAware() {
 170         return getFromFeatures(XINCLUDE_FEATURE);
 171     }
 172 
 173     public void setXIncludeAware(boolean state) {
 174         putInFeatures(XINCLUDE_FEATURE, state);
 175     }
 176 
 177 
 178     public void setValidating(boolean validating) {
 179         putInFeatures(VALIDATION_FEATURE, validating);
 180     }
 181 
 182     public boolean isValidating() {
 183          return getFromFeatures(VALIDATION_FEATURE);
 184     }
 185 
 186     private void putInFeatures(String name, boolean value){
 187          if (features == null) {
 188             features = new HashMap<>();
 189         }
 190         features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
 191     }
 192 
 193     private boolean getFromFeatures(String name){
 194          if (features == null){
 195             return false;
 196          }
 197          else {
 198              Boolean value = features.get(name);
 199              return (value == null) ? false : value;
 200          }
 201     }
 202 
 203     public boolean isNamespaceAware() {
 204         return getFromFeatures(NAMESPACES_FEATURE);
 205     }
 206 
 207     public void setNamespaceAware(boolean awareness) {
 208        putInFeatures(NAMESPACES_FEATURE, awareness);
 209     }
 210 
 211  }