FileDocCategorySizeDatePackage
OutputPropertiesFactory.javaAPI DocJava SE 6 API19681Tue Jun 10 00:23:06 BST 2008com.sun.org.apache.xml.internal.serializer

OutputPropertiesFactory

public final class OutputPropertiesFactory extends Object
This class is a factory to generate a set of default properties of key/value pairs that are used to create a serializer through the factory {@link SerializerFactory SerilizerFactory}. The properties generated by this factory may be modified to non-default values before the SerializerFactory is used to create a Serializer.

The given output types supported are "xml", "text", and "html". These type strings can be obtained from the {@link Method Method} class in this package.

Other constants defined in this class are the non-standard property keys that can be used to set non-standard property values on a java.util.Properties object that is used to create or configure a serializer. Here are the non-standard keys:

  • S_KEY_INDENT_AMOUNT - The non-standard property key to use to set the indentation amount. The "indent" key needs to have a value of "yes", and this properties value is a the number of whitespaces to indent by per indentation level.
  • S_KEY_CONTENT_HANDLER - This non-standard property key is used to set the name of the fully qualified Java class that implements the ContentHandler interface. The output of the serializer will be SAX events sent to this an object of this class.
  • S_KEY_ENTITIES - This non-standard property key is used to specify the name of the property file 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:
    quot=34
  • S_USE_URL_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.
  • S_OMIT_META_TAG - 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.
see
SerializerFactory
see
Method
see
Serializer

Fields Summary
private static final String
S_BUILTIN_EXTENSIONS_URL
S_BUILTIN_EXTENSIONS_URL is a mnemonic for the XML Namespace (http://xml.apache.org/xalan) predefined to signify Xalan's built-in XSLT Extensions. When used in stylesheets, this is often bound to the "xalan:" prefix.
private static final String
S_BUILTIN_OLD_EXTENSIONS_URL
The old built-in extension url. It is still supported for backward compatibility.
public static final String
S_BUILTIN_EXTENSIONS_UNIVERSAL
This is not a public API. This is the built-in extensions namespace, reexpressed in {namespaceURI} syntax suitable for prepending to a localname to produce a "universal name".
public static final String
S_KEY_INDENT_AMOUNT
The non-standard property key to use to set the number of whitepaces to indent by, per indentation level, if indent="yes".
public static final String
S_KEY_LINE_SEPARATOR
The non-standard property key to use to set the number of whitepaces to indent by, per indentation level, if indent="yes".
public static final String
S_KEY_CONTENT_HANDLER
This non-standard property key is used to set the name of the fully qualified Java class that implements the ContentHandler interface. Fully qualified name of class with a default constructor that implements the ContentHandler interface, where the result tree events will be sent to.
public static final String
S_KEY_ENTITIES
This non-standard property key is used to specify the name of the property file that specifies character to entity reference mappings.
public static final String
S_USE_URL_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_OMIT_META_TAG
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_BUILTIN_OLD_EXTENSIONS_UNIVERSAL
The old built-in extension namespace, this is not a public API.
public static final int
S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN
This is not a public API, it is only public because it is used by outside of this package, it is the length of the old built-in extension namespace.
private static final String
S_XSLT_PREFIX
private static final int
S_XSLT_PREFIX_LEN
private static final String
S_XALAN_PREFIX
private static final int
S_XALAN_PREFIX_LEN
private static Integer
m_synch_object
Synchronization object for lazy initialization of the above tables.
private static final String
PROP_DIR
the directory in which the various method property files are located
private static final String
PROP_FILE_XML
property file for default XML properties
private static final String
PROP_FILE_TEXT
property file for default TEXT properties
private static final String
PROP_FILE_HTML
property file for default HTML properties
private static final String
PROP_FILE_UNKNOWN
property file for default UNKNOWN (Either XML or HTML, to be determined later) properties
private static Properties
m_xml_properties
The default properties of all output files.
private static Properties
m_html_properties
The default properties when method="html".
private static Properties
m_text_properties
The default properties when method="text".
private static Properties
m_unknown_properties
The properties when method="" for the "unknown" wrapper
private static final Class
ACCESS_CONTROLLER_CLASS
Constructors Summary
Methods Summary
private static java.lang.ClassfindAccessControllerClass()


        
        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;
    
private static java.lang.StringfixupPropertyString(java.lang.String s, boolean doClipping)
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.

        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;
    
public static final java.util.PropertiesgetDefaultMethodProperties(java.lang.String method)
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.

Anything other than 'text', 'xml', and 'html', will use the output_xml.properties file.

param
method non-null reference to method name.
return
Properties object that holds the defaults for the given 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);
    
private static java.util.PropertiesloadPropertiesFile(java.lang.String resourceName, java.util.Properties defaults)
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.


        // 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 = (InputStream) AccessController
                    .doPrivileged(new PrivilegedAction() {
                        public Object 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 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 = System.getProperty(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 = System.getProperty(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;