You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/10/07 20:49:56 UTC

svn commit: r1530025 - /tomcat/trunk/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java

Author: markt
Date: Mon Oct  7 18:49:56 2013
New Revision: 1530025

URL: http://svn.apache.org/r1530025
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55630
Provide a way to disable the custom URLStreamHandlerFactory

Modified:
    tomcat/trunk/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java

Modified: tomcat/trunk/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java?rev=1530025&r1=1530024&r2=1530025&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java (original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/TomcatURLStreamHandlerFactory.java Mon Oct  7 18:49:56 2013
@@ -23,47 +23,69 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
-// TODO Add hook to enable user registered factories to be unloaded on web
-// application stop.
-public class TomcatURLStreamHandlerFactory implements URLStreamHandlerFactory{
+public class TomcatURLStreamHandlerFactory implements URLStreamHandlerFactory {
 
     private static final String WAR_PROTOCOL = "war";
 
     // Singleton instance
-    private static TomcatURLStreamHandlerFactory instance =
-            new TomcatURLStreamHandlerFactory();
+    private static volatile TomcatURLStreamHandlerFactory instance = null;
 
     /**
-     * Obtain a reference to the singleton instance,
+     * Obtain a reference to the singleton instance. It is recommended that
+     * callers check the value of {@link #isRegistered()} before using the
+     * returned instance.
      */
     public static TomcatURLStreamHandlerFactory getInstance() {
+        getInstanceInternal(true);
         return instance;
     }
 
 
+    private static TomcatURLStreamHandlerFactory getInstanceInternal(boolean register) {
+        // Double checked locking. OK because instance is volatile.
+        if (instance == null) {
+            synchronized (TomcatURLStreamHandlerFactory.class) {
+                if (instance == null) {
+                    instance = new TomcatURLStreamHandlerFactory(register);
+                }
+            }
+        }
+        return instance;
+    }
+
+
+    private final boolean registered;
+
     // List of factories for application defined stream handler factories.
     private List<URLStreamHandlerFactory> userFactories =
             new CopyOnWriteArrayList<>();
 
-
     /**
      * Register this factory with the JVM. May be called more than once. The
      * implementation ensures that registration only occurs once.
+     *
+     * @returns <code>true</code> if the factory is already registered with the
+     *          JVM or was successfully registered as a result of this call.
+     *          <code>false</code> if the factory was disabled prior to this
+     *          call.
      */
-    public static void register() {
-        // Calling this method loads this class which in turn triggers all the
-        // necessary registration.
+    public static boolean register() {
+        return getInstanceInternal(true).isRegistered();
     }
 
 
     /**
-     * Since the JVM only allows a single call to
-     * {@link URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)} and
-     * Tomcat needs to register a handler, provide a mechanism to allow
-     * applications to register their own handlers.
+     * Prevent this this factory from registering with the JVM. May be called
+     * more than once.
+     *
+     * @returns <code>true</code> if the factory is already disabled or was
+     *          successfully disabled as a result of this call.
+     *          <code>false</code> if the factory was already registered prior
+     *          to this call.
+
      */
-    public static void addUserFactory(URLStreamHandlerFactory factory) {
-        instance.userFactories.add(factory);
+    public static boolean disable() {
+        return !getInstanceInternal(false).isRegistered();
     }
 
 
@@ -87,11 +109,30 @@ public class TomcatURLStreamHandlerFacto
     }
 
 
-    private TomcatURLStreamHandlerFactory() {
+    private TomcatURLStreamHandlerFactory(boolean register) {
         // Hide default constructor
         // Singleton pattern to ensure there is only one instance of this
         // factory
-        URL.setURLStreamHandlerFactory(this);
+        this.registered = register;
+        if (register) {
+            URL.setURLStreamHandlerFactory(this);
+        }
+    }
+
+
+    public boolean isRegistered() {
+        return registered;
+    }
+
+
+    /**
+     * Since the JVM only allows a single call to
+     * {@link URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)} and
+     * Tomcat needs to register a handler, provide a mechanism to allow
+     * applications to register their own handlers.
+     */
+    public void addUserFactory(URLStreamHandlerFactory factory) {
+        userFactories.add(factory);
     }
 
 



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