jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
changeset 39907 db51759e3695
parent 36520 cb52aa47ff0a
child 39909 00e4298ae168
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java	Thu Jul 28 16:44:02 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java	Thu Jul 28 22:58:41 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,17 +17,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id: TransformerFactoryImpl.java,v 1.8 2007/04/09 21:30:41 joehw Exp $
- */
 
 package com.sun.org.apache.xalan.internal.xsltc.trax;
 
 import com.sun.org.apache.xalan.internal.XalanConstants;
 import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
-import com.sun.org.apache.xalan.internal.utils.FeatureManager;
 import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase;
-import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase.State;
 import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
 import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
 import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
@@ -48,6 +43,7 @@
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Map;
 import java.util.Properties;
@@ -55,6 +51,10 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import javax.xml.XMLConstants;
+import javax.xml.catalog.CatalogFeatures;
+import javax.xml.catalog.CatalogFeatures.Feature;
+import javax.xml.catalog.CatalogManager;
+import javax.xml.catalog.CatalogUriResolver;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import javax.xml.transform.ErrorListener;
@@ -75,6 +75,8 @@
 import javax.xml.transform.stax.*;
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
+import jdk.xml.internal.JdkXmlFeatures;
+import jdk.xml.internal.JdkXmlUtils;
 import org.xml.sax.InputSource;
 import org.xml.sax.XMLFilter;
 import org.xml.sax.XMLReader;
@@ -86,6 +88,7 @@
  * @author Morten Jorgensen
  * @author Santiago Pericas-Geertsen
  */
