< prev index next >
src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2017, 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.
--- 1,7 ----
/*
! * Copyright (c) 2017, 2019, 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.
*** 18,36 ****
* limitations under the License.
*/
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;
/**
--- 18,27 ----
*** 66,87 ****
* that specifies character to entity reference mappings. A line in such a
* file is has the name of the entity and the numeric (base 10) value
* 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.
*
* <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.
* </ul>
*
* @see SerializerFactory
* @see Method
* @see Serializer
! * @LastModified: Oct 2017
*/
public final class OutputPropertiesFactory
{
/** S_BUILTIN_EXTENSIONS_URL is a mnemonic for the XML Namespace
*(http://xml.apache.org/xalan) predefined to signify Xalan's
--- 57,78 ----
* that specifies character to entity reference mappings. A line in such a
* file is has the name of the entity and the numeric (base 10) value
* 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.
*
* <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.
* </ul>
*
* @see SerializerFactory
* @see Method
* @see Serializer
! * @LastModified: Feb 2019
*/
public final class OutputPropertiesFactory
{
/** S_BUILTIN_EXTENSIONS_URL is a mnemonic for the XML Namespace
*(http://xml.apache.org/xalan) predefined to signify Xalan's
*** 145,162 ****
*/
public static final String S_KEY_ENTITIES =
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. */
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.
*/
public static final String S_OMIT_META_TAG =
S_BUILTIN_EXTENSIONS_UNIVERSAL + "omit-meta-tag";
/**
--- 136,154 ----
*/
public static final String S_KEY_ENTITIES =
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.
! */
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.
*/
public static final String S_OMIT_META_TAG =
S_BUILTIN_EXTENSIONS_UNIVERSAL + "omit-meta-tag";
/**
*** 172,185 ****
*/
public static final int S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN =
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
*/
/**
* <p>Is Standalone</p>
*
* <ul>
--- 164,178 ----
*/
public static final int S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN =
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
! * added for application to neutralize the effect of Xalan patch 1495
*/
/**
* <p>Is Standalone</p>
*
* <ul>
*** 195,228 ****
//************************************************************
//* 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();
!
! /** Synchronization object for lazy initialization of the above tables. */
! private static final Object m_synch_object = new Object();
!
! /** 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 FIELDS
//************************************************************
! /** The default properties of all output files. */
private static Properties m_xml_properties = null;
/** The default properties when method="html". */
private static Properties m_html_properties = null;
--- 188,300 ----
//************************************************************
//* PRIVATE CONSTANTS
//************************************************************
! /*
! * 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"
! };
!
! 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"
! };
!
! 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 for all other than html and text. */
private static Properties m_xml_properties = null;
/** The default properties when method="html". */
private static Properties m_html_properties = null;
*** 230,535 ****
private static Properties m_text_properties = null;
/** 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>
*
* @param method non-null reference to method name.
*
* @return Properties object that holds the defaults for the given method.
*/
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))
! {
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);
- }
-
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))
{
String mimeEncoding = Encodings.getMimeEncoding(null);
! 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);
- }
-
defaultProperties = m_unknown_properties;
! }
! else
! {
! // TODO: Calculate res file from name.
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);
! }
// 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).
*
! * @param resourceName non-null reference to resource name.
* @param defaults Default properties, which may be null.
*/
! static private Properties loadPropertiesFile(
! final String resourceName,
! Properties defaults)
! throws IOException
{
-
- // 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);
! }
!
}
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;
- }
-
}
--- 302,383 ----
private static Properties m_text_properties = null;
/** The properties when method="" for the "unknown" wrapper */
private static Properties m_unknown_properties = null;
/**
! * Returns a Properties based on the specified method. The default is xml.
*
* @param method non-null reference to method name.
*
* @return Properties object that holds the defaults for the given method.
*/
static public final Properties getDefaultMethodProperties(String method)
{
Properties defaultProperties = null;
!
! if (null == m_xml_properties) {
! m_xml_properties = initProperties(PROP_XML, PROP_XML_VALUE, null);
}
!
! switch (method) {
! case Method.XML:
defaultProperties = 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;
! 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);
}
}
defaultProperties = m_text_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;
! break;
! default:
defaultProperties = m_xml_properties;
+ 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);
}
/**
! * Initiates the properties
*
! * @param keys an array of keys
! * @param values values corresponding to the keys
* @param defaults Default properties, which may be null.
*/
! static private Properties initProperties(String[] keys, String[] values, Properties defaults)
{
Properties props = new Properties(defaults);
! 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;
}
}
< prev index next >