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