+@SuppressWarnings("deprecation") //org.xml.sax.helpers.XMLReaderFactory
 public class TransformerFactoryImpl
     extends SAXTransformerFactory implements SourceLoader, ErrorListener
 {
@@ -229,7 +232,7 @@
     private XMLSecurityPropertyManager _xmlSecurityPropertyMgr;
     private XMLSecurityManager _xmlSecurityManager;
 
-    private final FeatureManager _featureManager;
+    private final JdkXmlFeatures _xmlFeatures;
 
     private ClassLoader _extensionClassLoader = null;
 
@@ -238,6 +241,15 @@
     // type checking
     private Map<String, Class> _xsltcExtensionFunctions;
 
+    CatalogUriResolver _catalogUriResolver;
+    CatalogFeatures _catalogFeatures;
+    CatalogFeatures.Builder cfBuilder = CatalogFeatures.builder();
+    // Catalog features
+    String _catalogFiles = null;
+    String _catalogDefer = null;
+    String _catalogPrefer = null;
+    String _catalogResolve = null;
+
     /**
      * javax.xml.transform.sax.TransformerFactory implementation.
      */
@@ -251,15 +263,13 @@
 
     private TransformerFactoryImpl(boolean useServicesMechanism) {
         this._useServicesMechanism = useServicesMechanism;
-        _featureManager = new FeatureManager();
 
         if (System.getSecurityManager() != null) {
             _isSecureMode = true;
             _isNotSecureProcessing = false;
-            _featureManager.setValue(FeatureManager.Feature.ORACLE_ENABLE_EXTENSION_FUNCTION,
-                    FeaturePropertyBase.State.FSP, XalanConstants.FEATURE_FALSE);
         }
 
+        _xmlFeatures = new JdkXmlFeatures(!_isNotSecureProcessing);
         _xmlSecurityPropertyMgr = new XMLSecurityPropertyManager();
         _accessExternalDTD = _xmlSecurityPropertyMgr.getValue(
                 Property.ACCESS_EXTERNAL_DTD);
@@ -332,10 +342,10 @@
             return _transletName;
         }
         else if (name.equals(GENERATE_TRANSLET)) {
-            return new Boolean(_generateTranslet);
+            return _generateTranslet;
         }
         else if (name.equals(AUTO_TRANSLET)) {
-            return new Boolean(_autoTranslet);
+            return _autoTranslet;
         }
         else if (name.equals(ENABLE_INLINING)) {
             if (_enableInlining)
@@ -346,6 +356,16 @@
             return _xmlSecurityManager;
         } else if (name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) {
            return _extensionClassLoader;
+        } else if (JdkXmlUtils.CATALOG_FILES.equals(name)) {
+            return _catalogFiles;
+        } else if (JdkXmlUtils.CATALOG_DEFER.equals(name)) {
+            return _catalogDefer;
+        } else if (JdkXmlUtils.CATALOG_PREFER.equals(name)) {
+            return _catalogPrefer;
+        } else if (JdkXmlUtils.CATALOG_RESOLVE.equals(name)) {
+            return _catalogResolve;
+        } else if (JdkXmlFeatures.CATALOG_FEATURES.equals(name)) {
+            return buildCatalogFeatures();
         }
 
         /** Check to see if the property is managed by the security manager **/
@@ -398,7 +418,7 @@
         }
         else if (name.equals(GENERATE_TRANSLET)) {
             if (value instanceof Boolean) {
-                _generateTranslet = ((Boolean) value).booleanValue();
+                _generateTranslet = ((Boolean) value);
                 return;
             }
             else if (value instanceof String) {
@@ -408,7 +428,7 @@
         }
         else if (name.equals(AUTO_TRANSLET)) {
             if (value instanceof Boolean) {
-                _autoTranslet = ((Boolean) value).booleanValue();
+                _autoTranslet = ((Boolean) value);
                 return;
             }
             else if (value instanceof String) {
@@ -418,7 +438,7 @@
         }
         else if (name.equals(USE_CLASSPATH)) {
             if (value instanceof Boolean) {
-                _useClasspath = ((Boolean) value).booleanValue();
+                _useClasspath = ((Boolean) value);
                 return;
             }
             else if (value instanceof String) {
@@ -428,7 +448,7 @@
         }
         else if (name.equals(DEBUG)) {
             if (value instanceof Boolean) {
-                _debug = ((Boolean) value).booleanValue();
+                _debug = ((Boolean) value);
                 return;
             }
             else if (value instanceof String) {
@@ -438,7 +458,7 @@
         }
         else if (name.equals(ENABLE_INLINING)) {
             if (value instanceof Boolean) {
-                _enableInlining = ((Boolean) value).booleanValue();
+                _enableInlining = ((Boolean) value);
                 return;
             }
             else if (value instanceof String) {
@@ -457,7 +477,7 @@
                 }
             }
             else if (value instanceof Integer) {
-                _indentNumber = ((Integer) value).intValue();
+                _indentNumber = ((Integer) value);
                 return;
             }
         }
@@ -470,6 +490,22 @@
                     = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_VALUE_ERR, "Extension Functions ClassLoader");
                 throw new IllegalArgumentException(err.toString());
             }
+        } else if (JdkXmlUtils.CATALOG_FILES.equals(name)) {
+            _catalogFiles = (String) value;
+            cfBuilder = CatalogFeatures.builder().with(Feature.FILES, _catalogFiles);
+            return;
+        } else if (JdkXmlUtils.CATALOG_DEFER.equals(name)) {
+            _catalogDefer = (String) value;
+            cfBuilder = CatalogFeatures.builder().with(Feature.DEFER, _catalogDefer);
+            return;
+        } else if (JdkXmlUtils.CATALOG_PREFER.equals(name)) {
+            _catalogPrefer = (String) value;
+            cfBuilder = CatalogFeatures.builder().with(Feature.PREFER, _catalogPrefer);
+            return;
+        } else if (JdkXmlUtils.CATALOG_RESOLVE.equals(name)) {
+            _catalogResolve = (String) value;
+            cfBuilder = CatalogFeatures.builder().with(Feature.RESOLVE, _catalogResolve);
+            return;
         }
 
         if (_xmlSecurityManager != null &&
@@ -534,18 +570,18 @@
             // set external access restriction when FSP is explicitly set
             if (value) {
                 _xmlSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_DTD,
-                        State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP);
+                        FeaturePropertyBase.State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP);
                 _xmlSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_STYLESHEET,
