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 
  62     /**
  63      * State of the secure processing feature, initially <code>false</code>
  64      */
  65     private boolean fSecureProcess = true;
  66 
  67     /**
  68      * Creates a new instance of <code>SAXParser</code> using the currently
  69      * configured factory parameters.
  70      * @return javax.xml.parsers.SAXParser
  71      */
  72     public SAXParser newSAXParser()
  73         throws ParserConfigurationException
  74     {
  75         SAXParser saxParserImpl;
  76         try {
  77             saxParserImpl = new SAXParserImpl(this, features, fSecureProcess);
  78         } catch (SAXException se) {
  79             // Translate to ParserConfigurationException
  80             throw new ParserConfigurationException(se.getMessage());
  81         }
  82         return saxParserImpl;
  83     }
  84 
  85     /**
  86      * Common code for translating exceptions
  87      */
  88     private SAXParserImpl newSAXParserImpl()
  89         throws ParserConfigurationException, SAXNotRecognizedException,
  90         SAXNotSupportedException
  91     {
  92         SAXParserImpl saxParserImpl;
  93         try {
  94             saxParserImpl = new SAXParserImpl(this, features);
  95         } catch (SAXNotSupportedException e) {
  96             throw e;
  97         } catch (SAXNotRecognizedException e) {
  98             throw e;
  99         } catch (SAXException se) {
 100             throw new ParserConfigurationException(se.getMessage());
 101         }
 102         return saxParserImpl;
 103     }
 104 
 105     /**
 106      * Sets the particular feature in the underlying implementation of
 107      * org.xml.sax.XMLReader.
 108      */
 109     public void setFeature(String name, boolean value)
 110         throws ParserConfigurationException, SAXNotRecognizedException,
 111                 SAXNotSupportedException {
 112         if (name == null) {
 113             throw new NullPointerException();
 114         }
 115         // If this is the secure processing feature, save it then return.
 116         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 117             if (System.getSecurityManager() != null && (!value)) {
 118                 throw new ParserConfigurationException(
 119                         SAXMessageFormatter.formatMessage(null,
 120                         "jaxp-secureprocessing-feature", null));
 121             }
 122             fSecureProcess = value;
 123             putInFeatures(name, value);
 124             return;
 125         }
 126 
 127         // XXX This is ugly.  We have to collect the features and then
 128         // later create an XMLReader to verify the features.
 129         putInFeatures(name, value);
 130         // Test the feature by possibly throwing SAX exceptions
 131         try {
 132             newSAXParserImpl();
 133         } catch (SAXNotSupportedException e) {
 134             features.remove(name);
 135             throw e;
 136         } catch (SAXNotRecognizedException e) {
 137             features.remove(name);
 138             throw e;
 139         }
 140     }
 141 
 142     /**
 143      * returns the particular property requested for in the underlying
 144      * implementation of org.xml.sax.XMLReader.
 145      */
 146     public boolean getFeature(String name)
 147         throws ParserConfigurationException, SAXNotRecognizedException,
 148                 SAXNotSupportedException {
 149         if (name == null) {
 150             throw new NullPointerException();
 151         }
 152         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 153             return fSecureProcess;
 154         }
 155         // Check for valid name by creating a dummy XMLReader to get
 156         // feature value
 157         return newSAXParserImpl().getXMLReader().getFeature(name);
 158     }
 159 
 160     public Schema getSchema() {
 161         return grammar;
 162     }
 163 
 164     public void setSchema(Schema grammar) {
 165         this.grammar = grammar;
 166     }
 167 
 168     public boolean isXIncludeAware() {
 169         return getFromFeatures(XINCLUDE_FEATURE);
 170     }
 171 
 172     public void setXIncludeAware(boolean state) {
 173         putInFeatures(XINCLUDE_FEATURE, state);
 174     }
 175 
 176 
 177     public void setValidating(boolean validating) {
 178         putInFeatures(VALIDATION_FEATURE, validating);
 179     }
 180 
 181     public boolean isValidating() {
 182          return getFromFeatures(VALIDATION_FEATURE);
 183     }
 184 
 185     private void putInFeatures(String name, boolean value){
 186          if (features == null) {
 187             features = new HashMap<>();
 188         }
 189         features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
 190     }
 191 
 192     private boolean getFromFeatures(String name){
 193          if (features == null){
 194             return false;
 195          }
 196          else {
 197              Boolean value = features.get(name);
 198              return (value == null) ? false : value;
 199          }
 200     }
 201 
 202     public boolean isNamespaceAware() {
 203         return getFromFeatures(NAMESPACES_FEATURE);
 204     }
 205 
 206     public void setNamespaceAware(boolean awareness) {
 207        putInFeatures(NAMESPACES_FEATURE, awareness);
 208     }
 209 
 210  }