Author: veithen Date: Thu Sep 30 17:30:53 2010 New Revision: 1003175 URL: http://svn.apache.org/viewvc?rev=1003175&view=rev Log: Made the XMLOutputFactory/XMLStreamWriter related code in StAXUtils more symmetric with respect to the XMLInputFactory/XMLStreamReader related code. In particular, introduced a StAXWriterConfiguration API (counterpart of StAXParserConfiguration) that gives more control over the XMLOutputFactory settings.
Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXWriterConfiguration.java (with props) Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXParserConfiguration.java webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXParserConfiguration.java URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXParserConfiguration.java?rev=1003175&r1=1003174&r2=1003175&view=diff ============================================================================== --- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXParserConfiguration.java (original) +++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXParserConfiguration.java Thu Sep 30 17:30:53 2010 @@ -38,6 +38,8 @@ import org.apache.axiom.util.stax.dialec * </ol> * These two requirements ensure that instances of this interface may be used as * cache keys. + * + * @see StAXWriterConfiguration */ public interface StAXParserConfiguration { /** Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java?rev=1003175&r1=1003174&r2=1003175&view=diff ============================================================================== --- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java (original) +++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java Thu Sep 30 17:30:53 2010 @@ -105,13 +105,15 @@ public class StAXUtils { // the StAXUtils classloader. private static final Map/*<StAXParserConfiguration,XMLInputFactory>*/ inputFactoryMap = Collections.synchronizedMap(new WeakHashMap()); - private static XMLOutputFactory outputFactory = null; + 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 Map outputFactoryPerCL = 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 @@ -182,7 +184,7 @@ public class StAXUtils { public static void releaseXMLInputFactory(XMLInputFactory factory) { } - public static XMLStreamReader createXMLStreamReader(final InputStream in, final String encoding) + public static XMLStreamReader createXMLStreamReader(InputStream in, String encoding) throws XMLStreamException { return createXMLStreamReader(null, in, encoding); @@ -210,7 +212,7 @@ public class StAXUtils { } } - public static XMLStreamReader createXMLStreamReader(final InputStream in) + public static XMLStreamReader createXMLStreamReader(InputStream in) throws XMLStreamException { return createXMLStreamReader(null, in); @@ -239,7 +241,7 @@ public class StAXUtils { } } - public static XMLStreamReader createXMLStreamReader(final Reader in) + public static XMLStreamReader createXMLStreamReader(Reader in) throws XMLStreamException { return createXMLStreamReader(null, in); @@ -268,33 +270,65 @@ public class StAXUtils { } /** - * Gets an XMLOutputFactory instance from pool. - * - * @return an XMLOutputFactory instance. + * 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() { - if (isFactoryPerClassLoader) { - return getXMLOutputFactory_perClassLoader(); - } else { - return getXMLOutputFactory_singleton(); - } + return getXMLOutputFactory(null, isFactoryPerClassLoader); } /** - * Get XMLOutputFactory - * @param factoryPerClassLoaderPolicy - * (if true, then factory using current classloader. - * if false, then factory using the classloader that loaded StAXUtils) - * @return XMLInputFactory + * 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(); + return getXMLOutputFactory_perClassLoader(configuration); } else { - return getXMLOutputFactory_singleton(); + 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 @@ -313,9 +347,15 @@ public class StAXUtils { public static void releaseXMLOutputFactory(XMLOutputFactory factory) { } - public static XMLStreamWriter createXMLStreamWriter(final OutputStream out) + public static XMLStreamWriter createXMLStreamWriter(OutputStream out) throws XMLStreamException { - final XMLOutputFactory outputFactory = getXMLOutputFactory(); + + return createXMLStreamWriter(null, out); + } + + public static XMLStreamWriter createXMLStreamWriter(StAXWriterConfiguration configuration, + final OutputStream out) throws XMLStreamException { + final XMLOutputFactory outputFactory = getXMLOutputFactory(configuration); try { XMLStreamWriter writer = (XMLStreamWriter) @@ -335,9 +375,15 @@ public class StAXUtils { } } - public static XMLStreamWriter createXMLStreamWriter(final OutputStream out, final String encoding) + public static XMLStreamWriter createXMLStreamWriter(OutputStream out, String encoding) throws XMLStreamException { - final XMLOutputFactory outputFactory = getXMLOutputFactory(); + + return createXMLStreamWriter(null, out, encoding); + } + + public static XMLStreamWriter createXMLStreamWriter(StAXWriterConfiguration configuration, + final OutputStream out, final String encoding) throws XMLStreamException { + final XMLOutputFactory outputFactory = getXMLOutputFactory(configuration); try { XMLStreamWriter writer = (XMLStreamWriter) @@ -359,7 +405,13 @@ public class StAXUtils { public static XMLStreamWriter createXMLStreamWriter(final Writer out) throws XMLStreamException { - final XMLOutputFactory outputFactory = getXMLOutputFactory(); + + return createXMLStreamWriter(null, out); + } + + public static XMLStreamWriter createXMLStreamWriter(StAXWriterConfiguration configuration, + final Writer out) throws XMLStreamException { + final XMLOutputFactory outputFactory = getXMLOutputFactory(configuration); try { XMLStreamWriter writer = (XMLStreamWriter) @@ -510,7 +562,6 @@ public class StAXUtils { log.debug("The classloader for javax.xml.stream.XMLInputFactory is: " + XMLInputFactory.class.getClassLoader()); } - factory = null; try { factory = newXMLInputFactory(null, configuration); } catch (ClassCastException cce) { @@ -567,7 +618,8 @@ public class StAXUtils { return f; } - private static XMLOutputFactory newXMLOutputFactory(final ClassLoader classLoader) { + private static XMLOutputFactory newXMLOutputFactory(final ClassLoader classLoader, + final StAXWriterConfiguration configuration) { return (XMLOutputFactory)AccessController.doPrivileged(new PrivilegedAction() { public Object run() { ClassLoader savedClassLoader; @@ -589,6 +641,9 @@ public class StAXUtils { } } StAXDialect dialect = StAXDialectDetector.getDialect(factory.getClass()); + if (configuration != null) { + factory = configuration.configure(factory, dialect); + } return new ImmutableXMLOutputFactory(dialect.normalize( dialect.makeThreadSafe(factory))); } finally { @@ -603,13 +658,24 @@ public class StAXUtils { /** * @return XMLOutputFactory for the current classloader */ - public static XMLOutputFactory getXMLOutputFactory_perClassLoader() { + private static XMLOutputFactory getXMLOutputFactory_perClassLoader(StAXWriterConfiguration configuration) { ClassLoader cl = getContextClassLoader(); XMLOutputFactory factory; if (cl == null) { - factory = getXMLOutputFactory_singleton(); + factory = getXMLOutputFactory_singleton(configuration); } else { - factory = (XMLOutputFactory) outputFactoryPerCL.get(cl); + 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 " + @@ -618,7 +684,7 @@ public class StAXUtils { XMLOutputFactory.class.getClassLoader()); } try { - factory = newXMLOutputFactory(null); + factory = newXMLOutputFactory(null, configuration); } catch (ClassCastException cce) { if (log.isDebugEnabled()) { log.debug("Failed creation of XMLOutputFactory implementation with " + @@ -627,17 +693,21 @@ public class StAXUtils { log.debug("Attempting with classloader: " + XMLOutputFactory.class.getClassLoader()); } - factory = newXMLOutputFactory(XMLOutputFactory.class.getClassLoader()); + factory = newXMLOutputFactory(XMLOutputFactory.class.getClassLoader(), + configuration); } if (factory != null) { - outputFactoryPerCL.put(cl, factory); + map.put(cl, factory); if (log.isDebugEnabled()) { log.debug("Created XMLOutputFactory = " + factory.getClass() + " for classloader=" + cl); - log.debug("Size of XMLOutputFactory map =" + outputFactoryPerCL.size()); + 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(); + factory = getXMLOutputFactory_singleton(configuration); } } @@ -648,16 +718,21 @@ public class StAXUtils { /** * @return XMLOutputFactory singleton loaded with the StAXUtils classloader */ - public static XMLOutputFactory getXMLOutputFactory_singleton() { - if (outputFactory == null) { - outputFactory = newXMLOutputFactory(StAXUtils.class.getClassLoader()); + 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 (outputFactory != null) { - log.debug("Created singleton XMLOutputFactory = " + outputFactory.getClass()); + if (f != null) { + log.debug("Created singleton XMLOutputFactory " + f.getClass() + " with configuration " + configuration); } } } - return outputFactory; + return f; } /** Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXWriterConfiguration.java URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXWriterConfiguration.java?rev=1003175&view=auto ============================================================================== --- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXWriterConfiguration.java (added) +++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXWriterConfiguration.java Thu Sep 30 17:30:53 2010 @@ -0,0 +1,68 @@ +/* + * 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 javax.xml.stream.XMLOutputFactory; + +import org.apache.axiom.util.stax.dialect.StAXDialect; +import org.apache.axiom.util.stax.dialect.StAXDialectDetector; + +/** + * Defines a particular StAX writer configuration. An implementation of this + * interface must satisfy the following requirements: + * <ol> + * <li>It MUST be immutable. + * <li>It MUST either be a singleton or properly implement + * {...@link Object#equals(Object)} and {...@link Object#hashCode()}. + * </ol> + * These two requirements ensure that instances of this interface may be used as + * cache keys. + * + * @see StAXParserConfiguration + */ +public interface StAXWriterConfiguration { + /** + * The default configuration. + */ + StAXWriterConfiguration DEFAULT = new StAXWriterConfiguration() { + public XMLOutputFactory configure(XMLOutputFactory factory, StAXDialect dialect) { + return factory; + } + + public String toString() { + return "DEFAULT"; + } + }; + + /** + * Apply the configuration to the given factory. The method MAY optionally + * wrap the factory. + * + * @param factory + * the factory to configure + * @param dialect + * The dialect of the StAX implementation as detected by + * {...@link StAXDialectDetector}. The implementation may use this + * information to configure implementation specific settings. + * @return The configured factory. This may be the original factory (if the + * implementation only changes the factory properties), or a + * wrapper. + */ + XMLOutputFactory configure(XMLOutputFactory factory, StAXDialect dialect); +} Propchange: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXWriterConfiguration.java ------------------------------------------------------------------------------ svn:eol-style = native