-                        State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP);
+                        FeaturePropertyBase.State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP);
                 _accessExternalDTD = _xmlSecurityPropertyMgr.getValue(
                         Property.ACCESS_EXTERNAL_DTD);
                 _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue(
                         Property.ACCESS_EXTERNAL_STYLESHEET);
             }
 
-            if (value && _featureManager != null) {
-                _featureManager.setValue(FeatureManager.Feature.ORACLE_ENABLE_EXTENSION_FUNCTION,
-                        FeaturePropertyBase.State.FSP, XalanConstants.FEATURE_FALSE);
+            if (value && _xmlFeatures != null) {
+                _xmlFeatures.setFeature(JdkXmlFeatures.XmlFeature.ENABLE_EXTENSION_FUNCTION,
+                        JdkXmlFeatures.State.FSP, false);
             }
         }
         else if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
@@ -554,8 +590,8 @@
                 _useServicesMechanism = value;
         }
         else {
-            if (_featureManager != null &&
-                    _featureManager.setValue(name, State.APIPROPERTY, value)) {
+            if (_xmlFeatures != null &&
+                    _xmlFeatures.setFeature(name, JdkXmlFeatures.State.APIPROPERTY, value)) {
                 return;
             }
 
@@ -603,16 +639,15 @@
                 return true;
             }
         }
-        // secure processing?
+
         if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
-                return !_isNotSecureProcessing;
+            return !_isNotSecureProcessing;
         }
 
