1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2000-2002,2004,2005 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * 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 java.util.Hashtable;
  24 
  25 import javax.xml.XMLConstants;
  26 import javax.xml.parsers.DocumentBuilder;
  27 import javax.xml.parsers.DocumentBuilderFactory;
  28 import javax.xml.parsers.ParserConfigurationException;
  29 import javax.xml.validation.Schema;
  30 
  31 import com.sun.org.apache.xerces.internal.parsers.DOMParser;
  32 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  33 import org.xml.sax.SAXException;
  34 import org.xml.sax.SAXNotRecognizedException;
  35 import org.xml.sax.SAXNotSupportedException;
  36 
  37 /**
  38  * @author Rajiv Mordani
  39  * @author Edwin Goei
  40  * @version $Id: DocumentBuilderFactoryImpl.java,v 1.8 2010-11-01 04:40:06 joehw Exp $
  41  */
  42 public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
  43     /** These are DocumentBuilderFactory attributes not DOM attributes */
  44     private Hashtable attributes;
  45     private Hashtable features;
  46     private Schema grammar;
  47     private boolean isXIncludeAware;
  48 
  49     /**
  50      * State of the secure processing feature, initially <code>false</code>
  51      */
  52     private boolean fSecureProcess = true;
  53 
  54     /**
  55      * Creates a new instance of a {@link javax.xml.parsers.DocumentBuilder}
  56      * using the currently configured parameters.
  57      */
  58     public DocumentBuilder newDocumentBuilder()
  59         throws ParserConfigurationException
  60     {
  61         /** Check that if a Schema has been specified that neither of the schema properties have been set. */
  62         if (grammar != null && attributes != null) {
  63             if (attributes.containsKey(JAXPConstants.JAXP_SCHEMA_LANGUAGE)) {
  64                 throw new ParserConfigurationException(
  65                         SAXMessageFormatter.formatMessage(null,
  66                         "schema-already-specified", new Object[] {JAXPConstants.JAXP_SCHEMA_LANGUAGE}));
  67             }
  68             else if (attributes.containsKey(JAXPConstants.JAXP_SCHEMA_SOURCE)) {
  69                 throw new ParserConfigurationException(
  70                         SAXMessageFormatter.formatMessage(null,
  71                         "schema-already-specified", new Object[] {JAXPConstants.JAXP_SCHEMA_SOURCE}));
  72             }
  73         }
  74 
  75         try {
  76             return new DocumentBuilderImpl(this, attributes, features, fSecureProcess);
  77         } catch (SAXException se) {
  78             // Handles both SAXNotSupportedException, SAXNotRecognizedException
  79             throw new ParserConfigurationException(se.getMessage());
  80         }
  81     }
  82 
  83     /**
  84      * Allows the user to set specific attributes on the underlying
  85      * implementation.
  86      * @param name    name of attribute
  87      * @param value   null means to remove attribute
  88      */
  89     public void setAttribute(String name, Object value)
  90         throws IllegalArgumentException
  91     {
  92         // This handles removal of attributes
  93         if (value == null) {
  94             if (attributes != null) {
  95                 attributes.remove(name);
  96             }
  97             // Unrecognized attributes do not cause an exception
  98             return;
  99         }
 100 
 101         // This is ugly.  We have to collect the attributes and then
 102         // later create a DocumentBuilderImpl to verify the attributes.
 103 
 104         // Create Hashtable if none existed before
 105         if (attributes == null) {
 106             attributes = new Hashtable();
 107         }
 108 
 109         attributes.put(name, value);
 110 
 111         // Test the attribute name by possibly throwing an exception
 112         try {
 113             new DocumentBuilderImpl(this, attributes, features);
 114         } catch (Exception e) {
 115             attributes.remove(name);
 116             throw new IllegalArgumentException(e.getMessage());
 117         }
 118     }
 119 
 120     /**
 121      * Allows the user to retrieve specific attributes on the underlying
 122      * implementation.
 123      */
 124     public Object getAttribute(String name)
 125         throws IllegalArgumentException
 126     {
 127         // See if it's in the attributes Hashtable
 128         if (attributes != null) {
 129             Object val = attributes.get(name);
 130             if (val != null) {
 131                 return val;
 132             }
 133         }
 134 
 135         DOMParser domParser = null;
 136         try {
 137             // We create a dummy DocumentBuilderImpl in case the attribute
 138             // name is not one that is in the attributes hashtable.
 139             domParser =
 140                 new DocumentBuilderImpl(this, attributes, features).getDOMParser();
 141             return domParser.getProperty(name);
 142         } catch (SAXException se1) {
 143             // assert(name is not recognized or not supported), try feature
 144             try {
 145                 boolean result = domParser.getFeature(name);
 146                 // Must have been a feature
 147                 return result ? Boolean.TRUE : Boolean.FALSE;
 148             } catch (SAXException se2) {
 149                 // Not a property or a feature
 150                 throw new IllegalArgumentException(se1.getMessage());
 151             }
 152         }
 153     }
 154 
 155     public Schema getSchema() {
 156         return grammar;
 157     }
 158 
 159     public void setSchema(Schema grammar) {
 160         this.grammar = grammar;
 161     }
 162 
 163     public boolean isXIncludeAware() {
 164         return this.isXIncludeAware;
 165     }
 166 
 167     public void setXIncludeAware(boolean state) {
 168         this.isXIncludeAware = state;
 169     }
 170 
 171     public boolean getFeature(String name)
 172         throws ParserConfigurationException {
 173         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 174             return fSecureProcess;
 175         }
 176         // See if it's in the features Hashtable
 177         if (features != null) {
 178             Object val = features.get(name);
 179             if (val != null) {
 180                 return ((Boolean) val).booleanValue();
 181             }
 182         }
 183         try {
 184             DOMParser domParser = new DocumentBuilderImpl(this, attributes, features).getDOMParser();
 185             return domParser.getFeature(name);
 186         }
 187         catch (SAXException e) {
 188             throw new ParserConfigurationException(e.getMessage());
 189         }
 190     }
 191 
 192     public void setFeature(String name, boolean value)
 193         throws ParserConfigurationException {
 194         if (features == null) {
 195             features = new Hashtable();
 196         }
 197         // If this is the secure processing feature, save it then return.
 198         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 199             if (System.getSecurityManager() != null && (!value)) {
 200                 throw new ParserConfigurationException(
 201                         SAXMessageFormatter.formatMessage(null,
 202                         "jaxp-secureprocessing-feature", null));
 203             }
 204             fSecureProcess = value;
 205             features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
 206             return;
 207         }
 208 
 209         features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
 210         // Test the feature by possibly throwing SAX exceptions
 211         try {
 212             new DocumentBuilderImpl(this, attributes, features);
 213         }
 214         catch (SAXNotSupportedException e) {
 215             features.remove(name);
 216             throw new ParserConfigurationException(e.getMessage());
 217         }
 218         catch (SAXNotRecognizedException e) {
 219             features.remove(name);
 220             throw new ParserConfigurationException(e.getMessage());
 221         }
 222     }
 223 }