--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java Thu Feb 14 21:52:39 2019 +0530
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java Thu Feb 14 09:38:19 2019 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -20,15 +20,6 @@
package com.sun.org.apache.xml.internal.serializer;
-import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
-import com.sun.org.apache.xml.internal.serializer.utils.Utils;
-import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException;
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Enumeration;
import java.util.Properties;
import javax.xml.transform.OutputKeys;
import jdk.xml.internal.SecuritySupport;
@@ -68,18 +59,18 @@
* of the corresponding character, like this one: <br> quot=34 <br>
*
* <li> <b>S_USE_URL_ESCAPING </b> -
- * This non-standard property key is used to set a value of "yes" if the href values for HTML serialization should
- * use %xx escaping.
+ * This non-standard property key is used to set a value of "yes" if the href values
+ * for HTML serialization should use %xx escaping.
*
* <li> <b>S_OMIT_META_TAG </b> -
- * This non-standard property key is used to set a value of "yes" if the META tag should be omitted where it would
- * otherwise be supplied.
+ * This non-standard property key is used to set a value of "yes" if the META tag
+ * should be omitted where it would otherwise be supplied.
* </ul>
*
* @see SerializerFactory
* @see Method
* @see Serializer
- * @LastModified: Oct 2017
+ * @LastModified: Feb 2019
*/
public final class OutputPropertiesFactory
{
@@ -147,14 +138,15 @@
S_BUILTIN_EXTENSIONS_UNIVERSAL + "entities";
/**
- * This non-standard property key is used to set a value of "yes" if the href values for HTML serialization should
- * use %xx escaping. */
+ * This non-standard property key is used to set a value of "yes" if the href
+ * values for HTML serialization should use %xx escaping.
+ */
public static final String S_USE_URL_ESCAPING =
S_BUILTIN_EXTENSIONS_UNIVERSAL + "use-url-escaping";
/**
- * This non-standard property key is used to set a value of "yes" if the META tag should be omitted where it would
- * otherwise be supplied.
+ * This non-standard property key is used to set a value of "yes" if the META
+ * tag should be omitted where it would otherwise be supplied.
*/
public static final String S_OMIT_META_TAG =
S_BUILTIN_EXTENSIONS_UNIVERSAL + "omit-meta-tag";
@@ -174,53 +166,133 @@
S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL.length();
/**
- * This non-standard, Oracle-impl only property key is used as if OutputKeys.STANDALONE is specified but
- * without writing it out in the declaration; It can be used to reverse the change by Xalan patch 1495.
- * Since Xalan patch 1495 can cause incompatible behavior, this property is add for application to neutralize
- * the effect of Xalan patch 1495
+ * This non-standard, Oracle-impl only property key is used as if
+ * OutputKeys.STANDALONE is specified but without writing it out in the declaration;
+ * It can be used to reverse the change by Xalan patch 1495.
+ * Since Xalan patch 1495 can cause incompatible behavior, this property is
+ * added for application to neutralize the effect of Xalan patch 1495
*/
- /**
- * <p>Is Standalone</p>
- *
- * <ul>
- * <li>
- * <code>yes</code> to indicate the output is intended to be used as standalone
- * </li>
- * <li>
- * <code>no</code> has no effect.
- * </li>
- * </ul>
- */
+ /**
+ * <p>Is Standalone</p>
+ *
+ * <ul>
+ * <li>
+ * <code>yes</code> to indicate the output is intended to be used as standalone
+ * </li>
+ * <li>
+ * <code>no</code> has no effect.
+ * </li>
+ * </ul>
+ */
public static final String ORACLE_IS_STANDALONE = "http://www.oracle.com/xml/is-standalone";
//************************************************************
//* PRIVATE CONSTANTS
//************************************************************
- private static final String S_XSLT_PREFIX = "xslt.output.";
- private static final int S_XSLT_PREFIX_LEN = S_XSLT_PREFIX.length();
- private static final String S_XALAN_PREFIX = "org.apache.xslt.";
- private static final int S_XALAN_PREFIX_LEN = S_XALAN_PREFIX.length();
+ /*
+ * XSLT properties do not need namespace qualification.
+ *
+ * Xalan-specific output properties can be overridden in the stylesheet
+ * assigning a xalan namespace. For example:
+ * <xsl:stylesheet version="1.0"
+ * xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ * xmlns:xalan="http://xml.apache.org/xalan">
+ * <xsl:output method="html" encoding="UTF-8"
+ * xalan:content-handler="MyContentHandler"/>
+ * ...
+ */
+ private static final String[] PROP_XML = {
+ "method",
+ "version",
+ "encoding",
+ "indent",
+ "omit-xml-declaration",
+ "standalone",
+ "media-type",
+ "{http://xml.apache.org/xalan}indent-amount",
+ "{http://xml.apache.org/xalan}content-handler",
+ "{http://xml.apache.org/xalan}entities"
+ };
- /** Synchronization object for lazy initialization of the above tables. */
- private static final Object m_synch_object = new Object();
+ private static final String[] PROP_XML_VALUE = {
+ "xml",
+ "1.0",
+ "UTF-8",
+ "no",
+ "no",
+ "no",
+ "text/xml",
+ "0",
+ "com.sun.org.apache.xml.internal.serializer.ToXMLStream",
+ "com/sun/org/apache/xml/internal/serializer/XMLEntities"
+ };
- /** the directory in which the various method property files are located */
- private static final String PROP_DIR = "com/sun/org/apache/xml/internal/serializer/";
- /** property file for default XML properties */
- private static final String PROP_FILE_XML = "output_xml.properties";
- /** property file for default TEXT properties */
- private static final String PROP_FILE_TEXT = "output_text.properties";
- /** property file for default HTML properties */
- private static final String PROP_FILE_HTML = "output_html.properties";
- /** property file for default UNKNOWN (Either XML or HTML, to be determined later) properties */
- private static final String PROP_FILE_UNKNOWN = "output_unknown.properties";
+ private static final String[] PROP_HTML = {
+ "method",
+ "indent",
+ "media",
+ "version",
+ "{http://xml.apache.org/xalan}indent-amount",
+ "{http://xml.apache.org/xalan}content-handler",
+ "{http://xml.apache.org/xalan}entities",
+ "{http://xml.apache.org/xalan}use-url-escaping",
+ "{http://xml.apache.org/xalan}omit-meta-tag"
+ };
+
+ private static final String[] PROP_HTML_VALUE = {
+ "html",
+ "yes",
+ "text/html",
+ "4.0",
+ "4",
+ "com.sun.org.apache.xml.internal.serializer.ToHTMLStream",
+ "com/sun/org/apache/xml/internal/serializer/HTMLEntities",
+ "yes",
+ "no"
+ };
+
+ private static final String[] PROP_TEXT = {
+ "method",
+ "media-type",
+ "{http://xml.apache.org/xalan}content-handler"
+ };
+
+ private static final String[] PROP_TEXT_VALUE = {
+ "text",
+ "text/plain",
+ "com.sun.org.apache.xml.internal.serializer.ToTextStream"
+ };
+
+ private static final String[] PROP_UNKNOWN = {
+ "method",
+ "version",
+ "encoding",
+ "indent",
+ "omit-xml-declaration",
+ "standalone",
+ "media-type",
+ "{http://xml.apache.org/xalan}indent-amount",
+ "{http://xml.apache.org/xalan}content-handler"
+ };
+
+ private static final String[] PROP_UNKNOWN_VALUE = {
+ "xml",
+ "1.0",
+ "UTF-8",
+ "no",
+ "no",
+ "no",
+ "text/xml",
+ "0",
+ "com.sun.org.apache.xml.internal.serializer.ToUnknownStream",
+ };
//************************************************************
//* PRIVATE STATIC FIELDS
//************************************************************
- /** The default properties of all output files. */
+ /** The default properties for all other than html and text. */
private static Properties m_xml_properties = null;
/** The default properties when method="html". */
@@ -232,38 +304,8 @@
/** The properties when method="" for the "unknown" wrapper */
private static Properties m_unknown_properties = null;
- private static final Class<?>
- ACCESS_CONTROLLER_CLASS = findAccessControllerClass();
-
- private static Class<?> findAccessControllerClass() {
- try
- {
- // This Class was introduced in JDK 1.2. With the re-architecture of
- // security mechanism ( starting in JDK 1.2 ), we have option of
- // giving privileges to certain part of code using doPrivileged block.
- // In JDK1.1.X applications won't be having security manager and if
- // there is security manager ( in applets ), code need to be signed
- // and trusted for having access to resources.
-
- return Class.forName("java.security.AccessController");
- }
- catch (Exception e)
- {
- //User may be using older JDK ( JDK <1.2 ). Allow him/her to use it.
- // But don't try to use doPrivileged
- }
-
- return null;
- }
-
/**
- * Creates an empty OutputProperties with the property key/value defaults specified by
- * a property file. The method argument is used to construct a string of
- * the form output_[method].properties (for instance, output_html.properties).
- * The output_xml.properties file is always used as the base.
- *
- * <p>Anything other than 'text', 'xml', and 'html', will
- * use the output_xml.properties file.</p>
+ * Returns a Properties based on the specified method. The default is xml.
*
* @param method non-null reference to method name.
*
@@ -271,265 +313,71 @@
*/
static public final Properties getDefaultMethodProperties(String method)
{
- String fileName = null;
Properties defaultProperties = null;
- // According to this article : Double-check locking does not work
- // http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-toolbox.html
- try
- {
- synchronized (m_synch_object)
- {
- if (null == m_xml_properties) // double check
- {
- fileName = PROP_FILE_XML;
- m_xml_properties = loadPropertiesFile(fileName, null);
- }
- }
- if (method.equals(Method.XML))
- {
+ if (null == m_xml_properties) {
+ m_xml_properties = initProperties(PROP_XML, PROP_XML_VALUE, null);
+ }
+
+
+ switch (method) {
+ case Method.XML:
defaultProperties = m_xml_properties;
- }
- else if (method.equals(Method.HTML))
- {
- if (null == m_html_properties) // double check
- {
- fileName = PROP_FILE_HTML;
- m_html_properties =
- loadPropertiesFile(fileName, m_xml_properties);
+ break;
+ case Method.HTML:
+ if (null == m_html_properties) {
+ m_html_properties = initProperties(
+ PROP_HTML, PROP_HTML_VALUE, m_xml_properties);
}
-
defaultProperties = m_html_properties;
- }
- else if (method.equals(Method.TEXT))
- {
- if (null == m_text_properties) // double check
- {
- fileName = PROP_FILE_TEXT;
- m_text_properties =
- loadPropertiesFile(fileName, m_xml_properties);
- if (null
- == m_text_properties.getProperty(OutputKeys.ENCODING))
+ break;
+ case Method.TEXT:
+ if (null == m_text_properties) {
+ m_text_properties = initProperties(
+ PROP_TEXT, PROP_TEXT_VALUE, m_xml_properties);
+
+ if (null == m_text_properties.getProperty(OutputKeys.ENCODING))
{
String mimeEncoding = Encodings.getMimeEncoding(null);
- m_text_properties.put(
- OutputKeys.ENCODING,
- mimeEncoding);
+ m_text_properties.put(OutputKeys.ENCODING, mimeEncoding);
}
}
-
defaultProperties = m_text_properties;
- }
- else if (method.equals(com.sun.org.apache.xml.internal.serializer.Method.UNKNOWN))
- {
- if (null == m_unknown_properties) // double check
- {
- fileName = PROP_FILE_UNKNOWN;
- m_unknown_properties =
- loadPropertiesFile(fileName, m_xml_properties);
+ break;
+ case com.sun.org.apache.xml.internal.serializer.Method.UNKNOWN:
+ if (null == m_unknown_properties) {
+ m_unknown_properties = initProperties(
+ PROP_UNKNOWN, PROP_UNKNOWN_VALUE, m_xml_properties);
}
-
defaultProperties = m_unknown_properties;
- }
- else
- {
- // TODO: Calculate res file from name.
+ break;
+ default:
defaultProperties = m_xml_properties;
- }
+ break;
}
- catch (IOException ioe)
- {
- throw new WrappedRuntimeException(
- Utils.messages.createMessage(
- MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
- new Object[] { fileName, method }),
- ioe);
- }
+
// wrap these cached defaultProperties in a new Property object just so
// that the caller of this method can't modify the default values
return new Properties(defaultProperties);
}
/**
- * Load the properties file from a resource stream. If a
- * key name such as "org.apache.xslt.xxx", fix up the start of
- * string to be a curly namespace. If a key name starts with
- * "xslt.output.xxx", clip off "xslt.output.". If a key name *or* a
- * key value is discovered, check for \u003a in the text, and
- * fix it up to be ":", since earlier versions of the JDK do not
- * handle the escape sequence (at least in key names).
+ * Initiates the properties
*
- * @param resourceName non-null reference to resource name.
+ * @param keys an array of keys
+ * @param values values corresponding to the keys
* @param defaults Default properties, which may be null.
*/
- static private Properties loadPropertiesFile(
- final String resourceName,
- Properties defaults)
- throws IOException
+ static private Properties initProperties(String[] keys, String[] values, Properties defaults)
{
-
- // This static method should eventually be moved to a thread-specific class
- // so that we can cache the ContextClassLoader and bottleneck all properties file
- // loading throughout Xalan.
-
Properties props = new Properties(defaults);
- InputStream is = null;
- BufferedInputStream bis = null;
-
- try
- {
- if (ACCESS_CONTROLLER_CLASS != null)
- {
- is = AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
- public InputStream run()
- {
- return OutputPropertiesFactory.class
- .getResourceAsStream(resourceName);
- }
- });
- }
- else
- {
- // User may be using older JDK ( JDK < 1.2 )
- is = OutputPropertiesFactory.class
- .getResourceAsStream(resourceName);
- }
-
- bis = new BufferedInputStream(is);
- props.load(bis);
- }
- catch (IOException ioe)
- {
- if (defaults == null)
- {
- throw ioe;
- }
- else
- {
- throw new WrappedRuntimeException(
- Utils.messages.createMessage(
- MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
- new Object[] { resourceName }),
- ioe);
- //"Could not load '"+resourceName+"' (check CLASSPATH), now using just the defaults ", ioe);
- }
- }
- catch (SecurityException se)
- {
- // Repeat IOException handling for sandbox/applet case -sc
- if (defaults == null)
- {
- throw se;
- }
- else
- {
- throw new WrappedRuntimeException(
- Utils.messages.createMessage(
- MsgKey.ER_COULD_NOT_LOAD_RESOURCE,
- new Object[] { resourceName }),
- se);
- //"Could not load '"+resourceName+"' (check CLASSPATH, applet security), now using just the defaults ", se);
- }
- }
- finally
- {
- if (bis != null)
- {
- bis.close();
- }
- if (is != null)
- {
- is.close();
- }
- }
-
- // Note that we're working at the HashTable level here,
- // and not at the Properties level! This is important
- // because we don't want to modify the default properties.
- // NB: If fixupPropertyString ends up changing the property
- // name or value, we need to remove the old key and re-add
- // with the new key and value. However, then our Enumeration
- // could lose its place in the HashTable. So, we first
- // clone the HashTable and enumerate over that since the
- // clone will not change. When we migrate to Collections,
- // this code should be revisited and cleaned up to use
- // an Iterator which may (or may not) alleviate the need for
- // the clone. Many thanks to Padraig O'hIceadha
- // <padraig@gradient.ie> for finding this problem. Bugzilla 2000.
-
- Enumeration<Object> keys = ((Properties) props.clone()).keys();
- while (keys.hasMoreElements())
- {
- String key = (String) keys.nextElement();
- // Now check if the given key was specified as a
- // System property. If so, the system property
- // overides the default value in the propery file.
- String value = null;
- try
- {
- value = SecuritySupport.getSystemProperty(key);
- }
- catch (SecurityException se)
- {
- // No-op for sandbox/applet case, leave null -sc
- }
- if (value == null)
- value = (String) props.get(key);
-
- String newKey = fixupPropertyString(key, true);
- String newValue = null;
- try
- {
- newValue = SecuritySupport.getSystemProperty(newKey);
- }
- catch (SecurityException se)
- {
- // No-op for sandbox/applet case, leave null -sc
- }
- if (newValue == null)
- newValue = fixupPropertyString(value, false);
- else
- newValue = fixupPropertyString(newValue, false);
-
- if (key != newKey || value != newValue)
- {
- props.remove(key);
- props.put(newKey, newValue);
- }
-
+ for (int i = 0; i < keys.length; i++) {
+ // check System Property. This is kept as is for binary compatibility
+ String sys = SecuritySupport.getSystemProperty(keys[i]);
+ props.put(keys[i], (sys == null) ? values[i] : sys);
}
return props;
}
-
- /**
- * Fix up a string in an output properties file according to
- * the rules of {@link #loadPropertiesFile}.
- *
- * @param s non-null reference to string that may need to be fixed up.
- * @return A new string if fixup occured, otherwise the s argument.
- */
- static private String fixupPropertyString(String s, boolean doClipping)
- {
- int index;
- if (doClipping && s.startsWith(S_XSLT_PREFIX))
- {
- s = s.substring(S_XSLT_PREFIX_LEN);
- }
- if (s.startsWith(S_XALAN_PREFIX))
- {
- s =
- S_BUILTIN_EXTENSIONS_UNIVERSAL
- + s.substring(S_XALAN_PREFIX_LEN);
- }
- if ((index = s.indexOf("\\u003a")) > 0)
- {
- String temp = s.substring(index + 6);
- s = s.substring(0, index) + ":" + temp;
-
- }
- return s;
- }
-
}