Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

/***************************************
 *                                     *
 *  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;
        }
    }

}