| /* |
| * 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. |
| */ |
| |
| package org.apache.axiom.om.util; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.axiom.om.OMConstants; |
| import org.apache.axiom.util.stax.XMLEventUtils; |
| import org.apache.axiom.util.stax.dialect.StAXDialect; |
| import org.apache.axiom.util.stax.dialect.StAXDialectDetector; |
| import org.apache.axiom.util.stax.wrapper.ImmutableXMLInputFactory; |
| import org.apache.axiom.util.stax.wrapper.ImmutableXMLOutputFactory; |
| |
| import javax.xml.stream.XMLInputFactory; |
| import javax.xml.stream.XMLOutputFactory; |
| import javax.xml.stream.XMLStreamException; |
| import javax.xml.stream.XMLStreamReader; |
| import javax.xml.stream.XMLStreamWriter; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.io.Reader; |
| import java.io.Writer; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.WeakHashMap; |
| |
| /** |
| * Utility class containing StAX related methods. |
| * <p>This class defines a set of methods to get {@link XMLStreamReader} and {@link XMLStreamWriter} |
| * instances. This class caches the corresponding factories ({@link XMLInputFactory} |
| * and {@link XMLOutputFactory} objects) by classloader (default) or as singletons. |
| * The behavior can be changed using {@link #setFactoryPerClassLoader(boolean)}.</p> |
| * <p>Default properties for these factories can be specified using |
| * <tt>XMLInputFactory.properties</tt> and <tt>XMLOutputFactory.properties</tt> files. |
| * When a new factory is instantiated, this class will attempt to load the corresponding file using |
| * the context classloader. This class supports properties with boolean, integer and string values. |
| * Both standard StAX properties and implementation specific properties can be specified. This |
| * feature should be used with care since changing some properties to non default values will break |
| * Axiom. Good candidates for <tt>XMLInputFactory.properties</tt> are:</p> |
| * <dl> |
| * <dt><tt>javax.xml.stream.isCoalescing</tt></dt> |
| * <dd>Requires the processor to coalesce adjacent character data (text nodes and CDATA |
| * sections). This property also controls whether CDATA sections are reported or not.</dd> |
| * <dt><tt>com.ctc.wstx.inputBufferLength</tt></dt> |
| * <dd>Size of input buffer (in chars), to use for reading XML content from input stream/reader. |
| * This property is Woodstox specific.</dd> |
| * <dt><tt>com.ctc.wstx.minTextSegment</tt></dt> |
| * <dd>Property to specify shortest non-complete text segment (part of CDATA section or text |
| * content) that the parser is allowed to return, if not required to coalesce text. |
| * This property is Woodstox specific.</dt> |
| * </dl> |
| * <p>Good candidates for <tt>XMLOutputFactory.properties</tt> are:</p> |
| * <dl> |
| * <dt><tt>com.ctc.wstx.outputEscapeCr</tt></dt> |
| * <dd>Property that determines whether Carriage Return (\r) characters are to be escaped when |
| * output or not. If enabled, all instances of of character \r are escaped using a character |
| * entity (where possible, that is, within CHARACTERS events, and attribute values). |
| * Otherwise they are output as is. The main reason to enable this property is to ensure |
| * that carriage returns are preserved as is through parsing, since otherwise they will be |
| * converted to canonical XML linefeeds (\n), when occurring along or as part of \r\n pair. |
| * This property is Woodstox specific.</dd> |
| * </dl> |
| */ |
| public class StAXUtils { |
| private static final Log log = LogFactory.getLog(StAXUtils.class); |
| |
| // If isFactoryPerClassLoader is true (default), then |
| // a separate singleton XMLInputFactory and XMLOutputFactory is maintained |
| // for the each classloader. The different classloaders may be using different |
| // implementations of STAX. |
| // |
| // If isFactoryPerClassLoader is false, then |
| // a single XMLInputFactory and XMLOutputFactory is constructed using |
| // the classloader that loaded StAXUtils. |
| private static boolean isFactoryPerClassLoader = true; |
| |
| // These static singletons are used when the XML*Factory is created with |
| // the StAXUtils classloader. |
| private static final Map/*<StAXParserConfiguration,XMLInputFactory>*/ inputFactoryMap |
| = Collections.synchronizedMap(new WeakHashMap()); |
| private static final Map/*<StAXWriterConfiguration,XMLOutputFactory>*/ outputFactoryMap |
| = Collections.synchronizedMap(new WeakHashMap()); |
| |
| // These maps are used for the isFactoryPerClassLoader==true case |
| // The maps are synchronized and weak. |
| private static final Map/*<StAXParserConfiguration,Map<ClassLoader,XMLInputFactory>>*/ inputFactoryPerCLMap |
| = Collections.synchronizedMap(new WeakHashMap()); |
| private static final Map/*<StAXWriterConfiguration,Map<ClassLoader,XMLInputFactory>>*/ outputFactoryPerCLMap |
| = Collections.synchronizedMap(new WeakHashMap()); |
| |
| /** |
| * Get a cached {@link XMLInputFactory} instance using the default |
| * configuration and cache policy (i.e. one instance per class loader). |
| * |
| * @return an {@link XMLInputFactory} instance. |
| */ |
| public static XMLInputFactory getXMLInputFactory() { |
| return getXMLInputFactory(null, isFactoryPerClassLoader); |
| } |
| |
| /** |
| * Get a cached {@link XMLInputFactory} instance using the specified |
| * configuration and the default cache policy. |
| * |
| * @param configuration |
| * the configuration applied to the requested factory |
| * @return an {@link XMLInputFactory} instance. |
| */ |
| public static XMLInputFactory getXMLInputFactory(StAXParserConfiguration configuration) { |
| return getXMLInputFactory(configuration, isFactoryPerClassLoader); |
| } |
| |
| /** |
| * Get a cached {@link XMLInputFactory} instance using the default |
| * configuration and the specified cache policy. |
| * |
| * @param factoryPerClassLoaderPolicy |
| * the cache policy; see |
| * {@link #getXMLInputFactory(StAXParserConfiguration, boolean)} |
| * for more details |
| * @return an {@link XMLInputFactory} instance. |
| */ |
| public static XMLInputFactory getXMLInputFactory(boolean factoryPerClassLoaderPolicy) { |
| return getXMLInputFactory(null, factoryPerClassLoaderPolicy); |
| } |
| |
| /** |
| * Get a cached {@link XMLInputFactory} instance using the specified |
| * configuration and cache policy. |
| * |
| * @param configuration |
| * the configuration applied to the requested factory |
| * @param factoryPerClassLoaderPolicy |
| * If set to <code>true</code>, the factory cached for the |
| * current class loader will be returned. If set to |
| * <code>false</code>, the singleton factory (instantiated using |
| * the class loader that loaded {@link StAXUtils}) will be |
| * returned. |
| * @return an {@link XMLInputFactory} instance. |
| */ |
| public static XMLInputFactory getXMLInputFactory(StAXParserConfiguration configuration, |
| boolean factoryPerClassLoaderPolicy) { |
| |
| if (factoryPerClassLoaderPolicy) { |
| return getXMLInputFactory_perClassLoader(configuration); |
| } else { |
| return getXMLInputFactory_singleton(configuration); |
| } |
| } |
| |
| /** |
| * @deprecated |
| * Returns an XMLInputFactory instance for reuse. |
| * |
| * @param factory An XMLInputFactory instance that is available for reuse |
| */ |
| public static void releaseXMLInputFactory(XMLInputFactory factory) { |
| } |
| |
| public static XMLStreamReader createXMLStreamReader(InputStream in, String encoding) |
| throws XMLStreamException { |
| |
| return createXMLStreamReader(null, in, encoding); |
| } |
| |
| public static XMLStreamReader createXMLStreamReader(StAXParserConfiguration configuration, |
| InputStream in, String encoding) throws XMLStreamException { |
| |
| XMLStreamReader reader = getXMLInputFactory(configuration).createXMLStreamReader(in, encoding); |
| if (log.isDebugEnabled()) { |
| log.debug("XMLStreamReader is " + reader.getClass().getName()); |
| } |
| return reader; |
| } |
| |
| public static XMLStreamReader createXMLStreamReader(InputStream in) |
| throws XMLStreamException { |
| |
| return createXMLStreamReader(null, in); |
| } |
| |
| public static XMLStreamReader createXMLStreamReader(StAXParserConfiguration configuration, |
| InputStream in) throws XMLStreamException { |
| |
| XMLStreamReader reader = getXMLInputFactory(configuration).createXMLStreamReader(in); |
| if (log.isDebugEnabled()) { |
| log.debug("XMLStreamReader is " + reader.getClass().getName()); |
| } |
| return reader; |
| } |
| |
| public static XMLStreamReader createXMLStreamReader(StAXParserConfiguration configuration, |
| String systemId, InputStream in) throws XMLStreamException { |
| |
| XMLStreamReader reader = getXMLInputFactory(configuration).createXMLStreamReader(systemId, in); |
| if (log.isDebugEnabled()) { |
| log.debug("XMLStreamReader is " + reader.getClass().getName()); |
| } |
| return reader; |
| } |
| |
| public static XMLStreamReader createXMLStreamReader(Reader in) |
| throws XMLStreamException { |
| |
| return createXMLStreamReader(null, in); |
| } |
| |
| public static XMLStreamReader createXMLStreamReader(StAXParserConfiguration configuration, |
| Reader in) throws XMLStreamException { |
| |
| XMLStreamReader reader = getXMLInputFactory(configuration).createXMLStreamReader(in); |
| if (log.isDebugEnabled()) { |
| log.debug("XMLStreamReader is " + reader.getClass().getName()); |
| } |
| return reader; |
| } |
| |
| /** |
| * Get a cached {@link XMLOutputFactory} instance using the default |
| * configuration and cache policy (i.e. one instance per class loader). |
| * |
| * @return an {@link XMLOutputFactory} instance. |
| */ |
| public static XMLOutputFactory getXMLOutputFactory() { |
| return getXMLOutputFactory(null, isFactoryPerClassLoader); |
| } |
| |
| /** |
| * Get a cached {@link XMLOutputFactory} instance using the specified |
| * configuration and the default cache policy. |
| * |
| * @param configuration |
| * the configuration applied to the requested factory |
| * @return an {@link XMLOutputFactory} instance. |
| */ |
| public static XMLOutputFactory getXMLOutputFactory(StAXWriterConfiguration configuration) { |
| return getXMLOutputFactory(configuration, isFactoryPerClassLoader); |
| } |
| |
| /** |
| * Get a cached {@link XMLOutputFactory} instance using the default |
| * configuration and the specified cache policy. |
| * |
| * @param factoryPerClassLoaderPolicy |
| * the cache policy; see |
| * {@link #getXMLOutputFactory(StAXWriterConfiguration, boolean)} |
| * for more details |
| * @return an {@link XMLOutputFactory} instance. |
| */ |
| public static XMLOutputFactory getXMLOutputFactory(boolean factoryPerClassLoaderPolicy) { |
| return getXMLOutputFactory(null, factoryPerClassLoaderPolicy); |
| } |
| |
| /** |
| * Get a cached {@link XMLOutputFactory} instance using the specified |
| * configuration and cache policy. |
| * |
| * @param configuration |
| * the configuration applied to the requested factory |
| * @param factoryPerClassLoaderPolicy |
| * If set to <code>true</code>, the factory cached for the |
| * current class loader will be returned. If set to |
| * <code>false</code>, the singleton factory (instantiated using |
| * the class loader that loaded {@link StAXUtils}) will be |
| * returned. |
| * @return an {@link XMLOutputFactory} instance. |
| */ |
| public static XMLOutputFactory getXMLOutputFactory(StAXWriterConfiguration configuration, |
| boolean factoryPerClassLoaderPolicy) { |
| |
| if (factoryPerClassLoaderPolicy) { |
| return getXMLOutputFactory_perClassLoader(configuration); |
| } else { |
| return getXMLOutputFactory_singleton(configuration); |
| } |
| } |
| |
| /** |
| * Set the policy for how to maintain the XMLInputFactory and XMLOutputFactory |
| * @param value (if false, then one singleton...if true...then singleton per class loader |
| * (default is true) |
| */ |
| public static void setFactoryPerClassLoader(boolean value) { |
| isFactoryPerClassLoader = value; |
| } |
| |
| /** |
| * @deprecated |
| * Returns an XMLOutputFactory instance for reuse. |
| * |
| * @param factory An XMLOutputFactory instance that is available for reuse. |
| */ |
| public static void releaseXMLOutputFactory(XMLOutputFactory factory) { |
| } |
| |
| public static XMLStreamWriter createXMLStreamWriter(OutputStream out) |
| throws XMLStreamException { |
| |
| return createXMLStreamWriter(null, out); |
| } |
| |
| public static XMLStreamWriter createXMLStreamWriter(StAXWriterConfiguration configuration, |
| OutputStream out) throws XMLStreamException { |
| XMLStreamWriter writer = getXMLOutputFactory(configuration).createXMLStreamWriter(out, OMConstants.DEFAULT_CHAR_SET_ENCODING); |
| if (log.isDebugEnabled()) { |
| log.debug("XMLStreamWriter is " + writer.getClass().getName()); |
| } |
| return writer; |
| } |
| |
| public static XMLStreamWriter createXMLStreamWriter(OutputStream out, String encoding) |
| throws XMLStreamException { |
| |
| return createXMLStreamWriter(null, out, encoding); |
| } |
| |
| public static XMLStreamWriter createXMLStreamWriter(StAXWriterConfiguration configuration, |
| OutputStream out, String encoding) throws XMLStreamException { |
| XMLStreamWriter writer = getXMLOutputFactory(configuration).createXMLStreamWriter(out, encoding); |
| if (log.isDebugEnabled()) { |
| log.debug("XMLStreamWriter is " + writer.getClass().getName()); |
| } |
| return writer; |
| } |
| |
| public static XMLStreamWriter createXMLStreamWriter(final Writer out) |
| throws XMLStreamException { |
| |
| return createXMLStreamWriter(null, out); |
| } |
| |
| public static XMLStreamWriter createXMLStreamWriter(StAXWriterConfiguration configuration, |
| Writer out) throws XMLStreamException { |
| XMLStreamWriter writer = getXMLOutputFactory(configuration).createXMLStreamWriter(out); |
| if (log.isDebugEnabled()) { |
| log.debug("XMLStreamWriter is " + writer.getClass().getName()); |
| } |
| return writer; |
| } |
| |
| /** |
| * @deprecated |
| */ |
| public static void reset() { |
| } |
| |
| /** |
| * Load factory properties from a resource. The context class loader is used to locate |
| * the resource. The method converts boolean and integer values to the right Java types. |
| * All other values are returned as strings. |
| * |
| * @param name |
| * @return |
| */ |
| // This has package access since it is used from within anonymous inner classes |
| static Map loadFactoryProperties(String name) { |
| ClassLoader cl = getContextClassLoader(); |
| InputStream in = cl.getResourceAsStream(name); |
| if (in == null) { |
| return null; |
| } else { |
| try { |
| Properties rawProps = new Properties(); |
| Map props = new HashMap(); |
| rawProps.load(in); |
| for (Iterator it = rawProps.entrySet().iterator(); it.hasNext(); ) { |
| Map.Entry entry = (Map.Entry)it.next(); |
| String strValue = (String)entry.getValue(); |
| Object value; |
| if (strValue.equals("true")) { |
| value = Boolean.TRUE; |
| } else if (strValue.equals("false")) { |
| value = Boolean.FALSE; |
| } else { |
| try { |
| value = Integer.valueOf(strValue); |
| } catch (NumberFormatException ex) { |
| value = strValue; |
| } |
| } |
| props.put(entry.getKey(), value); |
| } |
| if (log.isDebugEnabled()) { |
| log.debug("Loaded factory properties from " + name + ": " + props); |
| } |
| return props; |
| } catch (IOException ex) { |
| log.error("Failed to read " + name, ex); |
| return null; |
| } finally { |
| try { |
| in.close(); |
| } catch (IOException ex) { |
| // Ignore |
| } |
| } |
| } |
| } |
| |
| private static XMLInputFactory newXMLInputFactory(final ClassLoader classLoader, |
| final StAXParserConfiguration configuration) { |
| |
| return (XMLInputFactory)AccessController.doPrivileged(new PrivilegedAction() { |
| public Object run() { |
| ClassLoader savedClassLoader; |
| if (classLoader == null) { |
| savedClassLoader = null; |
| } else { |
| savedClassLoader = Thread.currentThread().getContextClassLoader(); |
| Thread.currentThread().setContextClassLoader(classLoader); |
| } |
| try { |
| XMLInputFactory factory = XMLInputFactory.newInstance(); |
| // Woodstox by default creates coalescing parsers. Even if this violates |
| // the StAX specs, for compatibility with Woodstox, we always enable the |
| // coalescing mode. Note that we need to do that before loading |
| // XMLInputFactory.properties so that this setting can be overridden. |
| factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); |
| Map props = loadFactoryProperties("XMLInputFactory.properties"); |
| if (props != null) { |
| for (Iterator it = props.entrySet().iterator(); it.hasNext(); ) { |
| Map.Entry entry = (Map.Entry)it.next(); |
| factory.setProperty((String)entry.getKey(), entry.getValue()); |
| } |
| } |
| StAXDialect dialect = StAXDialectDetector.getDialect(factory); |
| if (configuration != null) { |
| factory = configuration.configure(factory, dialect); |
| } |
| return new ImmutableXMLInputFactory(dialect.normalize( |
| dialect.makeThreadSafe(factory))); |
| } finally { |
| if (savedClassLoader != null) { |
| Thread.currentThread().setContextClassLoader(savedClassLoader); |
| } |
| } |
| } |
| }); |
| } |
| |
| /** |
| * @return XMLInputFactory for the current classloader |
| */ |
| private static XMLInputFactory getXMLInputFactory_perClassLoader(StAXParserConfiguration configuration) { |
| |
| ClassLoader cl = getContextClassLoader(); |
| XMLInputFactory factory; |
| if (cl == null) { |
| factory = getXMLInputFactory_singleton(configuration); |
| } else { |
| // Check the cache |
| if (configuration == null) { |
| configuration = StAXParserConfiguration.DEFAULT; |
| } |
| Map map = (Map)inputFactoryPerCLMap.get(configuration); |
| if (map == null) { |
| map = Collections.synchronizedMap(new WeakHashMap()); |
| inputFactoryPerCLMap.put(configuration, map); |
| factory = null; |
| } else { |
| factory = (XMLInputFactory)map.get(cl); |
| } |
| |
| // If not found in the cache map, crate a new factory |
| if (factory == null) { |
| |
| if (log.isDebugEnabled()) { |
| log.debug("About to create XMLInputFactory implementation with " + |
| "classloader=" + cl); |
| log.debug("The classloader for javax.xml.stream.XMLInputFactory is: " |
| + XMLInputFactory.class.getClassLoader()); |
| } |
| try { |
| factory = newXMLInputFactory(null, configuration); |
| } catch (ClassCastException cce) { |
| if (log.isDebugEnabled()) { |
| log.debug("Failed creation of XMLInputFactory implementation with " + |
| "classloader=" + cl); |
| log.debug("Exception is=" + cce); |
| log.debug("Attempting with classloader: " + |
| XMLInputFactory.class.getClassLoader()); |
| } |
| factory = newXMLInputFactory(XMLInputFactory.class.getClassLoader(), |
| configuration); |
| } |
| |
| if (factory != null) { |
| // Cache the new factory |
| map.put(cl, factory); |
| |
| if (log.isDebugEnabled()) { |
| log.debug("Created XMLInputFactory = " + factory.getClass() + |
| " with classloader=" + cl); |
| log.debug("Configuration = " + configuration); |
| log.debug("Size of XMLInputFactory map for this configuration = " + map.size()); |
| log.debug("Configurations for which factories have been cached = " + |
| inputFactoryPerCLMap.keySet()); |
| } |
| } else { |
| factory = getXMLInputFactory_singleton(configuration); |
| } |
| } |
| |
| } |
| return factory; |
| } |
| |
| /** |
| * @return singleton XMLInputFactory loaded with the StAXUtils classloader |
| */ |
| private static XMLInputFactory getXMLInputFactory_singleton(StAXParserConfiguration configuration) { |
| if (configuration == null) { |
| configuration = StAXParserConfiguration.DEFAULT; |
| } |
| XMLInputFactory f = (XMLInputFactory)inputFactoryMap.get(configuration); |
| if (f == null) { |
| f = newXMLInputFactory(StAXUtils.class.getClassLoader(), configuration); |
| inputFactoryMap.put(configuration, f); |
| if (log.isDebugEnabled()) { |
| if (f != null) { |
| log.debug("Created singleton XMLInputFactory " + f.getClass() + " with configuration " + configuration); |
| } |
| } |
| } |
| |
| return f; |
| } |
| |
| private static XMLOutputFactory newXMLOutputFactory(final ClassLoader classLoader, |
| final StAXWriterConfiguration configuration) { |
| return (XMLOutputFactory)AccessController.doPrivileged(new PrivilegedAction() { |
| public Object run() { |
| ClassLoader savedClassLoader; |
| if (classLoader == null) { |
| savedClassLoader = null; |
| } else { |
| savedClassLoader = Thread.currentThread().getContextClassLoader(); |
| Thread.currentThread().setContextClassLoader(classLoader); |
| } |
| try { |
| XMLOutputFactory factory = XMLOutputFactory.newInstance(); |
| factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, |
| Boolean.FALSE); |
| Map props = loadFactoryProperties("XMLOutputFactory.properties"); |
| if (props != null) { |
| for (Iterator it = props.entrySet().iterator(); it.hasNext(); ) { |
| Map.Entry entry = (Map.Entry)it.next(); |
| factory.setProperty((String)entry.getKey(), entry.getValue()); |
| } |
| } |
| StAXDialect dialect = StAXDialectDetector.getDialect(factory); |
| if (configuration != null) { |
| factory = configuration.configure(factory, dialect); |
| } |
| return new ImmutableXMLOutputFactory(dialect.normalize( |
| dialect.makeThreadSafe(factory))); |
| } finally { |
| if (savedClassLoader != null) { |
| Thread.currentThread().setContextClassLoader(savedClassLoader); |
| } |
| } |
| } |
| }); |
| } |
| |
| /** |
| * @return XMLOutputFactory for the current classloader |
| */ |
| private static XMLOutputFactory getXMLOutputFactory_perClassLoader(StAXWriterConfiguration configuration) { |
| ClassLoader cl = getContextClassLoader(); |
| XMLOutputFactory factory; |
| if (cl == null) { |
| factory = getXMLOutputFactory_singleton(configuration); |
| } else { |
| if (configuration == null) { |
| configuration = StAXWriterConfiguration.DEFAULT; |
| } |
| Map map = (Map)outputFactoryPerCLMap.get(configuration); |
| if (map == null) { |
| map = Collections.synchronizedMap(new WeakHashMap()); |
| outputFactoryPerCLMap.put(configuration, map); |
| factory = null; |
| } else { |
| factory = (XMLOutputFactory)map.get(cl); |
| } |
| |
| if (factory == null) { |
| if (log.isDebugEnabled()) { |
| log.debug("About to create XMLOutputFactory implementation with " + |
| "classloader=" + cl); |
| log.debug("The classloader for javax.xml.stream.XMLOutputFactory is: " + |
| XMLOutputFactory.class.getClassLoader()); |
| } |
| try { |
| factory = newXMLOutputFactory(null, configuration); |
| } catch (ClassCastException cce) { |
| if (log.isDebugEnabled()) { |
| log.debug("Failed creation of XMLOutputFactory implementation with " + |
| "classloader=" + cl); |
| log.debug("Exception is=" + cce); |
| log.debug("Attempting with classloader: " + |
| XMLOutputFactory.class.getClassLoader()); |
| } |
| factory = newXMLOutputFactory(XMLOutputFactory.class.getClassLoader(), |
| configuration); |
| } |
| if (factory != null) { |
| map.put(cl, factory); |
| if (log.isDebugEnabled()) { |
| log.debug("Created XMLOutputFactory = " + factory.getClass() |
| + " for classloader=" + cl); |
| log.debug("Configuration = " + configuration); |
| log.debug("Size of XMLOutFactory map for this configuration = " + map.size()); |
| log.debug("Configurations for which factories have been cached = " + |
| outputFactoryPerCLMap.keySet()); |
| } |
| } else { |
| factory = getXMLOutputFactory_singleton(configuration); |
| } |
| } |
| |
| } |
| return factory; |
| } |
| |
| /** |
| * @return XMLOutputFactory singleton loaded with the StAXUtils classloader |
| */ |
| private static XMLOutputFactory getXMLOutputFactory_singleton(StAXWriterConfiguration configuration) { |
| if (configuration == null) { |
| configuration = StAXWriterConfiguration.DEFAULT; |
| } |
| XMLOutputFactory f = (XMLOutputFactory)outputFactoryMap.get(configuration); |
| if (f == null) { |
| f = newXMLOutputFactory(StAXUtils.class.getClassLoader(), configuration); |
| outputFactoryMap.put(configuration, f); |
| if (log.isDebugEnabled()) { |
| if (f != null) { |
| log.debug("Created singleton XMLOutputFactory " + f.getClass() + " with configuration " + configuration); |
| } |
| } |
| } |
| return f; |
| } |
| |
| /** |
| * @return Trhead Context ClassLoader |
| */ |
| private static ClassLoader getContextClassLoader() { |
| if (System.getSecurityManager() == null) { |
| // If there is no security manager, avoid the overhead of the doPrivileged call. |
| return Thread.currentThread().getContextClassLoader(); |
| } else { |
| return (ClassLoader)AccessController.doPrivileged( |
| new PrivilegedAction() { |
| public Object run() { |
| return Thread.currentThread().getContextClassLoader(); |
| } |
| } |
| ); |
| } |
| } |
| |
| /** |
| * @deprecated use {@link #createXMLStreamReader(StAXParserConfiguration, InputStream, String)} |
| * with {@link StAXParserConfiguration#STANDALONE} |
| */ |
| public static XMLStreamReader createNetworkDetachedXMLStreamReader(InputStream in, String encoding) |
| throws XMLStreamException { |
| |
| return createXMLStreamReader(StAXParserConfiguration.STANDALONE, in, encoding); |
| } |
| |
| /** |
| * @deprecated use {@link #getXMLInputFactory(StAXParserConfiguration)} with |
| * {@link StAXParserConfiguration#STANDALONE} |
| */ |
| public static XMLInputFactory getNetworkDetachedXMLInputFactory() { |
| return getXMLInputFactory(StAXParserConfiguration.STANDALONE); |
| } |
| |
| /** |
| * @deprecated use {@link #createXMLStreamReader(StAXParserConfiguration, InputStream)} |
| * with {@link StAXParserConfiguration#STANDALONE} |
| */ |
| public static XMLStreamReader createNetworkDetachedXMLStreamReader(InputStream in) |
| throws XMLStreamException { |
| |
| return createXMLStreamReader(StAXParserConfiguration.STANDALONE, in); |
| } |
| |
| /** |
| * @deprecated use {@link #createXMLStreamReader(StAXParserConfiguration, Reader)} |
| * with {@link StAXParserConfiguration#STANDALONE} |
| */ |
| public static XMLStreamReader createNetworkDetachedXMLStreamReader(Reader in) |
| throws XMLStreamException { |
| |
| return createXMLStreamReader(StAXParserConfiguration.STANDALONE, in); |
| } |
| |
| /** |
| * @deprecated Use {@link XMLEventUtils#getEventTypeString(int)} instead |
| */ |
| public static String getEventTypeString(int event) { |
| return XMLEventUtils.getEventTypeString(event); |
| } |
| } |