-        /** Check to see if the property is managed by the security manager **/
-        String propertyValue = (_featureManager != null) ?
-                _featureManager.getValueAsString(name) : null;
-        if (propertyValue != null) {
-            return Boolean.parseBoolean(propertyValue);
+        /** Check to see if the property is managed by the JdkXmlFeatues **/
+        int index = _xmlFeatures.getIndex(name);
+        if (index > -1) {
+            return _xmlFeatures.getFeature(index);
         }
 
         // Feature not supported
@@ -628,8 +663,8 @@
      /**
      * @return the feature manager
      */
-    public FeatureManager getFeatureManager() {
-        return _featureManager;
+    public JdkXmlFeatures getJdkXmlFeatures() {
+        return _xmlFeatures;
     }
 
     /**
@@ -736,21 +771,9 @@
         } catch (StopParseException e ) {
           // startElement encountered so do not parse further
 
-        } catch (javax.xml.parsers.ParserConfigurationException e) {
-
+        } catch (javax.xml.parsers.ParserConfigurationException | org.xml.sax.SAXException | IOException e) {
              throw new TransformerConfigurationException(
              "getAssociatedStylesheets failed", e);
-
-        } catch (org.xml.sax.SAXException se) {
-
-             throw new TransformerConfigurationException(
-             "getAssociatedStylesheets failed", se);
-
-
-        } catch (IOException ioe ) {
-           throw new TransformerConfigurationException(
-           "getAssociatedStylesheets failed", ioe);
-
         }
 
          return _stylesheetPIHandler.getAssociatedStylesheet();
@@ -768,6 +791,9 @@
     public Transformer newTransformer()
         throws TransformerConfigurationException
     {
+        // create CatalogFeatures that is accessible by the Transformer
+        // through the factory instance
+        buildCatalogFeatures();
         TransformerImpl result = new TransformerImpl(new Properties(),
             _indentNumber, this);
         if (_uriResolver != null) {
@@ -805,7 +831,7 @@
     /**
      * Pass warning messages from the compiler to the error listener
      */
-    private void passWarningsToListener(Vector messages)
+    private void passWarningsToListener(ArrayList<ErrorMsg> messages)
         throws TransformerException
     {
         if (_errorListener == null || messages == null) {
@@ -814,7 +840,7 @@
         // Pass messages to listener, one by one
         final int count = messages.size();
         for (int pos = 0; pos < count; pos++) {
-            ErrorMsg msg = (ErrorMsg)messages.elementAt(pos);
+            ErrorMsg msg = messages.get(pos);
             // Workaround for the TCK failure ErrorListener.errorTests.error001.
             if (msg.isWarningError())
                 _errorListener.error(
@@ -828,7 +854,7 @@
     /**
      * Pass error messages from the compiler to the error listener
      */
-    private void passErrorsToListener(Vector messages) {
+    private void passErrorsToListener(ArrayList<ErrorMsg> messages) {
         try {
             if (_errorListener == null || messages == null) {
                 return;
@@ -836,7 +862,7 @@
             // Pass messages to listener, one by one
             final int count = messages.size();
             for (int pos = 0; pos < count; pos++) {
-                String message = messages.elementAt(pos).toString();
+                String message = messages.get(pos).toString();
                 _errorListener.error(new TransformerException(message));
             }
         }
@@ -858,6 +884,7 @@
     public Templates newTemplates(Source source)
         throws TransformerConfigurationException
     {
+        TemplatesImpl templates;
         // If the _useClasspath attribute is true, try to load the translet from
         // the CLASSPATH and create a template object using the loaded
         // translet.
@@ -871,7 +898,11 @@
                 final Class clazz = ObjectFactory.findProviderClass(transletName, true);
                 resetTransientAttributes();
 
-                return new TemplatesImpl(new Class[]{clazz}, transletName, null, _indentNumber, this);
+                templates = new TemplatesImpl(new Class[]{clazz}, transletName, null, _indentNumber, this);
+                if (_uriResolver != null) {
+                    templates.setURIResolver(_uriResolver);
+                }
+                return templates;
             }
             catch (ClassNotFoundException cnfe) {
                 ErrorMsg err = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, transletName);
@@ -912,12 +943,16 @@
                 // Reset the per-session attributes to their default values
                 // after each newTemplates() call.
                 resetTransientAttributes();
-                return new TemplatesImpl(bytecodes, transletClassName, null, _indentNumber, this);
+                templates = new TemplatesImpl(bytecodes, transletClassName, null, _indentNumber, this);
+                if (_uriResolver != null) {
+                    templates.setURIResolver(_uriResolver);
+                }
+                return templates;
             }
         }
 
         // Create and initialize a stylesheet compiler
-        final XSLTC xsltc = new XSLTC(_useServicesMechanism, _featureManager);
+        final XSLTC xsltc = new XSLTC(_useServicesMechanism, _xmlFeatures);
         if (_debug) xsltc.setDebug(true);
         if (_enableInlining)
                 xsltc.setTemplateInlining(true);
@@ -929,11 +964,17 @@
         xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
         xsltc.setProperty(XalanConstants.SECURITY_MANAGER, _xmlSecurityManager);
         xsltc.setProperty(XalanConstants.JDK_EXTENSION_CLASSLOADER, _extensionClassLoader);
+
+        // set Catalog features
+        buildCatalogFeatures();
+        xsltc.setProperty(JdkXmlFeatures.CATALOG_FEATURES, _catalogFeatures);
+
         xsltc.init();
         if (!_isNotSecureProcessing)
             _xsltcExtensionFunctions = xsltc.getExternalExtensionFunctions();
         // Set a document loader (for xsl:include/import) if defined
-        if (_uriResolver != null) {
+        if (_uriResolver != null || ( _catalogFiles != null
+                && _xmlFeatures.getFeature(JdkXmlFeatures.XmlFeature.USE_CATALOG))) {
             xsltc.setSourceLoader(this);
         }
 
@@ -1010,43 +1051,47 @@
         }
 
         // Check that the transformation went well before returning
-    if (bytecodes == null) {
-        Vector errs = xsltc.getErrors();
-        ErrorMsg err;
-        if (errs != null) {
-            err = (ErrorMsg)errs.elementAt(errs.size()-1);
-        } else {
-            err = new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR);
-        }
-        Throwable cause = err.getCause();
-        TransformerConfigurationException exc;
-        if (cause != null) {
-            exc =  new TransformerConfigurationException(cause.getMessage(), cause);
-        } else {
-            exc =  new TransformerConfigurationException(err.toString());
+        if (bytecodes == null) {
+            ArrayList<ErrorMsg> errs = xsltc.getErrors();
+            ErrorMsg err;
+            if (errs != null) {
+                err = errs.get(errs.size()-1);
+            } else {
+                err = new ErrorMsg(ErrorMsg.JAXP_COMPILE_ERR);
+            }
+            Throwable cause = err.getCause();
+            TransformerConfigurationException exc;
+            if (cause != null) {
+                exc =  new TransformerConfigurationException(cause.getMessage(), cause);
+            } else {
+                exc =  new TransformerConfigurationException(err.toString());
+            }
+
+            // Pass compiler errors to the error listener
+            if (_errorListener != null) {
+                passErrorsToListener(xsltc.getErrors());
+
+                // As required by TCK 1.2, send a fatalError to the
+                // error listener because compilation of the stylesheet
+                // failed and no further processing will be possible.
+                try {
+                    _errorListener.fatalError(exc);
+                } catch (TransformerException te) {
+                    // well, we tried.
+                }
+            }
+            else {
+                xsltc.printErrors();
+            }
+            throw exc;
         }
 
-        // Pass compiler errors to the error listener
-        if (_errorListener != null) {
-            passErrorsToListener(xsltc.getErrors());
-
-            // As required by TCK 1.2, send a fatalError to the
-            // error listener because compilation of the stylesheet
-            // failed and no further processing will be possible.
-            try {
-                _errorListener.fatalError(exc);
-            } catch (TransformerException te) {
-                // well, we tried.
-            }
+        templates = new TemplatesImpl(bytecodes, transletName, xsltc.getOutputProperties(),
+                _indentNumber, this);
+        if (_uriResolver != null) {
+            templates.setURIResolver(_uriResolver);
         }
-        else {
-            xsltc.printErrors();
-        }
-        throw exc;
-    }
-
-        return new TemplatesImpl(bytecodes, transletName,
-            xsltc.getOutputProperties(), _indentNumber, this);
+        return templates;
     }
 
     /**
@@ -1061,6 +1106,9 @@
     public TemplatesHandler newTemplatesHandler()
         throws TransformerConfigurationException
     {
+        // create CatalogFeatures that is accessible by the Handler
+        // through the factory instance
+        buildCatalogFeatures();
         final TemplatesHandlerImpl handler =
             new TemplatesHandlerImpl(_indentNumber, this);
         if (_uriResolver != null) {
@@ -1272,11 +1320,19 @@
     @Override
     public InputSource loadSource(String href, String context, XSLTC xsltc) {
         try {
+            Source source = null;
             if (_uriResolver != null) {
-                final Source source = _uriResolver.resolve(href, context);
-                if (source != null) {
-                    return Util.getInputSource(xsltc, source);
+                source = _uriResolver.resolve(href, context);
+            }
+            if (source == null && _catalogFiles != null &&
+                    _xmlFeatures.getFeature(JdkXmlFeatures.XmlFeature.USE_CATALOG)) {
+                if (_catalogUriResolver == null) {
+                    _catalogUriResolver = CatalogManager.catalogUriResolver(_catalogFeatures);
                 }
+                source = _catalogUriResolver.resolve(href, context);
+            }
+            if (source != null) {
+                return Util.getInputSource(xsltc, source);
             }
         }
         catch (TransformerException e) {
@@ -1289,6 +1345,26 @@
     }
 
     /**
+     * Build the CatalogFeatures object when a newTemplates or newTransformer is
+     * created. This will read any System Properties for the CatalogFeatures that
+     * may have been set.
+     */
+    private CatalogFeatures buildCatalogFeatures() {
+        // build will cause the CatalogFeatures to read SPs for those not set through the API
+        if (_catalogFeatures == null) {
+            _catalogFeatures = cfBuilder.build();
+        }
+
+        // update fields
+        _catalogFiles = _catalogFeatures.get(Feature.FILES);
+        _catalogDefer = _catalogFeatures.get(Feature.DEFER);
+        _catalogPrefer = _catalogFeatures.get(Feature.PREFER);
+        _catalogResolve = _catalogFeatures.get(Feature.RESOLVE);
+
+        return _catalogFeatures;
+    }
+
+    /**
      * Reset the per-session attributes to their default values
      */
     private void resetTransientAttributes() {