< prev index next >

src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java

Print this page
rev 1025 : 8023653: [JAXP] xalan inconsistently parses DOMSource and StreamSource
   1 /*
   2  * Copyright (c) 2007, 2016, 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.xml.internal.utils;
  22 
  23 import com.sun.org.apache.xalan.internal.XalanConstants;
  24 import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
  25 import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
  26 import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
  27 import java.util.HashMap;
  28 import javax.xml.XMLConstants;
  29 import javax.xml.catalog.CatalogFeatures;
  30 import javax.xml.parsers.FactoryConfigurationError;
  31 import javax.xml.parsers.ParserConfigurationException;
  32 import javax.xml.parsers.SAXParserFactory;
  33 import jdk.xml.internal.JdkXmlFeatures;
  34 import jdk.xml.internal.JdkXmlUtils;
  35 import org.xml.sax.SAXException;
  36 import org.xml.sax.SAXNotRecognizedException;
  37 import org.xml.sax.SAXNotSupportedException;
  38 import org.xml.sax.XMLReader;
  39 import org.xml.sax.helpers.XMLReaderFactory;
  40 
  41 /**
  42  * Creates XMLReader objects and caches them for re-use.
  43  * This class follows the singleton pattern.
  44  */
  45 @SuppressWarnings("deprecation") //org.xml.sax.helpers.XMLReaderFactory
  46 public class XMLReaderManager {
  47 
  48     private static final String NAMESPACES_FEATURE =
  49                              "http://xml.org/sax/features/namespaces";
  50     private static final String NAMESPACE_PREFIXES_FEATURE =
  51                              "http://xml.org/sax/features/namespace-prefixes";
  52     private static final XMLReaderManager m_singletonManager =
  53                                                      new XMLReaderManager();
  54     private static final String property = "org.xml.sax.driver";

  55     /**
  56      * Parser factory to be used to construct XMLReader objects
  57      */
  58     private static SAXParserFactory m_parserFactory;
  59 
  60     /**
  61      * Cache of XMLReader objects
  62      */
  63     private ThreadLocal<XMLReader> m_readers;
  64 
  65     /**
  66      * Keeps track of whether an XMLReader object is in use.
  67      */
  68     private HashMap<XMLReader, Boolean> m_inUse;
  69 
  70     private boolean m_useServicesMechanism = true;
  71 


  72     private boolean _secureProcessing;
  73      /**

  74      * protocols allowed for external DTD references in source file and/or stylesheet.
  75      */
  76     private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
  77 
  78     private XMLSecurityManager _xmlSecurityManager;
  79 
  80     //Catalog Feature


  81     private boolean _useCatalog;
  82     private CatalogFeatures _catalogFeatures;
  83 
  84     /**
  85      * Hidden constructor
  86      */
  87     private XMLReaderManager() {
  88     }
  89 
  90     /**
  91      * Retrieves the singleton reader manager
  92      */
  93     public static XMLReaderManager getInstance(boolean useServicesMechanism) {
  94         m_singletonManager.setServicesMechnism(useServicesMechanism);
  95         return m_singletonManager;
  96     }
  97 
  98     /**
  99      * Retrieves a cached XMLReader for this thread, or creates a new
 100      * XMLReader, if the existing reader is in use.  When the caller no
 101      * longer needs the reader, it must release it with a call to
 102      * {@link #releaseXMLReader}.
 103      */
 104     public synchronized XMLReader getXMLReader() throws SAXException {
 105         XMLReader reader;
 106 
 107         if (m_readers == null) {
 108             // When the m_readers.get() method is called for the first time
 109             // on a thread, a new XMLReader will automatically be created.
 110             m_readers = new ThreadLocal<>();
 111         }
 112 
 113         if (m_inUse == null) {
 114             m_inUse = new HashMap<>();
 115         }
 116 
 117         // If the cached reader for this thread is in use, construct a new
 118         // one; otherwise, return the cached reader unless it isn't an
 119         // instance of the class set in the 'org.xml.sax.driver' property
 120         reader = m_readers.get();
 121         boolean threadHasReader = (reader != null);
 122         String factory = SecuritySupport.getSystemProperty(property);
 123         if (threadHasReader && m_inUse.get(reader) != Boolean.TRUE &&
 124                 ( factory == null || reader.getClass().getName().equals(factory))) {

 125             m_inUse.put(reader, Boolean.TRUE);
 126         } else {
 127             try {
 128                 try {
 129                     // According to JAXP 1.2 specification, if a SAXSource
 130                     // is created using a SAX InputSource the Transformer or
 131                     // TransformerFactory creates a reader via the
 132                     // XMLReaderFactory if setXMLReader is not used
 133                     reader = XMLReaderFactory.createXMLReader();
 134                     try {
 135                         reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _secureProcessing);
 136                     } catch (SAXNotRecognizedException e) {
 137                         XMLSecurityManager.printWarning(reader.getClass().getName(),
 138                                 XMLConstants.FEATURE_SECURE_PROCESSING, e);
 139                     }
 140                 } catch (SAXException e) {
 141                    try {
 142                         // If unable to create an instance, let's try to use
 143                         // the XMLReader from JAXP
 144                         if (m_parserFactory == null) {
 145                             m_parserFactory = FactoryImpl.getSAXFactory(m_useServicesMechanism);
 146                             m_parserFactory.setNamespaceAware(true);
 147                         }
 148 
 149                         reader = m_parserFactory.newSAXParser().getXMLReader();
 150                    } catch (ParserConfigurationException pce) {
 151                        throw pce;   // pass along pce
 152                    }
 153                 }
 154                 try {
 155                     reader.setFeature(NAMESPACES_FEATURE, true);
 156                     reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
 157                 } catch (SAXException se) {
 158                     // Try to carry on if we've got a parser that
 159                     // doesn't know about namespace prefixes.
 160                 }
 161             } catch (ParserConfigurationException ex) {
 162                 throw new SAXException(ex);
 163             } catch (FactoryConfigurationError ex1) {
 164                 throw new SAXException(ex1.toString());
 165             } catch (NoSuchMethodError | AbstractMethodError ex2) {
 166             }
 167 
 168             // Cache the XMLReader if this is the first time we've created
 169             // a reader for this thread.
 170             if (!threadHasReader) {
 171                 m_readers.set(reader);
 172                 m_inUse.put(reader, Boolean.TRUE);
 173             }
 174         }
 175 
 176         try {














 177             //reader is cached, but this property might have been reset
 178             reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
 179         } catch (SAXException se) {
 180             XMLSecurityManager.printWarning(reader.getClass().getName(),
 181                     XMLConstants.ACCESS_EXTERNAL_DTD, se);
 182         }
 183 
 184         String lastProperty = "";
 185         try {
 186             if (_xmlSecurityManager != null) {
 187                 for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
 188                     lastProperty = limit.apiProperty();
 189                     reader.setProperty(lastProperty,
 190                             _xmlSecurityManager.getLimitValueAsString(limit));
 191                 }
 192                 if (_xmlSecurityManager.printEntityCountInfo()) {
 193                     lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
 194                     reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES);
 195                 }
 196             }


 232         }
 233     }
 234     /**
 235      * Return the state of the services mechanism feature.
 236      */
 237     public boolean useServicesMechnism() {
 238         return m_useServicesMechanism;
 239     }
 240 
 241     /**
 242      * Set the state of the services mechanism feature.
 243      */
 244     public void setServicesMechnism(boolean flag) {
 245         m_useServicesMechanism = flag;
 246     }
 247 
 248     /**
 249      * Set feature
 250      */
 251     public void setFeature(String name, boolean value) {
 252         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 253             _secureProcessing = value;
 254         } else if (XMLConstants.USE_CATALOG.equals(name)) {
 255             _useCatalog = value;


 256         }
 257     }
 258 
 259     /**
 260      * Get property value
 261      */
 262     public Object getProperty(String name) {
 263         if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
 264             return _accessExternalDTD;
 265         } else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
 266             return _xmlSecurityManager;
 267         }
 268         return null;
 269     }
 270 
 271     /**
 272      * Set property.
 273      */
 274     public void setProperty(String name, Object value) {
 275         if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
   1 /*
   2  * Copyright (c) 2007, 2016, 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 package com.sun.org.apache.xml.internal.utils;
  21 
  22 import com.sun.org.apache.xalan.internal.XalanConstants;
  23 import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
  24 import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
  25 import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
  26 import java.util.HashMap;
  27 import javax.xml.XMLConstants;
  28 import javax.xml.catalog.CatalogFeatures;
  29 import javax.xml.parsers.FactoryConfigurationError;
  30 import javax.xml.parsers.ParserConfigurationException;
  31 import javax.xml.parsers.SAXParserFactory;
  32 import jdk.xml.internal.JdkXmlFeatures;
  33 import jdk.xml.internal.JdkXmlUtils;
  34 import org.xml.sax.SAXException;
  35 import org.xml.sax.SAXNotRecognizedException;
  36 import org.xml.sax.SAXNotSupportedException;
  37 import org.xml.sax.XMLReader;
  38 import org.xml.sax.helpers.XMLReaderFactory;
  39 
  40 /**
  41  * Creates XMLReader objects and caches them for re-use.
  42  * This class follows the singleton pattern.
  43  */
  44 @SuppressWarnings("deprecation") //org.xml.sax.helpers.XMLReaderFactory
  45 public class XMLReaderManager {
  46 
  47     private static final String NAMESPACES_FEATURE =
  48                              "http://xml.org/sax/features/namespaces";
  49     private static final String NAMESPACE_PREFIXES_FEATURE =
  50                              "http://xml.org/sax/features/namespace-prefixes";
  51     private static final XMLReaderManager m_singletonManager =
  52                              new XMLReaderManager();
  53     private static final String property = "org.xml.sax.driver";
  54 
  55     /**
  56      * Parser factory to be used to construct XMLReader objects
  57      */
  58     private static SAXParserFactory m_parserFactory;
  59 
  60     /**
  61      * Cache of XMLReader objects
  62      */
  63     private ThreadLocal<XMLReader> m_readers;
  64 
  65     /**
  66      * Keeps track of whether an XMLReader object is in use.
  67      */
  68     private HashMap<XMLReader, Boolean> m_inUse;
  69 
  70     private boolean m_useServicesMechanism = true;
  71 
  72     private boolean m_NamespaceAware = true;
  73 
  74     private boolean _secureProcessing;
  75 
  76     /**
  77      * protocols allowed for external DTD references in source file and/or stylesheet.
  78      */
  79     private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
  80 
  81     private XMLSecurityManager _xmlSecurityManager;
  82 
  83     /**
  84      * Catalog Feature
  85      */
  86     private boolean _useCatalog;
  87     private CatalogFeatures _catalogFeatures;
  88 
  89     /**
  90      * Hidden constructor
  91      */
  92     private XMLReaderManager() {}

  93 
  94     /**
  95      * Retrieves the singleton reader manager
  96      */
  97     public static XMLReaderManager getInstance(boolean useServicesMechanism) {
  98         m_singletonManager.setServicesMechnism(useServicesMechanism);
  99         return m_singletonManager;
 100     }
 101 
 102     /**
 103      * Retrieves a cached XMLReader for this thread, or creates a new
 104      * XMLReader, if the existing reader is in use.  When the caller no
 105      * longer needs the reader, it must release it with a call to
 106      * {@link #releaseXMLReader}.
 107      */
 108     public synchronized XMLReader getXMLReader() throws SAXException {
 109         XMLReader reader;
 110 
 111         if (m_readers == null) {
 112             // When the m_readers.get() method is called for the first time
 113             // on a thread, a new XMLReader will automatically be created.
 114             m_readers = new ThreadLocal<>();
 115         }
 116 
 117         if (m_inUse == null) {
 118             m_inUse = new HashMap<>();
 119         }
 120 
 121         // If the cached reader for this thread is in use, construct a new
 122         // one; otherwise, return the cached reader unless it isn't an
 123         // instance of the class set in the 'org.xml.sax.driver' property
 124         reader = m_readers.get();
 125         boolean threadHasReader = (reader != null);
 126         String factory = SecuritySupport.getSystemProperty(property);
 127         if (threadHasReader &&
 128             m_inUse.get(reader) != Boolean.TRUE &&
 129             (factory == null || reader.getClass().getName().equals(factory))) {
 130             m_inUse.put(reader, Boolean.TRUE);
 131         } else {
 132             try {
 133                 try {
 134                     // According to JAXP 1.2 specification, if a SAXSource
 135                     // is created using a SAX InputSource the Transformer or
 136                     // TransformerFactory creates a reader via the
 137                     // XMLReaderFactory if setXMLReader is not used
 138                     reader = XMLReaderFactory.createXMLReader();
 139                     try {
 140                         reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _secureProcessing);
 141                     } catch (SAXNotRecognizedException e) {
 142                         XMLSecurityManager.printWarning(reader.getClass().getName(),
 143                                 XMLConstants.FEATURE_SECURE_PROCESSING, e);
 144                     }
 145                 } catch (SAXException e) {
 146                    try {
 147                         // If unable to create an instance, let's try to use
 148                         // the XMLReader from JAXP
 149                         if (m_parserFactory == null) {
 150                             m_parserFactory = FactoryImpl.getSAXFactory(m_useServicesMechanism);
 151                             m_parserFactory.setNamespaceAware(true);
 152                         }
 153 
 154                         reader = m_parserFactory.newSAXParser().getXMLReader();
 155                    } catch (ParserConfigurationException pce) {
 156                        throw pce;   // pass along pce
 157                    }
 158                 }







 159             } catch (ParserConfigurationException ex) {
 160                 throw new SAXException(ex);
 161             } catch (FactoryConfigurationError ex1) {
 162                 throw new SAXException(ex1.toString());
 163             } catch (NoSuchMethodError | AbstractMethodError ex2) {
 164             }
 165 
 166             // Cache the XMLReader if this is the first time we've created
 167             // a reader for this thread.
 168             if (!threadHasReader) {
 169                 m_readers.set(reader);
 170                 m_inUse.put(reader, Boolean.TRUE);
 171             }
 172         }
 173 
 174         try {
 175             //reader is cached, but this feature might have been reset
 176             if (m_NamespaceAware) {
 177                 reader.setFeature(NAMESPACES_FEATURE, true);
 178                 reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
 179             } else {
 180                 reader.setFeature(NAMESPACES_FEATURE, false);
 181                 reader.setFeature(NAMESPACE_PREFIXES_FEATURE, true);
 182             }
 183         } catch (SAXException se) {
 184             // Try to carry on if we've got a parser that
 185             // doesn't know about namespace prefixes.
 186         }
 187 
 188         try {
 189             //reader is cached, but this property might have been reset
 190             reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
 191         } catch (SAXException se) {
 192             XMLSecurityManager.printWarning(reader.getClass().getName(),
 193                     XMLConstants.ACCESS_EXTERNAL_DTD, se);
 194         }
 195 
 196         String lastProperty = "";
 197         try {
 198             if (_xmlSecurityManager != null) {
 199                 for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
 200                     lastProperty = limit.apiProperty();
 201                     reader.setProperty(lastProperty,
 202                             _xmlSecurityManager.getLimitValueAsString(limit));
 203                 }
 204                 if (_xmlSecurityManager.printEntityCountInfo()) {
 205                     lastProperty = XalanConstants.JDK_ENTITY_COUNT_INFO;
 206                     reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES);
 207                 }
 208             }


 244         }
 245     }
 246     /**
 247      * Return the state of the services mechanism feature.
 248      */
 249     public boolean useServicesMechnism() {
 250         return m_useServicesMechanism;
 251     }
 252 
 253     /**
 254      * Set the state of the services mechanism feature.
 255      */
 256     public void setServicesMechnism(boolean flag) {
 257         m_useServicesMechanism = flag;
 258     }
 259 
 260     /**
 261      * Set feature
 262      */
 263     public void setFeature(String name, boolean value) {
 264         if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(name)) {
 265             _secureProcessing = value;
 266         } else if (XMLConstants.USE_CATALOG.equals(name)) {
 267             _useCatalog = value;
 268         } else if (NAMESPACES_FEATURE.equals(name)) {
 269             m_NamespaceAware = value;
 270         }
 271     }
 272 
 273     /**
 274      * Get property value
 275      */
 276     public Object getProperty(String name) {
 277         if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
 278             return _accessExternalDTD;
 279         } else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
 280             return _xmlSecurityManager;
 281         }
 282         return null;
 283     }
 284 
 285     /**
 286      * Set property.
 287      */
 288     public void setProperty(String name, Object value) {
 289         if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
< prev index next >