You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by sc...@apache.org on 2008/03/23 13:53:23 UTC

svn commit: r640198 - /webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/util/StAXUtils.java

Author: scheu
Date: Sun Mar 23 05:53:21 2008
New Revision: 640198

URL: http://svn.apache.org/viewvc?rev=640198&view=rev
Log:
WSCOMMONS-315
Contributor:Rich Scheuerle
StAXUtils should get an XML*Factory using the current classloader.

Modified:
    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/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=640198&r1=640197&r2=640198&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 Sun Mar 23 05:53:21 2008
@@ -36,41 +36,62 @@
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
 
 
 public class StAXUtils {
     private static Log log = LogFactory.getLog(StAXUtils.class);
     private static boolean isDebugEnabled = log.isDebugEnabled();
+    
+    // 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 XMLInputFactory inputFactory = null;
     private static XMLOutputFactory outputFactory = null;
-
+    
+    // These maps are used for the isFactoryPerClassLoader==true case
+    // The maps are synchronized and weak.
+    private static Map inputFactoryPerCL = Collections.synchronizedMap(new WeakHashMap());
+    private static Map outputFactoryPerCL = Collections.synchronizedMap(new WeakHashMap());
+    
     /**
      * Gets an XMLInputFactory instance from pool.
      *
      * @return an XMLInputFactory instance.
      */
     public static XMLInputFactory getXMLInputFactory() {
-        if (inputFactory == null) {
-            inputFactory = (XMLInputFactory) AccessController.doPrivileged(
-                    new PrivilegedAction() {
-                        public Object run() {
-                            Thread currentThread = Thread.currentThread();
-                            ClassLoader savedClassLoader = currentThread.getContextClassLoader();
-                            XMLInputFactory factory = null;
-                            try {
-                                currentThread.setContextClassLoader(StAXUtils.class.getClassLoader());
-                                factory = XMLInputFactory.newInstance();
-                            }
-                            finally {
-                                currentThread.setContextClassLoader(savedClassLoader);
-                            }
-                            return factory;
-                        }
-                    });
+        
+        if (isFactoryPerClassLoader) {
+            return getXMLInputFactory_perClassLoader();
+        } else {
+            return getXMLInputFactory_singleton();
+        }
+    }
+    
+    /**
+     * Get XMLInputFactory
+     * @param factoryPerClassLoaderPolicy 
+     * (if true, then factory using current classloader.
+     * if false, then factory using the classloader that loaded StAXUtils)
+     * @return XMLInputFactory
+     */
+    public static XMLInputFactory getXMLInputFactory(boolean factoryPerClassLoaderPolicy) {
+        if (factoryPerClassLoaderPolicy) {
+            return getXMLInputFactory_perClassLoader();
+        } else {
+            return getXMLInputFactory_singleton();
         }
-        return inputFactory;
     }
 
     /**
@@ -158,27 +179,35 @@
      * @return an XMLOutputFactory instance.
      */
     public static XMLOutputFactory getXMLOutputFactory() {
-        if (outputFactory == null) {
-            outputFactory = (XMLOutputFactory) AccessController.doPrivileged(
-                    new PrivilegedAction() {
-                        public Object run() {
-
-                            Thread currentThread = Thread.currentThread();
-                            ClassLoader savedClassLoader = currentThread.getContextClassLoader();
-                            XMLOutputFactory factory = null;
-                            try {
-                                currentThread.setContextClassLoader(StAXUtils.class.getClassLoader());
-                                factory = XMLOutputFactory.newInstance();
-                                factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.FALSE);
-                            }
-                            finally {
-                                currentThread.setContextClassLoader(savedClassLoader);
-                            }
-                            return factory;
-                        }
-                    });
+        if (isFactoryPerClassLoader) {
+            return getXMLOutputFactory_perClassLoader();
+        } else {
+            return getXMLOutputFactory_singleton();
+        }
+    }
+    
+    /**
+     * Get XMLOutputFactory
+     * @param factoryPerClassLoaderPolicy 
+     * (if true, then factory using current classloader.
+     * if false, then factory using the classloader that loaded StAXUtils)
+     * @return XMLInputFactory
+     */
+    public static XMLOutputFactory getXMLOutputFactory(boolean factoryPerClassLoaderPolicy) {
+        if (factoryPerClassLoaderPolicy) {
+            return getXMLOutputFactory_perClassLoader();
+        } else {
+            return getXMLOutputFactory_singleton();
         }
-        return outputFactory;
+    }
+    
+    /**
+     * 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;
     }
 
     /**
@@ -259,5 +288,161 @@
      * @deprecated
      */
     public static void reset() {
+    }
+    
+    /**
+     * @return XMLInputFactory for the current classloader
+     */
+    private static XMLInputFactory getXMLInputFactory_perClassLoader() {
+        
+        ClassLoader cl = getContextClassLoader();
+        XMLInputFactory factory;
+        if (cl == null) {
+            factory = getXMLInputFactory_singleton();
+        } else {
+            factory = (XMLInputFactory) inputFactoryPerCL.get(cl);
+            if (factory == null) {
+
+                factory =
+                    (XMLInputFactory) 
+                    AccessController.doPrivileged(
+                        new PrivilegedAction() {
+                            public Object run() {
+                                return XMLInputFactory.newInstance();
+                            }
+                        });
+                if (factory != null) {
+                    inputFactoryPerCL.put(cl, factory);
+                    if (log.isDebugEnabled()) {
+                        log.debug("Created XMLInputFactory = " + factory.getClass() + 
+                                  " for classloader=" + cl);
+                        log.debug("Size of XMLInputFactory map =" + inputFactoryPerCL.size());
+                    }
+                } else {
+                    factory = getXMLInputFactory_singleton();
+                }
+            }
+            
+        }
+        return factory;
+    }
+    
+    /**
+     * @return singleton XMLInputFactory loaded with the StAXUtils classloader
+     */
+    private static XMLInputFactory getXMLInputFactory_singleton() {
+ 
+        if (inputFactory == null) {
+            inputFactory = (XMLInputFactory) AccessController.doPrivileged(
+                    new PrivilegedAction() {
+                        public Object run() {
+                            Thread currentThread = Thread.currentThread();
+                            ClassLoader savedClassLoader = currentThread.getContextClassLoader();
+                            XMLInputFactory factory = null;
+                            try {
+                                currentThread.setContextClassLoader(StAXUtils.class.getClassLoader());
+                                factory = XMLInputFactory.newInstance();
+                            }
+                            finally {
+                                currentThread.setContextClassLoader(savedClassLoader);
+                            }
+                            return factory;
+                        }
+                    });
+            if (log.isDebugEnabled()) {
+                if (inputFactory != null) {
+                    log.debug("Created singleton XMLInputFactory = " + inputFactory.getClass());
+                }
+            }
+        }
+        
+        return inputFactory;
+    }
+    
+    /**
+     * @return XMLOutputFactory for the current classloader
+     */
+    public static XMLOutputFactory getXMLOutputFactory_perClassLoader() {
+        ClassLoader cl = getContextClassLoader();
+        XMLOutputFactory factory;
+        if (cl == null) {
+            factory = getXMLOutputFactory_singleton();
+        } else {
+            factory = (XMLOutputFactory) outputFactoryPerCL.get(cl);
+            if (factory == null) {
+
+                factory =
+                    (XMLOutputFactory) 
+                    AccessController.doPrivileged(
+                        new PrivilegedAction() {
+                            public Object run() {
+                                XMLOutputFactory factory = XMLOutputFactory.newInstance();
+                                factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, 
+                                                    Boolean.FALSE);
+                                return factory;
+                            }
+                        });
+                if (factory != null) {
+                    outputFactoryPerCL.put(cl, factory);
+                    if (log.isDebugEnabled()) {
+                        log.debug("Created XMLOutputFactory = " + factory.getClass() 
+                                  + " for classloader=" + cl);
+                        log.debug("Size of XMLOutputFactory map =" + outputFactoryPerCL.size());
+                    }
+                } else {
+                    factory = getXMLOutputFactory_singleton();
+                }
+            }
+            
+        }
+        return factory;
+    }
+    
+    /**
+     * @return XMLOutputFactory singleton loaded with the StAXUtils classloader
+     */
+    public static XMLOutputFactory getXMLOutputFactory_singleton() {
+        if (outputFactory == null) {
+            outputFactory = (XMLOutputFactory) AccessController.doPrivileged(
+                    new PrivilegedAction() {
+                        public Object run() {
+
+                            Thread currentThread = Thread.currentThread();
+                            ClassLoader savedClassLoader = currentThread.getContextClassLoader();
+                            XMLOutputFactory factory = null;
+                            try {
+                                currentThread.setContextClassLoader(StAXUtils.class.getClassLoader());
+                                factory = XMLOutputFactory.newInstance();
+                                factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, 
+                                                    Boolean.FALSE);
+                            }
+                            finally {
+                                currentThread.setContextClassLoader(savedClassLoader);
+                            }
+                            return factory;
+                        }
+                    });
+            if (log.isDebugEnabled()) {
+                if (outputFactory != null) {
+                    log.debug("Created singleton XMLOutputFactory = " + outputFactory.getClass());
+                }
+            }
+        }
+        return outputFactory;
+    }
+    
+    /**
+     * @return Trhead Context ClassLoader
+     */
+    private static ClassLoader getContextClassLoader() {
+        ClassLoader cl = (ClassLoader) AccessController.doPrivileged(
+                    new PrivilegedAction() {
+                        public Object run()  {
+                            return Thread.currentThread().getContextClassLoader();
+                        }
+                    }
+            );
+        
+        return cl;
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: commons-dev-help@ws.apache.org