8187697: Cleanup: irrelevant code in OutputPropertiesFactory

Reviewed-by: lancea
This commit is contained in:
Joe Wang 2019-02-14 09:38:19 -08:00
parent 37169f4bbc
commit 08a370a8a5
5 changed files with 162 additions and 494 deletions

View File

@ -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 @@ import jdk.xml.internal.SecuritySupport;
* 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 @@ public final class OutputPropertiesFactory
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 @@ public final class OutputPropertiesFactory
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 @@ public final class OutputPropertiesFactory
/** 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 @@ public final class OutputPropertiesFactory
*/
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;
}
}
catch (IOException ioe)
{
throw new WrappedRuntimeException(
Utils.messages.createMessage(
MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY,
new Object[] { fileName, method }),
ioe);
break;
}
// 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;
}
}

View File

@ -1,45 +0,0 @@
###########################################################################
# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
###########################################################################
##
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
#
# Specify defaults when method="html". These defaults use output_xml.properties
# as a base.
#
# XSLT properties do not need namespace qualification.
method=html
indent=yes
media-type=text/html
version=4.0
# Xalan-specific output properties. These 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"/>
# ...
# Note that the colon after the protocol needs to be escaped.
{http\u003a//xml.apache.org/xalan}indent-amount=4
{http\u003a//xml.apache.org/xalan}content-handler=com.sun.org.apache.xml.internal.serializer.ToHTMLStream
{http\u003a//xml.apache.org/xalan}entities=com/sun/org/apache/xml/internal/serializer/HTMLEntities
{http\u003a//xml.apache.org/xalan}use-url-escaping=yes
{http\u003a//xml.apache.org/xalan}omit-meta-tag=no

View File

@ -1,39 +0,0 @@
###########################################################################
# reserved comment block
# DO NOT REMOVE OR ALTER!
###########################################################################
##########################################################################
# Copyright 2003-2004 The Apache Software Foundation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##########################################################################
#
# $Id: output_text.properties,v 1.3 2005/09/28 13:49:10 pvedula Exp $
#
# Specify defaults when method="text".
#
# XSLT properties do not need namespace qualification.
method=text
media-type=text/plain
# Xalan-specific output properties. These 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"/>
# ...
# Note that the colon after the protocol needs to be escaped.
{http\u003a//xml.apache.org/xalan}content-handler=com.sun.org.apache.xml.internal.serializer.ToTextStream

View File

@ -1,48 +0,0 @@
###########################################################################
# reserved comment block
# DO NOT REMOVE OR ALTER!
###########################################################################
###########################################################################
# Copyright 2003-2004 The Apache Software Foundation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##########################################################################
#
# $Id: output_unknown.properties,v 1.2.4.1 2005/09/15 08:15:33 suresh_emailid Exp $
#
# Specify defaults when no method="..." is specified.
# This type of output will quickly switch to "xml" or "html"
# depending on the first element name.
#
# XSLT properties do not need namespace qualification.
method=xml
version=1.0
encoding=UTF-8
indent=no
omit-xml-declaration=no
standalone=no
media-type=text/xml
# Xalan-specific output properties. These 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"/>
# ...
# Note that the colon after the protocol needs to be escaped.
{http\u003a//xml.apache.org/xalan}indent-amount=0
{http\u003a//xml.apache.org/xalan}content-handler=com.sun.org.apache.xml.internal.serializer.ToUnknownStream

View File

@ -1,48 +0,0 @@
###########################################################################
# reserved comment block
# DO NOT REMOVE OR ALTER!
###########################################################################
###########################################################################
# Copyright 2003-2004 The Apache Software Foundation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##########################################################################
#
# $Id: output_xml.properties,v 1.2.4.1 2005/09/15 08:15:33 suresh_emailid Exp $
#
# Specify defaults when method="xml". These defaults serve as a base for
# other defaults, such as output_html and output_text.
#
# XSLT properties do not need namespace qualification.
method=xml
version=1.0
encoding=UTF-8
indent=no
omit-xml-declaration=no
standalone=no
media-type=text/xml
# Xalan-specific output properties. These 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"/>
# ...
# Note that the colon after the protocol needs to be escaped.
{http\u003a//xml.apache.org/xalan}indent-amount=0
{http\u003a//xml.apache.org/xalan}content-handler=com.sun.org.apache.xml.internal.serializer.ToXMLStream
{http\u003a//xml.apache.org/xalan}entities=com/sun/org/apache/xml/internal/serializer/XMLEntities