873 lines · 29.6 KB · Java
RawDownload
                }            }        }        return url;    }      private boolean resourceExists(URL url) {        // Check if the resource exists.        // It almost works to just try to do an openConnection() but        // HttpURLConnection will return true on HTTP_BAD_REQUEST        // when the requested name ends in ".html", ".htm", and ".txt"        // and we want to be able to handle these        //        // Also, cannot just open a connection for things like FileURLConnection,        // because they succeed when connecting to a nonexistent file.        // So, in those cases we open and close an input stream.        boolean ok = true;        try {            URLConnection conn = url.openConnection();            if (conn instanceof java.net.HttpURLConnection) {                java.net.HttpURLConnection hconn =                    (java.net.HttpURLConnection) conn;                 // To reduce overhead, using http HEAD method instead of GET method                hconn.setRequestMethod("HEAD");                 int code = hconn.getResponseCode();                if (code == java.net.HttpURLConnection.HTTP_OK) {                    return true;                }                if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) {                    return false;                }            } else {                /**                 * Fix for #4182052 - stanleyh                 *                 * The same connection should be reused to avoid multiple                 * HTTP connections                 */                 // our best guess for the other cases                InputStream is = conn.getInputStream();                is.close();            }        } catch (Exception ex) {            ok = false;        }        return ok;    }     /*     * Returns an enumeration of all the applet resources with the specified     * name. First checks loaded JAR files then the applet code base for all     * available resources.     */    public Enumeration findResources(String name) throws IOException {         final Enumeration e = super.findResources(name);         // 6215746:  Disable META-INF/* lookup from codebase in        // applet/plugin classloader. [stanley.ho]        if (name.startsWith("META-INF/"))            return e;         // 4668479: Option to turn off codebase lookup in AppletClassLoader        // during resource requests. [stanley.ho]        if (codebaseLookup == false)            return e;         URL u = new URL(base, ParseUtil.encodePath(name, false));        if (!resourceExists(u)) {            u = null;        }         final URL url = u;        return new Enumeration() {            private boolean done;            public Object nextElement() {                if (!done) {                    if (e.hasMoreElements()) {                        return e.nextElement();                    }                    done = true;                    if (url != null) {                        return url;                    }                }                throw new NoSuchElementException();            }            public boolean hasMoreElements() {                return !done && (e.hasMoreElements() || url != null);            }        };    }     /*     * Load and resolve the file specified by the applet tag CODE     * attribute. The argument can either be the relative path     * of the class file itself or just the name of the class.     */    Class loadCode(String name) throws ClassNotFoundException {        // first convert any '/' or native file separator to .        name = name.replace('/', '.');        name = name.replace(File.separatorChar, '.');         // deal with URL rewriting        String cookie = null;        int index = name.indexOf(";");        if(index != -1) {                cookie = name.substring(index, name.length());                name = name.substring(0, index);        }         // save that name for later        String fullName = name;        // then strip off any suffixes        if (name.endsWith(".class") || name.endsWith(".java")) {            name = name.substring(0, name.lastIndexOf('.'));        }        try {                if(cookie != null)                        name = (new StringBuffer(name)).append(cookie).toString();            return loadClass(name);        } catch (ClassNotFoundException e) {        }        // then if it didn't end with .java or .class, or in the        // really pathological case of a class named class or java        if(cookie != null)                fullName = (new StringBuffer(fullName)).append(cookie).toString();         return loadClass(fullName);    }     /*     * The threadgroup that the applets loaded by this classloader live     * in. In the sun.* implementation of applets, the security manager's     * (AppletSecurity) getThreadGroup returns the thread group of the     * first applet on the stack, which is the applet's thread group.     */    private AppletThreadGroup threadGroup;    private AppContext appContext;     public ThreadGroup getThreadGroup() {      synchronized (threadGroupSynchronizer) {        if (threadGroup == null || threadGroup.isDestroyed()) {            AccessController.doPrivileged(new PrivilegedAction() {                public Object run() {                    threadGroup = new AppletThreadGroup(base + "-threadGroup");                    // threadGroup.setDaemon(true);                    // threadGroup is now destroyed by AppContext.dispose()                     // Create the new AppContext from within a Thread belonging                    // to the newly created ThreadGroup, and wait for the                    // creation to complete before returning from this method.                    AppContextCreator creatorThread = new AppContextCreator(threadGroup);                     // Since this thread will later be used to launch the                    // applet's AWT-event dispatch thread and we want the applet                    // code executing the AWT callbacks to use their own class                    // loader rather than the system class loader, explicitly                    // set the context class loader to the AppletClassLoader.                    creatorThread.setContextClassLoader(AppletClassLoader.this);                     creatorThread.start();                    try {                        synchronized(creatorThread.syncObject) {                            while (!creatorThread.created) {                                creatorThread.syncObject.wait();                            }                        }                    } catch (InterruptedException e) { }                    appContext = creatorThread.appContext;                    return null;                }            });        }        return threadGroup;      }    }     /*     * Get the AppContext, if any, corresponding to this AppletClassLoader.     */    public AppContext getAppContext()  {        return appContext;    }     int usageCount = 0;     /**     * Grab this AppletClassLoader and its ThreadGroup/AppContext, so they     * won't be destroyed.     */public     void grab() {        synchronized(grabReleaseSynchronizer) {            usageCount++;        }        getThreadGroup(); // Make sure ThreadGroup/AppContext exist    }     protected void setExceptionStatus()    {        exceptionStatus = true;    }     public boolean getExceptionStatus()    {        return exceptionStatus;    }     /**     * Release this AppletClassLoader and its ThreadGroup/AppContext.     * If nothing else has grabbed this AppletClassLoader, its ThreadGroup     * and AppContext will be destroyed.     *     * Because this method may destroy the AppletClassLoader's ThreadGroup,     * this method should NOT be called from within the AppletClassLoader's     * ThreadGroup.     *     * Changed modifier to protected in order to be able to overwrite this     * function in PluginClassLoader.java     */    protected void release() {         AppContext tempAppContext = null;         synchronized(grabReleaseSynchronizer) {            if (usageCount > 1)  {                --usageCount;            } else {                synchronized(threadGroupSynchronizer) {                    tempAppContext = resetAppContext();                }            }        }         // Dispose appContext outside any sync block to        // prevent potential deadlock.        if (tempAppContext != null)  {            try {                tempAppContext.dispose(); // nuke the world!            } catch (IllegalThreadStateException e) { }        }    }     /*     * reset classloader's AppContext and ThreadGroup     * This method is for subclass PluginClassLoader to     * reset superclass's AppContext and ThreadGroup but do     * not dispose the AppContext. PluginClassLoader does not     * use UsageCount to decide whether to dispose AppContext     *     * @return previous AppContext     */    protected AppContext resetAppContext() {        AppContext tempAppContext = null;         synchronized(threadGroupSynchronizer) {            // Store app context in temp variable            tempAppContext = appContext;            usageCount = 0;            appContext = null;            threadGroup = null;        }        return tempAppContext;    }      // Hash map to store applet compatibility info    private HashMap jdk11AppletInfo = new HashMap();    private HashMap jdk12AppletInfo = new HashMap();     /**     * Set applet target level as JDK 1.1.     *     * @param clazz Applet class.     * @param bool true if JDK is targeted for JDK 1.1;     *             false otherwise.     */    void setJDK11Target(Class clazz, boolean bool)    {         jdk11AppletInfo.put(clazz.toString(), Boolean.valueOf(bool));    }     /**     * Set applet target level as JDK 1.2.     *     * @param clazz Applet class.     * @param bool true if JDK is targeted for JDK 1.2;     *             false otherwise.     */    void setJDK12Target(Class clazz, boolean bool)    {        jdk12AppletInfo.put(clazz.toString(), Boolean.valueOf(bool));    }     /**     * Determine if applet is targeted for JDK 1.1.     *     * @param applet Applet class.     * @return TRUE if applet is targeted for JDK 1.1;     *         FALSE if applet is not;     *         null if applet is unknown.     */    Boolean isJDK11Target(Class clazz)    {        return (Boolean) jdk11AppletInfo.get(clazz.toString());    }     /**     * Determine if applet is targeted for JDK 1.2.     *     * @param applet Applet class.     * @return TRUE if applet is targeted for JDK 1.2;     *         FALSE if applet is not;     *         null if applet is unknown.     */    Boolean isJDK12Target(Class clazz)    {        return (Boolean) jdk12AppletInfo.get(clazz.toString());    }     private static AppletMessageHandler mh =        new AppletMessageHandler("appletclassloader");     /*     * Prints a class loading error message.     */    private static void printError(String name, Throwable e) {        String s = null;        if (e == null) {            s = mh.getMessage("filenotfound", name);        } else if (e instanceof IOException) {            s = mh.getMessage("fileioexception", name);        } else if (e instanceof ClassFormatError) {            s = mh.getMessage("fileformat", name);        } else if (e instanceof ThreadDeath) {            s = mh.getMessage("filedeath", name);        } else if (e instanceof Error) {            s = mh.getMessage("fileerror", e.toString(), name);        }        if (s != null) {            System.err.println(s);        }    }} /* * The AppContextCreator class is used to create an AppContext from within * a Thread belonging to the new AppContext's ThreadGroup.  To wait for * this operation to complete before continuing, wait for the notifyAll() * operation on the syncObject to occur. */class AppContextCreator extends Thread  {    Object syncObject = new Object();    AppContext appContext = null;    volatile boolean created = false;     AppContextCreator(ThreadGroup group)  {        super(group, "AppContextCreator");    }     public void run()  {        appContext = SunToolkit.createNewAppContext();        created = true;        synchronized(syncObject) {            syncObject.notifyAll();        }    } // run() } // class AppContextCreator

Lines 501–873 of 873. Previous lines