Java URL .setURLStreamHandlerFactory (URLStreamHandlerFactory fac)
Syntax
URL.setURLStreamHandlerFactory(URLStreamHandlerFactory fac) has the following syntax.
public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
Example
In the following code shows how to use URL.setURLStreamHandlerFactory(URLStreamHandlerFactory fac) method.
//www .j av a2 s . co m
/***************************************
* *
* JBoss: The OpenSource J2EE WebOS *
* *
* Distributable under LGPL license. *
* See terms of license at gnu.org. *
* *
***************************************/
import java.net.URL;
import java.net.URLStreamHandler;
import java.util.Collections;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] argv) throws Exception{
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory());
}
}
/**
* A factory for loading URL protocol handlers. This is based
* on Sun's URL mechanism, in that <tt>Handler</tt> classes will be
* searched for in the packages specified by the java.protocol.handler.pkgs
* property are searched for classes matching the protocol + ".Handler"
* classname. The default JBoss package "org.jboss.net.protocol" is searched
* even if not specified in the java.protocol.handler.pkgs property.
*
* <p>This factory is installed by the default server implementaion
* to ensure that protocol handlers not in the system classpath are
* located. The thread context class is used first followed by the
* Class.forName method.
* </p>
*
* <p>Use {@link preload} to force the URL handler map to load the
* handlers for each protocol listed in {@link #PROTOCOLS}.
*
* @version <tt>$Revision: 1.8 $</tt>
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @author Scott.Stark@jboss.org
*/
class URLStreamHandlerFactory
implements java.net.URLStreamHandlerFactory
{
/** The package prefix where JBoss protocol handlers live. */
public static final String PACKAGE_PREFIX = "org.jboss.net.protocol";
/** A map of protocol names to handlers. Since there can only be one
URLStreamHandlerFactory installed, this is a static map that may be
cleared.
*/
private static Map handlerMap = Collections.synchronizedMap(new HashMap());
/** This thread local is used to prevent recursion in the
* createURLStreamHandler method. Resolving the protocol handler
* class can end up creating a new URL which can loop back into
* this factory with a stack like:
* <pre>
URLStreamHandlerFactory that use the TCL. See bug#669043
createURLStreamHandler():146, URLStreamHandlerFactory.java
getURLStreamHandler():1057, URL.java
<init>():405, URL.java
<init>():329, URL.java
<init>():321, URL.java
<init>():540, URLClassPath.java
run():319, URLClassPath.java
doPrivileged():-1, AccessController.java
getLoader():308, URLClassPath.java
getLoader():285, URLClassPath.java
findResource():136, URLClassPath.java
run():351, URLClassLoader.java
doPrivileged():-1, AccessController.java
findResource():348, URLClassLoader.java
getResource():780, ClassLoader.java
getResourceLocally():250, UnifiedClassLoader.java
getResourceFromClassLoader():333, UnifiedLoaderRepository3.java
getResource():243, UnifiedLoaderRepository3.java
getResource():228, UnifiedClassLoader3.java
</pre>
So we detect recursion based on the protocol value matches the current
createURLStreamHandlerProtocol setting.
*/
private static ThreadLocal createURLStreamHandlerProtocol = new ThreadLocal();
/** The current packages prefixes determined from the java.protocol.handler.pkgs
property + the org.jboss.net.protocol default package.
*/
private String[] handlerPkgs = {PACKAGE_PREFIX};
/** The last java.protocol.handler.pkgs value. Used to determine if the
java.protocol.handler.pkgs property has changed since handlerPkgs was
last built.
*/
private String lastHandlerPkgs = PACKAGE_PREFIX;
/** A list of JBoss specific protocols for preloading. */
public static final String PROTOCOLS[] = {
"resource",
"file"
};
/**
* Preload the JBoss specific protocol handlers, so that URL knows about
* them even if the handler factory is changed.
*/
public static void preload()
{
for (int i = 0; i < PROTOCOLS.length; i ++)
{
try
{
URL url = new URL(PROTOCOLS[i], "", -1, "");
}
catch (Exception e)
{
}
}
}
/** Clear the current protocol to handler map. The map will be rebuilt
as protocol handlers are requested.
*/
public static void clear()
{
handlerMap.clear();
}
/** Search the handlerPkgs for URLStreamHandler classes matching the
* pkg + protocol + ".Handler" naming convention.
*
* @see #checkHandlerPkgs()
* @param protocol The protocol to create a stream handler for
* @return The protocol handler or null if not found
*/
public URLStreamHandler createURLStreamHandler(final String protocol)
{
// Check the handler map
URLStreamHandler handler = (URLStreamHandler) handlerMap.get(protocol);
if( handler != null )
return handler;
// Validate that createURLStreamHandler is not recursing
String prevProtocol = (String) createURLStreamHandlerProtocol.get();
if( prevProtocol != null && prevProtocol.equals(protocol) )
return null;
createURLStreamHandlerProtocol.set(protocol);
// See if the handler pkgs definition has changed
checkHandlerPkgs();
// Search the handlerPkgs for a matching protocol handler
ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader();
for(int p = 0; p < handlerPkgs.length; p ++)
{
try
{
// Form the standard protocol handler class name
String classname = handlerPkgs[p] + "." + protocol + ".Handler";
Class type = null;
try
{
type = ctxLoader.loadClass(classname);
}
catch(ClassNotFoundException e)
{
// Try our class loader
type = Class.forName(classname);
}
if( type != null )
{
handler = (URLStreamHandler) type.newInstance();
handlerMap.put(protocol, handler);
}
}
catch (Throwable ignore)
{
}
}
createURLStreamHandlerProtocol.set(null);
return handler;
}
/** See if the java.protocol.handler.pkgs system property has changed
and if it has, parse it to update the handlerPkgs array.
*/
private synchronized void checkHandlerPkgs()
{
String handlerPkgsProp = System.getProperty("java.protocol.handler.pkgs");
if( handlerPkgsProp != null && handlerPkgsProp.equals(lastHandlerPkgs) == false )
{
// Update the handlerPkgs[] from the handlerPkgsProp
StringTokenizer tokeninzer = new StringTokenizer(handlerPkgsProp, "|");
ArrayList tmp = new ArrayList();
while( tokeninzer.hasMoreTokens() )
{
String pkg = tokeninzer.nextToken().intern();
if( tmp.contains(pkg) == false )
tmp.add(pkg);
}
// Include the JBoss default protocol handler pkg
if( tmp.contains(PACKAGE_PREFIX) == false )
tmp.add(PACKAGE_PREFIX);
handlerPkgs = new String[tmp.size()];
tmp.toArray(handlerPkgs);
lastHandlerPkgs = handlerPkgsProp;
}
}
}